From ec455c72ef81b7b3977936ea60077e4503a5fa1d Mon Sep 17 00:00:00 2001 From: John Haugeland Date: Sun, 8 May 2022 01:05:27 -0700 Subject: [PATCH] All-transition hooks, fixes StoneCypher/fsl#665, fixes StoneCypher/fsl#683 --- benchmark/results/general.chart.html | 14 ++-- benchmark/results/general.json | 24 +++--- docs/docs/classes/Machine.html | 2 +- docs/docs/modules.html | 2 +- src/ts/tests/hooks.spec.ts | 106 +++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 21 deletions(-) diff --git a/benchmark/results/general.chart.html b/benchmark/results/general.chart.html index adc7e0ac..ac91360b 100644 --- a/benchmark/results/general.chart.html +++ b/benchmark/results/general.chart.html @@ -28,7 +28,7 @@
- +
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_flow: FslDirection
_fsl_version?: string
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_hooks: Map<string, Function>
_machine_author?: string[]
_machine_comment?: string
_machine_contributor?: string[]
_machine_definition?: string
_machine_language?: string
_machine_license?: string
_machine_name?: string
_machine_version?: string
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • Parameters

    • state_config: JssmGenericState

    Returns string

  • action(name: string, newData?: mDT): boolean
  • Parameters

    • name: string
    • Optional newData: mDT

    Returns boolean

  • actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • current_action_edge_for(action: string): JssmTransition<mDT>
  • Parameters

    • action: string

    Returns JssmTransition<mDT>

  • current_action_for(action: string): number
  • Parameters

    • action: string

    Returns number

  • dot_preamble(): string
  • flow(): FslDirection
  • force_transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • fsl_version(): string
  • get_transition_by_state_names(from: string, to: string): number
  • Parameters

    • from: string
    • to: string

    Returns number

  • graph_layout(): string
  • has_completes(): boolean
  • has_state(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • has_terminals(): boolean
  • has_unenterables(): boolean
  • hook(from: string, to: string, handler: Function): Machine<mDT>
  • hook_action(from: string, to: string, action: string, handler: Function): Machine<mDT>
  • Parameters

    • from: string
    • to: string
    • action: string
    • handler: Function

    Returns Machine<mDT>

  • hook_any_transition(handler: Function): Machine<mDT>
  • is_complete(): boolean
  • is_final(): boolean
  • is_terminal(): boolean
  • is_unenterable(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • list_actions(): string[]
  • list_edges(): JssmTransition<mDT>[]
  • list_entrances(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exits(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • list_states_having_action(whichState: string): string[]
  • Parameters

    • whichState: string

    Returns string[]

  • list_transitions(whichState?: string): JssmTransitionList
  • Parameters

    • whichState: string = ...

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<mDT>
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>

  • machine_author(): string[]
  • machine_comment(): string
  • machine_contributor(): string[]
  • machine_definition(): string
  • machine_language(): string
  • machine_license(): string
  • machine_name(): string
  • machine_state(): JssmMachineInternalState<mDT>
  • Returns JssmMachineInternalState<mDT>

  • machine_version(): string
  • probabilistic_histo_walk(n: number): Map<string, number>
  • Parameters

    • n: number

    Returns Map<string, number>

  • probabilistic_transition(): boolean
  • probabilistic_walk(n: number): string[]
  • Parameters

    • n: number

    Returns string[]

  • probable_action_exits(whichState?: string): any[]
  • Parameters

    • whichState: string = ...

    Returns any[]

  • probable_exits_for(whichState: string): JssmTransition<mDT>[]
  • Parameters

    • whichState: string

    Returns JssmTransition<mDT>[]

  • raw_state_declarations(): Object[]
  • set_hook(HookDesc: HookDescription): void
  • Parameters

    • HookDesc: HookDescription

    Returns void

  • sm(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • state(): string
  • state_declaration(which: string): JssmStateDeclaration
  • Parameters

    • which: string

    Returns JssmStateDeclaration

  • state_declarations(): Map<string, JssmStateDeclaration>
  • Returns Map<string, JssmStateDeclaration>

  • state_for(whichState: string): JssmGenericState
  • Parameters

    • whichState: string

    Returns JssmGenericState

  • state_is_complete(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_final(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • states(): string[]
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Generated using TypeDoc

\ No newline at end of file +Machine | jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_flow: FslDirection
_fsl_version?: string
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_hooks: Map<string, Function>
_machine_author?: string[]
_machine_comment?: string
_machine_contributor?: string[]
_machine_definition?: string
_machine_language?: string
_machine_license?: string
_machine_name?: string
_machine_version?: string
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • Parameters

    • state_config: JssmGenericState

    Returns string

  • action(name: string, newData?: mDT): boolean
  • Parameters

    • name: string
    • Optional newData: mDT

    Returns boolean

  • actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • current_action_edge_for(action: string): JssmTransition<mDT>
  • Parameters

    • action: string

    Returns JssmTransition<mDT>

  • current_action_for(action: string): number
  • Parameters

    • action: string

    Returns number

  • dot_preamble(): string
  • flow(): FslDirection
  • force_transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • fsl_version(): string
  • get_transition_by_state_names(from: string, to: string): number
  • Parameters

    • from: string
    • to: string

    Returns number

  • graph_layout(): string
  • has_completes(): boolean
  • has_state(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • has_terminals(): boolean
  • has_unenterables(): boolean
  • hook(from: string, to: string, handler: Function): Machine<mDT>
  • hook_action(from: string, to: string, action: string, handler: Function): Machine<mDT>
  • Parameters

    • from: string
    • to: string
    • action: string
    • handler: Function

    Returns Machine<mDT>

  • hook_any_transition(handler: Function): Machine<mDT>
  • is_complete(): boolean
  • is_final(): boolean
  • is_terminal(): boolean
  • is_unenterable(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • list_actions(): string[]
  • list_edges(): JssmTransition<mDT>[]
  • list_entrances(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exit_actions(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_exits(whichState?: string): string[]
  • Parameters

    • whichState: string = ...

    Returns string[]

  • list_named_transitions(): Map<string, number>
  • list_states_having_action(whichState: string): string[]
  • Parameters

    • whichState: string

    Returns string[]

  • list_transitions(whichState?: string): JssmTransitionList
  • Parameters

    • whichState: string = ...

    Returns JssmTransitionList

  • lookup_transition_for(from: string, to: string): JssmTransition<mDT>
  • Parameters

    • from: string
    • to: string

    Returns JssmTransition<mDT>

  • machine_author(): string[]
  • machine_comment(): string
  • machine_contributor(): string[]
  • machine_definition(): string
  • machine_language(): string
  • machine_license(): string
  • machine_name(): string
  • machine_state(): JssmMachineInternalState<mDT>
  • Returns JssmMachineInternalState<mDT>

  • machine_version(): string
  • probabilistic_histo_walk(n: number): Map<string, number>
  • Parameters

    • n: number

    Returns Map<string, number>

  • probabilistic_transition(): boolean
  • probabilistic_walk(n: number): string[]
  • Parameters

    • n: number

    Returns string[]

  • probable_action_exits(whichState?: string): any[]
  • Parameters

    • whichState: string = ...

    Returns any[]

  • probable_exits_for(whichState: string): JssmTransition<mDT>[]
  • Parameters

    • whichState: string

    Returns JssmTransition<mDT>[]

  • raw_state_declarations(): Object[]
  • set_hook(HookDesc: HookDescription): void
  • Parameters

    • HookDesc: HookDescription

    Returns void

  • sm(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • state(): string
  • state_declaration(which: string): JssmStateDeclaration
  • Parameters

    • which: string

    Returns JssmStateDeclaration

  • state_declarations(): Map<string, JssmStateDeclaration>
  • Returns Map<string, JssmStateDeclaration>

  • state_for(whichState: string): JssmGenericState
  • Parameters

    • whichState: string

    Returns JssmGenericState

  • state_is_complete(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_final(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • state_is_terminal(whichState: string): boolean
  • Parameters

    • whichState: string

    Returns boolean

  • states(): string[]
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/docs/modules.html b/docs/docs/modules.html index 168b2a2d..a450adb6 100644 --- a/docs/docs/modules.html +++ b/docs/docs/modules.html @@ -1 +1 @@ -jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

histograph: Function = ...
seq: Function = ...
version: string = "5.49.0"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • Parameters

    • input: string
    • Optional options: Object

    Returns any

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • Parameters

    • state_decl: JssmStateDeclaration

    Returns JssmStateDeclaration

Generated using TypeDoc

\ No newline at end of file +jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

histograph: Function = ...
seq: Function = ...
version: string = "5.49.0"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • Parameters

    • input: string
    • Optional options: Object

    Returns any

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • Parameters

    • state_decl: JssmStateDeclaration

    Returns JssmStateDeclaration

Generated using TypeDoc

\ No newline at end of file diff --git a/src/ts/tests/hooks.spec.ts b/src/ts/tests/hooks.spec.ts index 75b86367..87178d87 100644 --- a/src/ts/tests/hooks.spec.ts +++ b/src/ts/tests/hooks.spec.ts @@ -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( () => { @@ -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', () => {