Skip to content

Commit

Permalink
add forced transitions, graph node lists, histo, stripes, theme, weig…
Browse files Browse the repository at this point in the history
…hted histo key, weighted rand select, weighted sample select
  • Loading branch information
StoneCypher committed Jan 15, 2021
1 parent 833ccda commit bdc5a4b
Show file tree
Hide file tree
Showing 9 changed files with 227 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .nycrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"exclude": [
"src/js/jssm-dot.js",
"src/ts/jssm-dot.*",
"build/**/*"
]
}
27 changes: 27 additions & 0 deletions src/ts/tests/forced transitions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

/* eslint-disable max-len */

const jssm = require('../jssm'),
sm = jssm.sm;





describe('reject and accept correctly', () => {

const machine = sm` a ~> b -> c; `;

test('starts in a', () => expect( machine.state() ).toBe('a') );
test('rejects transition to b', () => expect( machine.transition('b') ).toBe(false) );
test('still in a', () => expect( machine.state() ).toBe('a') );
test('rejects transition to c', () => expect( machine.transition('c') ).toBe(false) );
test('still in a 2', () => expect( machine.state() ).toBe('a') );
test('rejects forced transition to c', () => expect( machine.force_transition('c') ).toBe(false) );
test('still in a 3', () => expect( machine.state() ).toBe('a') );
test('accepts forced transition to b', () => expect( machine.force_transition('b') ).toBe(true) );
test('now in b', () => expect( machine.state() ).toBe('b') );
test('accepts transition to c', () => expect( machine.transition('c') ).toBe(true) );
test('now in c', () => expect( machine.state() ).toBe('c') );

});
22 changes: 22 additions & 0 deletions src/ts/tests/graph node lists.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

/* eslint-disable max-len */

const jssm = require('../jssm'),
sm = jssm.sm;





describe('graph node lists', () => {

test('start states don\'t throw', () => expect( () => { const _a = sm`start_states: [a b c]; a->b->c->d;`; }).not.toThrow() );
test('end states don\'t throw', () => expect( () => { const _a = sm`end_states: [a b c]; a->b->c->d;`; }).not.toThrow() );

test.todo('start node overrides');

// comeback whargarbl
// const overrider = make(` a->b->c; start_nodes: [c]; `);
// it('start nodes override initial node', t => t.is(0, () => {}) );

});
24 changes: 24 additions & 0 deletions src/ts/tests/histo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

const jssm = require('../jssm');





describe('histograph/1', () => {

test('([]) generates Map()', () =>
expect( jssm.histograph([]) ).toEqual( new Map( ) ) );

test('([1]) generates Map([[1,1]])', () =>
expect( jssm.histograph([1]) ).toEqual( new Map( [[1,1]] ) ) );

test('([1,2]) generates Map([[1,1],[2,1]])', () =>
expect( jssm.histograph([1,2]) ).toEqual( new Map( [[1,1],[2,1]] ) ) );

test('([1,1,2]) generates Map([[1,2],[2,1]])', () =>
expect( jssm.histograph([1,1,2]) ).toEqual( new Map( [[1,2],[2,1]] ) ) );

});

// stochable
52 changes: 52 additions & 0 deletions src/ts/tests/stripes.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

/* eslint-disable max-len */

const jssm = require('../../../build/jssm.es5.cjs.js');





describe('stripe strategies', () => {



const is_v = (str, v) =>
test(str, () =>
expect( jssm.parse(str) ).toEqual(v)
);



describe('basic stripe', () => {
is_v(
'[a b c] -> +|1;',
[{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'stripe', value: 1}}}]
);
});

describe('negative stripe', () => {
is_v(
'[a b c] -> -|1;',
[{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'stripe', value: -1}}}]
);
});

describe('wide stripe', () => {
is_v(
'[a b c] -> +|2;',
[{from: ['a','b','c'], key: 'transition', se: {kind: '->', to: {key: 'stripe', value: 2}}}]
);
});



test('illegal fractional stripe throws', () => {

expect( () =>
jssm.parse('[a b c] -> +|2.5;')
).toThrow();

});

});
24 changes: 24 additions & 0 deletions src/ts/tests/theme.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

import { Themes } from './constants.spec';

const jssm = require('../../../build/jssm.es5.cjs.js'),
sm = jssm.sm;





describe('Named themes', () => {

Themes.map(thisTheme =>
it(`Theme "${thisTheme}" parses as a theme`, () =>
expect( () => { const _foo = sm`theme: ${thisTheme}; a-> b;`; }).not.toThrow() ) );

Themes.map(thisTheme =>
it(`Theme "${thisTheme}" shows correct theme`, () =>
expect( sm`theme: ${thisTheme}; a-> b;`.theme() ).toBe(thisTheme) ) );

it('Fake theme throws', () =>
expect( () => { const _foo = sm`theme: zeghezgqqqqthirteen; a-> b;`; }).toThrow() );

});
22 changes: 22 additions & 0 deletions src/ts/tests/weighted_histo_key.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

const jssm = require('../jssm');





describe('weighted_histo_key/2', () => {

const fruit = [ { label: 'apple', probability: 0.1 },
{ label: 'orange', probability: 0.4 },
{ label: 'banana', probability: 0.5 } ];

const out = jssm.weighted_histo_key(10000, fruit, 'probability', 'label');

test('produces a well formed probability map', () =>
expect([... out.keys()].length).toBe(3)
);

});

// stochable
29 changes: 29 additions & 0 deletions src/ts/tests/weighted_rand_select.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

/* eslint-disable fp/no-loops */

const jssm = require('../jssm');





describe('weighted_rand_select/2', () => {

const fruit = [ { label: 'apple', probability: 0.1 },
{ label: 'orange', probability: 0.4 },
{ label: 'banana', probability: 0.5 } ];

const acc = { apple: 0, orange: 0, banana: 0 };

for (let i=0; i<10000; ++i) {
acc[jssm.weighted_rand_select(fruit).label] = acc[jssm.weighted_rand_select(fruit).label] + 1;
}

test('banana baseline', () => expect( acc.banana > 3000 ).toBe(true) );

test('requires an array', () => expect( () => jssm.weighted_rand_select( 'not_an_array' )).toThrow() );
test('requires members to be objects', () => expect( () => jssm.weighted_rand_select( ['not_an_obj'] )).toThrow() );

});

// stochable
26 changes: 26 additions & 0 deletions src/ts/tests/weighted_sample_select.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

const jssm = require('../jssm');





describe('weighted_sample_select/2', () => {

const fruit = [ { label: 'apple', probability: 0.1 },
{ label: 'orange', probability: 0.4 },
{ label: 'banana', probability: 0.5 } ];

const none = jssm.weighted_sample_select(0, fruit),
one = jssm.weighted_sample_select(1, fruit),
some = jssm.weighted_sample_select(2, fruit),
over = jssm.weighted_sample_select(4, fruit);

test('0 returns []', () => expect(none.length).toBe(0) );
test('1 returns [any]', () => expect(one.length ).toBe(1) );
test('2 returns [any,any]', () => expect(some.length).toBe(2) );
test('4 returns [any,any,any,any]', () => expect(over.length).toBe(4) );

});

// stochable

0 comments on commit bdc5a4b

Please sign in to comment.