Statics & Constants
Tests in this category ensure static methods, static properties and constants are accessible from the host.
Constants can be read
Test: constantsCanBeRead
static readonly properties of a jsii class are constants. The host MUST be able to read constants of any type,
including object references, without creating an instance of the class. Reading a constant MUST return the value
initialized in JavaScript.
Reference Implementation
// GIVEN
export class DoubleTrouble {
public hello() {
return 'world';
}
}
export class Statics {
public static readonly Foo = 'hello';
public static readonly BAR = 1234;
public static readonly zooBar: { [name: string]: string } = { hello: 'world' };
public static readonly ConstObj = new DoubleTrouble();
}
// WHEN
const obj = Statics.ConstObj;
// THEN
expect(Statics.Foo).toBe('hello');
expect(Statics.BAR).toBe(1234);
expect(Statics.zooBar['hello']).toBe('world');
expect(obj.hello()).toBe('world');
Static methods and properties can be used
Test: staticMembersCanBeUsed
Static methods of a jsii class MUST be invocable from the host without an instance, and MUST accept and return values of
their declared types. Static properties MUST be readable from the host, and static properties that are not readonly
MUST also be writable. A value assigned from the host MUST be returned by subsequent reads, and MAY be an object
reference created by the host.
Reference Implementation
// GIVEN
export class Statics {
public constructor(public readonly value: string) {}
public static staticMethod(name: string) {
return `hello ,${name}!`;
}
private static _instance?: Statics;
public static get instance(): Statics {
this._instance ??= new Statics('default');
return this._instance;
}
public static set instance(val: Statics) {
this._instance = val;
}
public static nonConstStatic = 100;
}
// WHEN
const greeting = Statics.staticMethod('Yoyo');
const defaultInstance = Statics.instance;
const newStatics = new Statics('new value');
Statics.instance = newStatics;
// THEN
expect(greeting).toBe('hello ,Yoyo!');
expect(defaultInstance.value).toBe('default');
expect(Statics.instance).toBe(newStatics);
expect(Statics.instance.value).toBe('new value');
expect(Statics.nonConstStatic).toBe(100);
Assigning a static property updates the value in JavaScript
Test: staticPropertyAssignmentUpdatesJavaScript
Assigning a value to a static property from the host MUST call the property's setter in the kernel, so that the new value is observable from JavaScript. The host MUST NOT store the assigned value only on the host side, for example by replacing the host representation of the property.
Reference Implementation
// GIVEN
export class StaticPropertyAssignment {
public static value = 'default';
/** Reads `value` from within JavaScript, so that host language assignments are observable. */
public static readValue(): string {
return StaticPropertyAssignment.value;
}
private constructor() {}
}
// WHEN
const before = StaticPropertyAssignment.readValue();
StaticPropertyAssignment.value = 'assigned';
// THEN
expect(before).toBe('default');
expect(StaticPropertyAssignment.readValue()).toBe('assigned');
expect(StaticPropertyAssignment.value).toBe('assigned');
Kernel Trace
> {"api":"sinvoke","fqn":"jsii-calc.StaticPropertyAssignment","method":"readValue","args":[]}
< {"ok":{"result":"default"}}
> {"api":"sset","fqn":"jsii-calc.StaticPropertyAssignment","property":"value","value":"assigned"}
< {"ok":{}}
> {"api":"sinvoke","fqn":"jsii-calc.StaticPropertyAssignment","method":"readValue","args":[]}
< {"ok":{"result":"assigned"}}
> {"api":"sget","fqn":"jsii-calc.StaticPropertyAssignment","property":"value"}
< {"ok":{"value":"assigned"}}