JSlang.dev

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

December 13, 2023
TestsSource
Static Initialization Blocks

Source Code

The source code we wrote during the event.

import {strict as assert} from 'assert';

describe('in what order are blocks executed?', () => {
  it('a static property defined before a static block is visible inside of it', () => {
    let visible;
    class Klass {
      static log = 'the property';
      static {
        visible = this.log;
      }
    }
    assert.equal(visible, 'the property');
  });
  it('the first block is executed before the second one', () => {
    class Klass {
      static log = [];
      static {
        this.log.push('first block');
      }
      static {
        this.log.push('second block');
      }
    }
    assert.deepEqual(Klass.log, ['first block', 'second block']);
  });
  it('a static property can be accessed before it is declared', () => {
    class Klass {
      static {
        this.log = 'visible?';
      }
      static log = 'initial';
    }
    assert.equal(Klass.log, 'initial');
  });
  
  it('assigning the result of a function call to a static prop works', () => {
    const giveMeValue = () => 42;
    class Klass {
      static log = giveMeValue();
    }
    assert.equal(Klass.log, 42);
  });

  it('a static block is not async (by default)', () => {
    const giveMeValue = async () => 42;
    class Klass {
      static {
        giveMeValue().then(x => this.log = x);
      }
    }
    assert.equal(Klass.log, undefined);
  });
  it('an async value inside a static block resolves after a timeout (even its 0ms)', async () => {
    const giveMeValue = async () => 42;
    class Klass {
      static {
        giveMeValue().then(x => this.log = x);
      }
    }
    await new Promise(resolve => setTimeout(resolve, 0));
    assert.equal(Klass.log, 42);
  });
});

describe('order of constructor and static blocks', () => {
  it('a property inside a static block is not the same as the property by the constructor', () => {
    class Klass {
      static {
        this.log = 'inside static block';
      }
      constructor(value) {
        this.log = value;
      }
    }
    const klass = new Klass('from constructor');
    assert.equal(klass.log, 'from constructor');
    assert.equal(Klass.log, 'inside static block');
  });
  it('a static block is run before a constructor', () => {
    const steps = [];
    class Klass {
      constructor() {
        steps.push('constructor');
      }
      static {
        steps.push('static block');
      }
    }
    new Klass();
    new Klass();
    assert.deepEqual(steps, ['static block', 'constructor', 'constructor']);
  });
});