JSlang.dev

JavaScript Deep Dives with Wolfram. Since 2015
Inclusive, Test-Driven, Spec-Focused, Collaborative.

November 23, 2023
TestsSource
JavaScript Class (and Prototypes)

Source Code

The source code we wrote during the event.

import {strict as assert} from 'assert';

describe('static fields', () => {
  it('creating a static field on a class, it can be accessed without instantiating the class', () => {
    class WithOneMember {
      static IamStatic = 42;
    }
    assert.equal(WithOneMember.IamStatic, 42);
  });
  it('the static member is writable from outside the class', () => {
    class Klass {
      static member = 'initial value';
    }
    Klass.member = 'overridden value';
    assert.equal(Klass.member, 'overridden value');
  });
  it('a member of an instance of a class can be overriden', () => {
    class Klass {
      nonStatic = 'initial';
    }
    const instance = new Klass();
    instance.nonStatic = 'overridden';
    assert.equal(instance.nonStatic, 'overridden');
  });
  it('a class is an instance of Object', () => {
    class Klass {}
    assert(Klass instanceof Object);
  });
  it('trying to overridde a static member throws', () => {
    class Klass {
      static member = 'initial';
    }
    Object.freeze(Klass);
    assert.throws(() => Klass.member = 'overridden', TypeError);
  });
});

describe('anonymous class', () => {
  it('an anonymous class does have a name ;)', () => {
    const Klass = class {}
    assert.equal(Klass.name, 'Klass');
  });
  it('an anonymous class created without assigning it has the name "" (empty string)', () => {
    assert.equal((class {}).name, '');
  });
});

describe('inheritance', () => {
  it('a member from class A is visible on an instance of class B, if it extends it', () => {
    class A {
      member = 'I am in A';
    }
    class B extends A {}
    const instance = new B();
    assert.equal(instance.member, 'I am in A');
  });
  it('a method is inherited from A to B (using `extends`)', () => {
    class A {
      method() { return 'method of A'; }
    }
    class B extends A {}

    const instanceOfB = new B();
    const instanceOfA = new A();
    assert.equal(instanceOfB.method(), instanceOfA.method());
  });
  it('private methods can not be called from a child class', () => {
    const fn = `
      class A {
        #method() { return 'from A'; }
      }
      class B extends A {
        callsPrivate() { return this.#method(); }
      }
    `;
    assert.throws(() => new Function(fn), SyntaxError);
  });
});