import { describe, it, expect } from 'vitest'; import { FlowfulError } from '../src/error'; import { actionCreatorSingle, actionCreatorMulti, actionCreator, actionCreatorDefault, ACTION_MODE_SINGLE, ACTION_MODE_MULTI, } from '../src/action'; import { skipDevMessages } from '../src/dev'; import { MODE_DEV, setGlobalMode } from '../src/mode'; setGlobalMode(MODE_DEV); skipDevMessages(true); describe('actionCreatorSingle', () => { it('should create a single mode action creator', () => { const type = 'TEST_ACTION_SINGLE'; const creator = actionCreatorSingle(type); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_SINGLE); }); it('should create a single mode action when called', () => { const type = 'TEST_ACTION_SINGLE'; const payload = 'test payload'; const creator = actionCreatorSingle(type); const action = creator(payload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(payload); expect(action.creator).toBe(creator); }); }); describe('actionCreatorMulti', () => { it('should create a multi mode action creator', () => { const type = 'TEST_ACTION_MULTI'; const creator = actionCreatorMulti(type); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_MULTI); }); it('should create a multi mode action when called', () => { const type = 'TEST_ACTION_MULTI'; const payload = 123; const creator = actionCreatorMulti(type); const action = creator(payload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_MULTI); expect(action.payload).toBe(payload); expect(action.creator).toBe(creator); }); }); describe('actionCreator', () => { it('should create a single mode action creator by default', () => { const type = 'TEST_ACTION_DEFAULT'; const creator = actionCreator(type); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_SINGLE); const payload = true; const action = creator(payload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(payload); expect(action.creator).toBe(creator); }); it('should create a single mode action creator when specified', () => { const type = 'TEST_ACTION_EXPLICIT_SINGLE'; const creator = actionCreator(type, ACTION_MODE_SINGLE); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_SINGLE); const payload = 'explicit single'; const action = creator(payload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(payload); expect(action.creator).toBe(creator); }); it('should create a multi mode action creator when specified', () => { const type = 'TEST_ACTION_EXPLICIT_MULTI'; const creator = actionCreator(type, ACTION_MODE_MULTI); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_MULTI); const payload = 456; const action = creator(payload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_MULTI); expect(action.payload).toBe(payload); expect(action.creator).toBe(creator); }); it('should throw FlowfulError for invalid mode', () => { const type = 'TEST_ACTION_INVALID_MODE'; const invalidMode: any = 'invalid'; expect(() => actionCreator(type, invalidMode)).toThrow(FlowfulError); expect(() => actionCreator(type, invalidMode)).toThrow( `[Flowful][actionCreator] Invalid mode: "${invalidMode}" for action "${type}". Must be "${ACTION_MODE_SINGLE}" or "${ACTION_MODE_MULTI}".` ); }); }); describe('actionCreatorDefault', () => { const type = 'TEST_ACTION_DEFAULT_PAYLOAD'; const defaultPayload = { value: 'default' }; const providedPayload = { value: 'provided' }; it('should create a single mode action creator by default', () => { const creator = actionCreatorDefault(type, defaultPayload); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_SINGLE); }); it('should use default payload in single mode when none provided', () => { const creator = actionCreatorDefault(type, defaultPayload); const action = creator(); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(defaultPayload); expect(action.creator).toBe(creator); }); it('should use provided payload in single mode when provided', () => { const creator = actionCreatorDefault(type, defaultPayload); const action = creator(providedPayload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(providedPayload); expect(action.creator).toBe(creator); }); it('should create a single mode action creator when specified', () => { const creator = actionCreatorDefault(type, defaultPayload, ACTION_MODE_SINGLE); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_SINGLE); }); it('should use default payload in explicit single mode when none provided', () => { const creator = actionCreatorDefault(type, defaultPayload, ACTION_MODE_SINGLE); const action = creator(); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(defaultPayload); expect(action.creator).toBe(creator); }); it('should use provided payload in explicit single mode when provided', () => { const creator = actionCreatorDefault(type, defaultPayload, ACTION_MODE_SINGLE); const action = creator(providedPayload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_SINGLE); expect(action.payload).toBe(providedPayload); expect(action.creator).toBe(creator); }); it('should create a multi mode action creator when specified', () => { const creator = actionCreatorDefault(type, defaultPayload, ACTION_MODE_MULTI); expect(creator.type).toBe(type); expect(creator.mode).toBe(ACTION_MODE_MULTI); }); it('should use default payload in multi mode when none provided', () => { const creator = actionCreatorDefault(type, defaultPayload, ACTION_MODE_MULTI); const action = creator(); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_MULTI); expect(action.payload).toBe(defaultPayload); expect(action.creator).toBe(creator); }); it('should use provided payload in multi mode when provided', () => { const creator = actionCreatorDefault(type, defaultPayload, ACTION_MODE_MULTI); const action = creator(providedPayload); expect(action.type).toBe(type); expect(action.mode).toBe(ACTION_MODE_MULTI); expect(action.payload).toBe(providedPayload); expect(action.creator).toBe(creator); }); it('should throw FlowfulError for invalid mode', () => { const invalidMode: any = 'invalid'; expect(() => actionCreatorDefault(type, defaultPayload, invalidMode)).toThrow(FlowfulError); expect(() => actionCreatorDefault(type, defaultPayload, invalidMode)).toThrow( `[Flowful][actionCreatorDefault] Invalid action mode: "${invalidMode}" for action "${type}". Must be "${ACTION_MODE_SINGLE}" or "${ACTION_MODE_MULTI}".` ); }); });