Skip to content

Commit

Permalink
Cleanup @xstate/vue tests (#4506)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist authored Nov 27, 2023
1 parent a9c8ecc commit ef4db67
Show file tree
Hide file tree
Showing 23 changed files with 157 additions and 936 deletions.
214 changes: 2 additions & 212 deletions packages/xstate-react/test/typegenTypes.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,180 +53,10 @@ describe('useMachine', () => {

render(<App />);
});

it('should require all missing implementations ', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: 'myAction';
delays: 'myDelay';
guards: never;
actors: never;
};
eventsCausingActions: {
myAction: 'FOO';
myDelay: 'BAR';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' } | { type: 'BAZ' }
}
});

function App() {
// @ts-expect-error
useMachine(machine);
useMachine(
machine.provide({
// @ts-expect-error
actions: {}
})
);
useMachine(
// @ts-expect-error
machine.provide({
actions: {
myAction: () => {}
}
})
);
useMachine(
machine.provide({
actions: {
myAction: () => {}
},
delays: {
myDelay: () => 42
}
})
);
return null;
}

render(<App />);
});

it('should allow to override already provided implementation', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: 'fooAction';
delays: never;
guards: never;
actors: never;
};
eventsCausingActions: { fooAction: 'FOO' };
eventsCausingDelays: { barDelay: 'BAR' };
}

const machine = createMachine(
{
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' } | { type: 'BAZ' }
}
},
{
delays: {
barDelay: () => 42
}
}
);

function App() {
useMachine(
machine.provide({
actions: {
fooAction: () => {}
},
delays: {
barDelay: () => 100
}
})
);
return null;
}

render(<App />);
});

it('should accept a machine that accepts a specific subset of events in one of the implementations', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: never;
actors: never;
guards: never;
delays: never;
};
eventsCausingActions: {
fooAction: 'FOO';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' }
}
});

function App() {
useMachine(
machine.provide({
actions: {
// it's important to use `event` here somehow to make this a possible source of information for inference
fooAction: () => {}
}
})
);
return null;
}

render(<App />);
});

it('should provide subset of the event type to action objects given in the `options` argument', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: never;
actors: never;
guards: never;
delays: never;
};
eventsCausingActions: {
fooAction: 'FOO';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' }
}
});

function App() {
useMachine(
machine.provide({
actions: {
fooAction: assign(({ event }) => {
((_accept: 'FOO') => {})(event.type);
// @ts-expect-error
((_accept: "test that this isn't any") => {})(event.type);
})
}
})
);
return null;
}

render(<App />);
});
});

describe('useActorRef', () => {
it('Should handle multiple state.matches when passed TypegenMeta', () => {
it('should handle multiple state.matches when passed TypegenMeta', () => {
interface TypesMeta extends TypegenMeta {
matchesStates: 'a' | 'b';
missingImplementations: {
Expand Down Expand Up @@ -254,7 +84,7 @@ describe('useActorRef', () => {
};
});

it('Should handle multiple state.matches when NOT passed TypegenMeta', () => {
it('should handle multiple state.matches when NOT passed TypegenMeta', () => {
const machine = createMachine({});

() => {
Expand Down Expand Up @@ -497,46 +327,6 @@ describe('createActorContext', () => {
render(<App />);
});

it('should accept a machine that accepts a specific subset of events in one of the implementations', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
actions: never;
actors: never;
guards: never;
delays: never;
};
eventsCausingActions: {
fooAction: 'FOO';
};
}

const machine = createMachine({
types: {
typegen: {} as TypesMeta,
events: {} as { type: 'FOO' } | { type: 'BAR' }
}
});

const Context = createActorContext(machine);

function App() {
return (
<Context.Provider
logic={machine.provide({
actions: {
// it's important to use `event` here somehow to make this a possible source of information for inference
fooAction: () => {}
}
})}
>
{null}
</Context.Provider>
);
}

render(<App />);
});

it('should provide subset of the event type to action objects given in the `options` argument', () => {
interface TypesMeta extends TypegenMeta {
missingImplementations: {
Expand Down
11 changes: 11 additions & 0 deletions packages/xstate-vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,23 @@
"import": "./dist/xstate-vue.cjs.mjs",
"default": "./dist/xstate-vue.cjs.js"
},
"development": {
"module": "./dist/xstate-vue.development.esm.js",
"import": "./dist/xstate-vue.development.cjs.mjs",
"default": "./dist/xstate-vue.development.cjs.js"
},
"module": "./dist/xstate-vue.esm.js",
"import": "./dist/xstate-vue.cjs.mjs",
"default": "./dist/xstate-vue.cjs.js"
},
"./package.json": "./package.json"
},
"imports": {
"#is-development": {
"development": "./src/true.ts",
"default": "./src/false.ts"
}
},
"sideEffects": false,
"files": [
"dist"
Expand Down
1 change: 1 addition & 0 deletions packages/xstate-vue/src/false.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default false;
2 changes: 1 addition & 1 deletion packages/xstate-vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { useMachine } from './useMachine.ts';
export { useActor } from './useActor.ts';
export { useActorRef } from './useActorRef.ts';
export { useMachine } from './useMachine.ts';
export { useSelector } from './useSelector.ts';
1 change: 1 addition & 0 deletions packages/xstate-vue/src/true.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default true;
3 changes: 0 additions & 3 deletions packages/xstate-vue/src/types.ts

This file was deleted.

29 changes: 16 additions & 13 deletions packages/xstate-vue/src/useActor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Ref, shallowRef } from 'vue';
import isDevelopment from '#is-development';
import { Ref } from 'vue';
import {
ActorOptions,
ActorRefFrom,
Expand All @@ -7,35 +8,37 @@ import {
Snapshot,
SnapshotFrom
} from 'xstate';
import { UseActorRefRestParams, useActorRef } from './useActorRef.ts';
import { useActorRef } from './useActorRef.ts';
import { useSelector } from './useSelector.ts';

export function useActor<TLogic extends AnyActorLogic>(
actorLogic: TLogic,
...[options = {}]: UseActorRefRestParams<TLogic>
options: ActorOptions<TLogic>
): {
snapshot: Ref<SnapshotFrom<TLogic>>;
send: (event: EventFrom<TLogic>) => void;
actorRef: ActorRefFrom<TLogic>;
};
export function useActor(
actorLogic: AnyActorLogic,
options?: ActorOptions<AnyActorLogic>
options: ActorOptions<AnyActorLogic> = {}
) {
if (process.env.NODE_ENV !== 'production') {
if ('send' in actorLogic && typeof actorLogic.send === 'function') {
throw new Error(
`useActor() expects actor logic (e.g. a machine), but received an ActorRef. Use the useSelector(actorRef, ...) hook instead to read the ActorRef's snapshot.`
);
}
if (
isDevelopment &&
'send' in actorLogic &&
typeof actorLogic.send === 'function'
) {
throw new Error(
`useActor() expects actor logic (e.g. a machine), but received an ActorRef. Use the useSelector(actorRef, ...) hook instead to read the ActorRef's snapshot.`
);
}

function listener(nextState: Snapshot<unknown>) {
snapshot.value = nextState;
function listener(nextSnapshot: Snapshot<unknown>) {
snapshot.value = nextSnapshot;
}

const actorRef = useActorRef(actorLogic, options, listener);
const snapshot = useSelector(actorRef, (state) => state);
const snapshot = useSelector(actorRef, (s) => s);

return {
snapshot,
Expand Down
14 changes: 5 additions & 9 deletions packages/xstate-vue/src/useActorRef.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
import { onBeforeUnmount, onMounted } from 'vue';
import {
ActorOptions,
ActorRefFrom,
AnyActorLogic,
createActor,
ActorOptions,
Observer,
SnapshotFrom,
Subscription,
createActor,
toObserver
} from 'xstate';

export type UseActorRefRestParams<TLogic extends AnyActorLogic> = [
options?: ActorOptions<TLogic>,
export function useActorRef<TLogic extends AnyActorLogic>(
actorLogic: TLogic,
options: ActorOptions<TLogic> = {},
observerOrListener?:
| Observer<SnapshotFrom<TLogic>>
| ((value: SnapshotFrom<TLogic>) => void)
];

export function useActorRef<TLogic extends AnyActorLogic>(
actorLogic: TLogic,
...[options = {}, observerOrListener]: UseActorRefRestParams<TLogic>
): ActorRefFrom<TLogic> {
const actorRef = createActor(actorLogic, options);

Expand Down
4 changes: 2 additions & 2 deletions packages/xstate-vue/src/useMachine.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Ref } from 'vue';
import {
ActorOptions,
ActorRefFrom,
AnyStateMachine,
AreAllImplementationsAssumedToBeProvided,
EventFrom,
ActorOptions,
MissingImplementationsError,
SnapshotFrom
} from 'xstate';
import { useActor } from './useActor.ts';
import { Ref } from 'vue';

/**
* @alias useActor
Expand Down
3 changes: 1 addition & 2 deletions packages/xstate-vue/src/useSelector.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { shallowRef, Ref, isRef, watch } from 'vue';
import { Ref, isRef, shallowRef, watch } from 'vue';
import { ActorRef, SnapshotFrom } from 'xstate';

function defaultCompare<T>(a: T, b: T) {
Expand All @@ -23,7 +23,6 @@ export function useSelector<TActor extends ActorRef<any, any>, T>(
}
};

// TODO: add test for actor changing
watch(
actorRefRef,
(newActor, _, onCleanup) => {
Expand Down
File renamed without changes.
Loading

0 comments on commit ef4db67

Please sign in to comment.