diff --git a/lib/planner.spec.ts b/lib/planner.spec.ts index cb2ba2a..726a99c 100644 --- a/lib/planner.spec.ts +++ b/lib/planner.spec.ts @@ -1,7 +1,7 @@ import { expect, console } from '~/test-utils'; import { Planner } from './planner'; import { Task } from './task'; -import { plan, serialize } from './testing'; +import { plan, simplified } from './testing'; describe('Planner', () => { describe('plan', () => { @@ -120,7 +120,7 @@ describe('Planner', () => { }, { blocks: { a: 'b', b: 'c', c: 'table' } }, ); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action('take block c') .action('put c on table') @@ -318,7 +318,7 @@ describe('Planner', () => { { blocks: { a: 'b', b: 'c', c: 'table' } }, ); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action('unstack block c') .action('put down block c') diff --git a/lib/testing.spec.ts b/lib/testing.spec.ts deleted file mode 100644 index 0b0098f..0000000 --- a/lib/testing.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { expect } from '~/test-utils'; -import { plan } from './testing'; - -describe('Testing', () => { - describe('builder', () => { - it('builds a plan representation', () => { - expect(plan().end()).to.deep.equal([]); - expect(plan().action('a').end()).to.deep.equal(['a']); - expect(plan().action('a').action('b').action('c').end()).to.deep.equal([ - 'a', - 'b', - 'c', - ]); - }); - }); -}); diff --git a/lib/testing/builder.spec.ts b/lib/testing/builder.spec.ts new file mode 100644 index 0000000..9ede73e --- /dev/null +++ b/lib/testing/builder.spec.ts @@ -0,0 +1,14 @@ +import { expect } from '~/test-utils'; +import { plan } from './builder'; + +describe('testing/builder', () => { + it('builds a plan representation', () => { + expect(plan().end()).to.deep.equal([]); + expect(plan().action('a').end()).to.deep.equal(['a']); + expect(plan().action('a').action('b').action('c').end()).to.deep.equal([ + 'a', + 'b', + 'c', + ]); + }); +}); diff --git a/lib/testing/builder.ts b/lib/testing/builder.ts new file mode 100644 index 0000000..55277c9 --- /dev/null +++ b/lib/testing/builder.ts @@ -0,0 +1,34 @@ +import { SimplePlan } from './types'; + +export interface Builder { + /** + * Adds a next node to the plan + */ + action(description: string): Builder; + + /** + * Builds the test plan + */ + end(): SimplePlan; +} + +/** + * Start building a plan + */ +export function plan(): Builder { + const repr: SimplePlan = []; + + const builder = { + action(description: string) { + repr.push(description); + + return builder; + }, + + end() { + return repr; + }, + }; + + return builder; +} diff --git a/lib/testing/index.ts b/lib/testing/index.ts index adecd87..516993b 100644 --- a/lib/testing/index.ts +++ b/lib/testing/index.ts @@ -1,66 +1,4 @@ -import { Node, Plan } from '../planner'; - export * from './mermaid'; - -/** - * A "serialized" plan. - * - * It's not really serialized as plan cannot be reconstructed - * from the serialization. But is really an object representation - * of a plan that's easier to print and compare. - */ -export type Serialized = string[]; - -export interface Builder { - /** - * Adds a next node to the plan - */ - action(description: string): Builder; - - /** - * Builds the test plan - */ - end(): Serialized; -} - -function toArray(n: Node | null): Serialized { - if (n == null) { - return []; - } - - return [n.action.description, ...toArray(n.next)]; -} - -/** - * Return a serialized version of the plan for comparison - * - * The function will throw if the plan is not successful - */ -export function serialize(p: Plan): Serialized { - if (!p.success) { - throw new Error('Plan not found'); - } - - return toArray(p.start); -} - -/** - * Start building a plan - */ -export function plan(): Builder { - const repr: Serialized = []; - - const builder = { - action(description: string) { - repr.push(description); - - return builder; - }, - - end() { - return repr; - }, - }; - - return builder; -} +export * from './types'; +export * from './builder'; +export * from './simplify'; diff --git a/lib/testing/simplify.ts b/lib/testing/simplify.ts new file mode 100644 index 0000000..bd78b77 --- /dev/null +++ b/lib/testing/simplify.ts @@ -0,0 +1,24 @@ +import { Node, Plan } from '../planner'; + +import { SimplePlan } from './types'; + +function toArray(n: Node | null): SimplePlan { + if (n == null) { + return []; + } + + return [n.action.description, ...toArray(n.next)]; +} + +/** + * Return a serialized version of the plan for comparison + * + * The function will throw if the plan is not successful + */ +export function simplified(p: Plan): SimplePlan { + if (!p.success) { + throw new Error('Plan not found'); + } + + return toArray(p.start); +} diff --git a/lib/testing/types.ts b/lib/testing/types.ts new file mode 100644 index 0000000..c5436a0 --- /dev/null +++ b/lib/testing/types.ts @@ -0,0 +1,7 @@ +/** + * A "simplified" plan. + * + * It is an object representation + * of a plan that's easier to print and compare. + */ +export type SimplePlan = string[]; diff --git a/tests/composer/planning.spec.ts b/tests/composer/planning.spec.ts index 7182957..b265eda 100644 --- a/tests/composer/planning.spec.ts +++ b/tests/composer/planning.spec.ts @@ -2,7 +2,7 @@ import { expect } from '~/test-utils'; import { planner } from './planner'; import { ServiceStatus } from './state'; -import { plan, serialize } from 'mahler/testing'; +import { plan, simplified } from 'mahler/testing'; describe('composer/planning', () => { it('pulls the service image if it does not exist yet', () => { @@ -22,7 +22,7 @@ describe('composer/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("pull image 'alpine:latest' for service 'main'") .action("installing container for service 'main'") @@ -48,7 +48,7 @@ describe('composer/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("installing container for service 'main'") .action("starting container for service 'main'") @@ -78,7 +78,7 @@ describe('composer/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan().action("stopping container for service 'main'").end(), ); }); @@ -101,7 +101,7 @@ describe('composer/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("pull image 'alpine:latest' for service 'main'") .action("installing container for service 'main'") @@ -134,7 +134,7 @@ describe('composer/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("stopping container for service 'main'") .action("removing container for service 'main'") @@ -168,7 +168,7 @@ describe('composer/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("removing container for service 'main'") .action("pull image 'alpine:3.14' for service 'main'") @@ -202,7 +202,7 @@ it('knows to recreate service if config has changed', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("stopping container for service 'main'") .action("removing container for service 'main'") diff --git a/tests/orchestrator/planning.spec.ts b/tests/orchestrator/planning.spec.ts index f7a214b..6a2d49b 100644 --- a/tests/orchestrator/planning.spec.ts +++ b/tests/orchestrator/planning.spec.ts @@ -3,7 +3,7 @@ import { expect } from '~/test-utils'; import { ServiceStatus } from './state'; import { planner } from './planner'; import { DELETED } from 'mahler'; -import { plan, serialize } from 'mahler/testing'; +import { plan, simplified } from 'mahler/testing'; describe('orchestrator/planning', () => { it('updates the app/release state if it has not been set', () => { @@ -34,7 +34,7 @@ describe('orchestrator/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("initialize '/apps/a0'") .action("initialize release 'r0' for app 'a0'") @@ -85,7 +85,7 @@ describe('orchestrator/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("pull image 'alpine:latest' for service 'main' of app 'a0'") .action( @@ -140,7 +140,7 @@ describe('orchestrator/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action( "start container for service 'main' of app 'a0' and release 'r0'", @@ -190,7 +190,7 @@ describe('orchestrator/planning', () => { images: [{ name: 'a0_main:r0' }], }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("pull image 'alpine:latest' for service 'main' of app 'a0'") .action( @@ -253,7 +253,7 @@ describe('orchestrator/planning', () => { images: [{ name: 'a0_main:r0' }], }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action( "stop container for service 'main' of app 'a0' and release 'r0'", @@ -321,7 +321,7 @@ describe('orchestrator/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("initialize release 'r1' for app 'a0'") .action("pull image 'alpine:latest' for service 'main' of app 'a0'") @@ -400,7 +400,7 @@ describe('orchestrator/planning', () => { }, }); - expect(serialize(result)).to.deep.equal( + expect(simplified(result)).to.deep.equal( plan() .action("initialize release 'r1' for app 'a0'") .action("pull image 'alpine:latest' for service 'main' of app 'a0'")