Skip to content

Commit

Permalink
All-transition hooks, fixes StoneCypher/fsl#665, fixes StoneCypher/fs…
Browse files Browse the repository at this point in the history
  • Loading branch information
StoneCypher committed May 8, 2022
1 parent d5cc00e commit ec455c7
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 21 deletions.
14 changes: 7 additions & 7 deletions benchmark/results/general.chart.html
Expand Up @@ -28,7 +28,7 @@
</head>
<body>
<div class="container">
<canvas id="chart1651995427476" width="16" height="9"></canvas>
<canvas id="chart1651997014689" width="16" height="9"></canvas>
</div>
<script>
const format = (num) => {
Expand All @@ -51,18 +51,18 @@
chunked.map((chunk) => chunk.join('')).join(' ') + fractionStr
)
}
const ctx1651995427476 = document
.getElementById('chart1651995427476')
const ctx1651997014689 = document
.getElementById('chart1651997014689')
.getContext('2d')
const chart1651995427476 = new Chart(ctx1651995427476, {
const chart1651997014689 = new Chart(ctx1651997014689, {
type: 'bar',
data: {
labels: ["Blind cycle a traffic light 500 times by transition","Blind cycle a hooked traffic light 500 times by transition","Blind cycle a traffic light 500 times by action","Blind cycle a hooked traffic light 500 times by action"],
datasets: [
{
data: [21875,1683,13445,1459],
backgroundColor: ["hsl(120, 85%, 55%)","hsl(9.227999999999998, 85%, 55%)","hsl(73.75200000000001, 85%, 55%)","hsl(8.004000000000003, 85%, 55%)"],
borderColor: ["hsl(120, 85%, 55%)","hsl(9.227999999999998, 85%, 55%)","hsl(73.75200000000001, 85%, 55%)","hsl(8.004000000000003, 85%, 55%)"],
data: [21012,1747,14556,1488],
backgroundColor: ["hsl(120, 85%, 55%)","hsl(9.972000000000003, 85%, 55%)","hsl(83.124, 85%, 55%)","hsl(8.495999999999999, 85%, 55%)"],
borderColor: ["hsl(120, 85%, 55%)","hsl(9.972000000000003, 85%, 55%)","hsl(83.124, 85%, 55%)","hsl(8.495999999999999, 85%, 55%)"],
borderWidth: 2,
},
],
Expand Down
24 changes: 12 additions & 12 deletions benchmark/results/general.json
@@ -1,31 +1,31 @@
{
"name": "General performance suite",
"date": "2022-05-08T07:37:07.476Z",
"date": "2022-05-08T08:03:34.689Z",
"version": "1.1.0",
"results": [
{
"name": "Blind cycle a traffic light 500 times by transition",
"ops": 21875,
"margin": 1.34,
"ops": 21012,
"margin": 1.45,
"percentSlower": 0
},
{
"name": "Blind cycle a hooked traffic light 500 times by transition",
"ops": 1683,
"margin": 2.98,
"percentSlower": 92.31
"ops": 1747,
"margin": 0.62,
"percentSlower": 91.69
},
{
"name": "Blind cycle a traffic light 500 times by action",
"ops": 13445,
"margin": 1.65,
"percentSlower": 38.54
"ops": 14556,
"margin": 0.93,
"percentSlower": 30.73
},
{
"name": "Blind cycle a hooked traffic light 500 times by action",
"ops": 1459,
"margin": 1.21,
"percentSlower": 93.33
"ops": 1488,
"margin": 1.41,
"percentSlower": 92.92
}
],
"fastest": {
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/classes/Machine.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/docs/modules.html

Large diffs are not rendered by default.

106 changes: 106 additions & 0 deletions src/ts/tests/hooks.spec.ts
Expand Up @@ -52,6 +52,17 @@ describe('Basic hooks on API callpoint', () => {
} );


test('Setting an any-transition hook doesn\'t throw', () => {

expect( () => {
const _foo = sm`a 'foo' -> b;`;
_foo.set_hook({ handler: () => console.log('hi'), kind: 'any transition' })
})
.not.toThrow();

});


test('Setting a kind of hook that doesn\'t exist throws', () => {

expect( () => {
Expand Down Expand Up @@ -143,6 +154,101 @@ test('Named hook rejection doesn\'t block transitions', () => {



test('All-transition hook rejection works on actions', () => {

const foo = sm`a 'foo' => b;`;

foo.set_hook({ kind: 'any transition', handler: () => false });
expect(foo.action('foo')).toBe(false);
expect(foo.state()).toBe('a');

foo.set_hook({ kind: 'any transition', handler: () => true });
expect(foo.action('foo')).toBe(true);
expect(foo.state()).toBe('b');

});





test('All-transition hook rejection works on transitions', () => {

const foo = sm`a => b;`;

foo.set_hook({ kind: 'any transition', handler: () => false });
expect(foo.transition('b')).toBe(false);
expect(foo.state()).toBe('a');

foo.set_hook({ kind: 'any transition', handler: () => true });
expect(foo.transition('b')).toBe(true);
expect(foo.state()).toBe('b');

});





test('All-transition hook rejection works on forced transitions', () => {

const foo = sm`a ~> b;`;

foo.set_hook({ kind: 'any transition', handler: () => false });
expect(foo.force_transition('b')).toBe(false);
expect(foo.state()).toBe('a');

foo.set_hook({ kind: 'any transition', handler: () => true });
expect(foo.force_transition('b')).toBe(true);
expect(foo.state()).toBe('b');

});





test('All-transition fluent hook rejection works on transitions', () => {

const foo = sm`a => b;`
.hook_any_transition( () => false );

expect(foo.transition('b')).toBe(false);
expect(foo.state()).toBe('a');

foo.hook_any_transition( () => true );

expect(foo.transition('b')).toBe(true);
expect(foo.state()).toBe('b');

});





test('All-transition hook rejection prevents subsequent hooks', () => {

const foo = sm`a => b;`,
cnt = jest.fn(x => true);

foo.set_hook({ kind: 'any transition', handler: () => false });
foo.set_hook({ kind: 'hook', handler: cnt, from: 'a', to: 'b' });
expect(foo.transition('b')).toBe(false);
expect(foo.state()).toBe('a');
expect(cnt.mock.calls.length).toBe(0);

foo.set_hook({ kind: 'any transition', handler: () => true });
expect(foo.transition('b')).toBe(true);
expect(foo.state()).toBe('b');
expect(cnt.mock.calls.length).toBe(1);

});





describe('Basic hooks on API callpoint', () => {


Expand Down

0 comments on commit ec455c7

Please sign in to comment.