Skip to content

Commit

Permalink
fix(test): cover i18next locale, local script services
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed May 26, 2021
1 parent dea790e commit 25a2e7a
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 20 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -88,6 +88,7 @@ test: node_modules out
NYC_ARGS := --all \
--check-coverage \
--exclude ".eslintrc.js" \
--exclude "bundle/**" \
--exclude "config/**" \
--exclude "docs/**" \
--exclude "out/coverage/**" \
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -37,6 +37,7 @@
"@types/react-dom": "^17.0.5",
"@types/seedrandom": "^3.0.0",
"@types/sinon": "^10.0.0",
"@types/sinon-chai": "^3.2.5",
"@types/yargs-parser": "^20.2.0",
"@typescript-eslint/eslint-plugin": "^4.24.0",
"@typescript-eslint/parser": "^4.24.0",
Expand Down
2 changes: 1 addition & 1 deletion src/error/AbortEventError.ts
@@ -1,3 +1,3 @@
import { BaseError } from 'noicejs';

export class AbortEventError extends BaseError { /* noop */ }
export class AbortEventError extends BaseError { /* noop */ }
6 changes: 0 additions & 6 deletions src/service/render/InkRender.ts
Expand Up @@ -7,12 +7,6 @@ import { RenderService } from '.';
import { Frame } from '../../component/ink/Frame';
import { BaseReactRender } from './BaseReactRender';

export interface InkState {
input: string;
prompt: string;
output: Array<string>;
}

/**
* Interface with Ink's React tree using an event emitter.
*/
Expand Down
6 changes: 0 additions & 6 deletions src/service/render/ReactDomRender.ts
Expand Up @@ -7,12 +7,6 @@ import { RenderService } from '.';
import { Frame } from '../../component/react/Frame';
import { BaseReactRender } from './BaseReactRender';

export interface InkState {
input: string;
prompt: string;
output: Array<string>;
}

/**
* Interface with React tree using an event emitter.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/service/script/LocalScript.ts
Expand Up @@ -33,11 +33,11 @@ export class LocalScriptService implements ScriptService {
protected logger: Logger;
protected scripts: Map<string, ScriptFunction>;

constructor(options: LocalScriptServiceOptions) {
constructor(options: LocalScriptServiceOptions, scripts = COMMON_SCRIPTS) {
this.logger = options[INJECT_LOGGER].child({
kind: constructorName(this),
});
this.scripts = new Map(COMMON_SCRIPTS);
this.scripts = new Map(scripts);
}

public async invoke(target: ScriptTarget, slot: string, scope: SuppliedScope): Promise<void> {
Expand Down
72 changes: 69 additions & 3 deletions test/service/locale/TestNextLocale.ts
@@ -1,6 +1,72 @@
import { NotFoundError } from '@apextoaster/js-utils';
import { expect } from 'chai';
import { Container, NullLogger } from 'noicejs';

import { LocalModule } from '../../../src/module/LocalModule';
import { NextLocaleService } from '../../../src/service/locale/NextLocale';

describe('next locale service', () => {
xit('should have an i18next instance after being started');
xit('should translate keys with context');
it('should have an i18next instance after being started', async () => {
const container = Container.from(new LocalModule());
await container.configure({
logger: NullLogger.global,
});

const locale = await container.create(NextLocaleService);

expect(() => locale.getInstance()).to.throw(NotFoundError);

await locale.start();

expect(locale.getInstance()).not.to.equal(undefined);
});

it('should prefer the world bundle', async () => {
const container = Container.from(new LocalModule());
await container.configure({
logger: NullLogger.global,
});

const locale = await container.create(NextLocaleService);
await locale.start();

locale.addBundle('common', {
bundles: {
en: {
foo: 'bar',
},
},
});
locale.addBundle('world', {
bundles: {
en: {
foo: 'bin',
},
},
});

expect(locale.translate('foo')).to.equal('bin');
});

it('should translate keys with context', async () => {
const container = Container.from(new LocalModule());
await container.configure({
logger: NullLogger.global,
});

const locale = await container.create(NextLocaleService);
await locale.start();

locale.addBundle('common', {
bundles: {
en: {
foo: '{{size}} bar',
},
},
});

expect(locale.translate('foo', { size: 4 })).to.equal('4 bar');
});

xit('should remove language bundles');
xit('should prefer the world bundle');
});
158 changes: 157 additions & 1 deletion test/service/script/TestLocalScript.ts
@@ -1,5 +1,161 @@
import { expect } from 'chai';
import { Container, NullLogger } from 'noicejs';
import { spy } from 'sinon';

import { Item } from '../../../src/model/entity/Item';
import { State } from '../../../src/model/State';
import { LocalModule } from '../../../src/module/LocalModule';
import { LocalScriptService } from '../../../src/service/script/LocalScript';
import { StateEntityTransfer } from '../../../src/util/state/EntityTransfer';
import { StateFocusResolver } from '../../../src/util/state/FocusResolver';

const TEST_STATE: State = {
focus: {
actor: '',
room: '',
},
meta: {
desc: '',
id: '',
name: '',
template: '',
},
rooms: [],
start: {
actor: '',
room: '',
},
step: {
time: 0,
turn: 0,
},
world: {
depth: 0,
seed: '',
},
};

describe('local script service', () => {
xit('should invoke the script with target');
it('should invoke the script with target', async () => {
const container = Container.from(new LocalModule());
await container.configure({
logger: NullLogger.global,
});

const target: Item = {
type: 'item',
meta: {
desc: '',
id: '',
name: '',
template: '',
},
slots: new Map(),
stats: new Map(),
verbs: new Map(),
};

const script = await container.create(LocalScriptService, {}, new Map());
await script.invoke(target, 'foo', {
data: new Map(),
focus: await container.create(StateFocusResolver, {
events: {
onActor: async () => { },
onRoom: async () => { },
onShow: async () => { },
},
state: TEST_STATE,
}),
state: TEST_STATE,
transfer: await container.create(StateEntityTransfer, {
state: TEST_STATE,
}),
});
});

it('should gracefully handle unknown scripts', async () => {
const container = Container.from(new LocalModule());
await container.configure({
logger: NullLogger.global,
});

const target: Item = {
type: 'item',
meta: {
desc: '',
id: '',
name: '',
template: '',
},
slots: new Map([
['foo', 'none'],
]),
stats: new Map(),
verbs: new Map(),
};

const script = await container.create(LocalScriptService, {}, new Map());
await script.invoke(target, 'foo', {
data: new Map(),
focus: await container.create(StateFocusResolver, {
events: {
onActor: async () => { },
onRoom: async () => { },
onShow: async () => { },
},
state: TEST_STATE,
}),
state: TEST_STATE,
transfer: await container.create(StateEntityTransfer, {
state: TEST_STATE,
}),
});
});

it('should invoke scripts with entity', async () => {
const container = Container.from(new LocalModule());
await container.configure({
logger: NullLogger.global,
});

const target: Item = {
type: 'item',
meta: {
desc: '',
id: '',
name: '',
template: '',
},
slots: new Map([
['foo', 'bar'],
]),
stats: new Map(),
verbs: new Map(),
};

const scriptSpy = spy();
const script = await container.create(LocalScriptService, {}, new Map([
['bar', scriptSpy],
]));
await script.invoke(target, 'foo', {
data: new Map(),
focus: await container.create(StateFocusResolver, {
events: {
onActor: async () => { },
onRoom: async () => { },
onShow: async () => { },
},
state: TEST_STATE,
}),
state: TEST_STATE,
transfer: await container.create(StateEntityTransfer, {
state: TEST_STATE,
}),
});

expect(scriptSpy).to.have.callCount(1);
});

xit('should gracefully handle undefined slots');
xit('should broadcast events to matching entities');
});
2 changes: 2 additions & 0 deletions test/setup.ts
@@ -1,8 +1,10 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import sinonChai from 'sinon-chai';

export function setupTests(): void {
chai.use(chaiAsPromised);
chai.use(sinonChai);
}

setupTests();
3 changes: 2 additions & 1 deletion tsconfig.json
Expand Up @@ -26,7 +26,8 @@
"types": [
"chai-as-promised",
"mocha",
"node"
"node",
"sinon-chai"
],
"typeRoots": [
"./node_modules/@types",
Expand Down
22 changes: 22 additions & 0 deletions yarn.lock
Expand Up @@ -618,6 +618,13 @@
dependencies:
"@sinonjs/commons" "^1.7.0"

"@sinonjs/fake-timers@^7.1.0":
version "7.1.0"
resolved "https://artifacts.apextoaster.com/repository/group-npm/@sinonjs/fake-timers/-/fake-timers-7.1.0.tgz#8f13af27d842cbf51ad4502e05562fe9391d084e"
integrity sha512-hAEzXi6Wbvlb67NnGMGSNOeAflLVnMa4yliPU/ty1qjgW/vAletH15/v/esJwASSIA0YlIyjnloenFbEZc9q9A==
dependencies:
"@sinonjs/commons" "^1.7.0"

"@sinonjs/samsam@^5.3.1":
version "5.3.1"
resolved "https://artifacts.apextoaster.com/repository/group-npm/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f"
Expand Down Expand Up @@ -796,6 +803,21 @@
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/seedrandom/-/seedrandom-3.0.0.tgz#13f4d71aa58cf6068a2e75261a4580fb71dc84e6"
integrity sha512-Jr03BtXs7v6M/wtTum2VOMLBq7R8zpjdZLynhA/IOJq83czXrnVo8iSUI05gcq8Ecq0Swt+nuoK3y2ji/TWyMA==

"@types/sinon-chai@^3.2.5":
version "3.2.5"
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48"
integrity sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==
dependencies:
"@types/chai" "*"
"@types/sinon" "*"

"@types/sinon@*":
version "10.0.1"
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/sinon/-/sinon-10.0.1.tgz#97ccb0482b750f5140ffdc661240ebbbe6e28d75"
integrity sha512-tZulsvuJwif5ddTBtscflI7gJcd+RpENcNZ7QCp0jKEl0bZY3Pu6PbJs4GR3SfQkGgsUa+FrlKsKQ0XyGNvDuA==
dependencies:
"@sinonjs/fake-timers" "^7.1.0"

"@types/sinon@^10.0.0":
version "10.0.0"
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/sinon/-/sinon-10.0.0.tgz#eecc3847af03d45ffe53d55aaaaf6ecb28b5e584"
Expand Down

0 comments on commit 25a2e7a

Please sign in to comment.