export const NO_REPLY_GITHUB_EMAIL = 'noreply@github.com';

export default class Author {
  constructor(email, fullName, login = null) {
    this.email = email;
    this.fullName = fullName;
    this.login = login;
  }

  getEmail() {
    return this.email;
  }

  getFullName() {
    return this.fullName;
  }

  getLogin() {
    return this.login;
  }

  isNoReply() {
    return this.email === NO_REPLY_GITHUB_EMAIL;
  }

  hasLogin() {
    return this.login !== null;
  }

  isPresent() {
    return true;
  }

  matches(other) {
    return this.getEmail() === other.getEmail();
  }

  toString() {
    let s = `${this.fullName} <${this.email}>`;
    if (this.hasLogin()) {
      s += ` @${this.login}`;
    }
    return s;
  }

  static compare(a, b) {
    if (a.getFullName() < b.getFullName()) { return -1; }
    if (a.getFullName() > b.getFullName()) { return 1; }
    return 0;
  }
}

export const nullAuthor = {
  getEmail() {
    return '';
  },

  getFullName() {
    return '';
  },

  getLogin() {
    return null;
  },

  isNoReply() {
    return false;
  },

  hasLogin() {
    return false;
  },

  isPresent() {
    return false;
  },

  matches(other) {
    return other === this;
  },

  toString() {
    return 'null author';
  },
};

@@ -1,20 +1,48 @@
+const NEW = Symbol('new');%0A%0A
 export const NO_REPL
@@ -149,16 +149,30 @@
  login =
+ null, isNew =
  null) %7B
@@ -246,24 +246,146 @@
 in = login;%0A
+    this.new = isNew === NEW;%0A  %7D%0A%0A  static createNew(email, fullName) %7B%0A    return new this(email, fullName, null, NEW);%0A
   %7D%0A%0A  getEm
@@ -630,24 +630,62 @@
  null;%0A  %7D%0A%0A
+  isNew() %7B%0A    return this.new;%0A  %7D%0A%0A
   isPresent(
@@ -1270,16 +1270,16 @@
 ;%0A  %7D,%0A%0A
-
   hasLog
@@ -1305,24 +1305,60 @@
 alse;%0A  %7D,%0A%0A
+  isNew() %7B%0A    return false;%0A  %7D,%0A%0A
   isPresent(

Create and test for new Authors