Skip to content

Commit

Permalink
Refactor @mahler/testing sub-module
Browse files Browse the repository at this point in the history
This breaks up index into multiple files to simplify the move to
a DAG representation of a plan.

Change-type: minor
  • Loading branch information
pipex committed Aug 16, 2023
1 parent 427ca3c commit 4361c94
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 100 deletions.
6 changes: 3 additions & 3 deletions lib/planner.spec.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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')
Expand Down
16 changes: 0 additions & 16 deletions lib/testing.spec.ts

This file was deleted.

14 changes: 14 additions & 0 deletions lib/testing/builder.spec.ts
Original file line number Diff line number Diff line change
@@ -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',
]);
});
});
34 changes: 34 additions & 0 deletions lib/testing/builder.ts
Original file line number Diff line number Diff line change
@@ -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;
}
68 changes: 3 additions & 65 deletions lib/testing/index.ts
Original file line number Diff line number Diff line change
@@ -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<T>(n: Node<T> | 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<T>(p: Plan<T>): 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';
24 changes: 24 additions & 0 deletions lib/testing/simplify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Node, Plan } from '../planner';

import { SimplePlan } from './types';

function toArray<T>(n: Node<T> | 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<T>(p: Plan<T>): SimplePlan {
if (!p.success) {
throw new Error('Plan not found');
}

return toArray(p.start);
}
7 changes: 7 additions & 0 deletions lib/testing/types.ts
Original file line number Diff line number Diff line change
@@ -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[];
16 changes: 8 additions & 8 deletions tests/composer/planning.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -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'")
Expand All @@ -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'")
Expand Down Expand Up @@ -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(),
);
});
Expand All @@ -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'")
Expand Down Expand Up @@ -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'")
Expand Down Expand Up @@ -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'")
Expand Down Expand Up @@ -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'")
Expand Down
16 changes: 8 additions & 8 deletions tests/orchestrator/planning.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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'")
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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'",
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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'",
Expand Down Expand Up @@ -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'")
Expand Down Expand Up @@ -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'")
Expand Down

0 comments on commit 4361c94

Please sign in to comment.