Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
Average work distribution
<input type="checkbox" name="random">
</label>
<label>
Work on unique stories
<input type="checkbox" name="unique-items" checked>
</label>
<button id="create-scenario">run</button>
</form>
<div id="scenarios">
Expand Down
10 changes: 5 additions & 5 deletions spec/animation.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const PubSub = require('pubsub-js');
const animation = require('../src/animation');

const {Worker, WorkItem} = require('../src/worker');
const {Worker, WorkItem, SimpleSkillStrategy} = require('../src/worker');
const Board = require('../src/board');

const find = selector => document.querySelector(selector);
Expand Down Expand Up @@ -63,7 +63,7 @@ describe('animation', () => {
});

it('a worker picks up an item', () => {
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
let workItem = new WorkItem({dev: 1});
board.addWorkItems(workItem);
jest.advanceTimersByTime(0);
Expand All @@ -78,7 +78,7 @@ describe('animation', () => {
})

it('shows card amount', () => {
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
board.addWorkItems(new WorkItem({dev: 1}));
jest.advanceTimersByTime(0);

Expand Down Expand Up @@ -131,15 +131,15 @@ describe('animation', () => {
});

it('adds new workers', () => {
const worker = new Worker({dev: 0});
const worker = new Worker(new SimpleSkillStrategy({dev: 0}));
jest.runAllTimers();
let $worker = find(`.workers [data-worker-id="${worker.id}"]`);
expect($worker.querySelector('.name').innerHTML).toEqual(`${worker.name()}: `);
expect($worker.querySelector('.stat').innerHTML).toEqual('0%');
});

it('stat update', () => {
const worker = new Worker({dev: 0});
const worker = new Worker(new SimpleSkillStrategy({dev: 0}));
const newStats = {workerId: worker.id, stats: {efficiency: 0.9500111}};
PubSub.publish('worker.stats.updated', newStats);
jest.runAllTimers();
Expand Down
18 changes: 9 additions & 9 deletions spec/board.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {Worker, WorkItem, WorkList} = require('../src/worker');
const {Worker, WorkItem, WorkList, SimpleSkillStrategy} = require('../src/worker');
const Board = require('../src/board');
const PubSub = require('pubsub-js');

Expand All @@ -15,15 +15,15 @@ describe('a worker', () => {

describe('without tasks', () => {
it('doesnt crash', () => {
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
jest.runAllTimers();
expect(board.items()).toEqual([[], [], []]);
});
});

describe('with one task', () => {
beforeEach(() => {
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
workItem = new WorkItem({dev: 1});
board.addWorkItems(workItem);
});
Expand Down Expand Up @@ -66,7 +66,7 @@ describe('a worker', () => {

describe('works on an item added after simulation started', () => {
it('works', () => {
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
let workItem = new WorkItem({dev: 1});
workItem.foo = 'bar';
board.addWorkItems(workItem);
Expand All @@ -78,7 +78,7 @@ describe('a worker', () => {

describe('with two tasks', () => {
beforeEach(() => {
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
workItem1 = new WorkItem({dev: 1});
workItem2 = new WorkItem({dev: 1});
board.addWorkItems(workItem1, workItem2);
Expand Down Expand Up @@ -135,7 +135,7 @@ describe('workers work at their own speed', () => {
beforeEach(() => {
workItem = new WorkItem({dev: 1});
board.addWorkItems(workItem);
board.addWorkers(new Worker({dev: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})));
});
it('starts instantly', () => {
jest.advanceTimersByTime(0);
Expand All @@ -155,7 +155,7 @@ describe('workers work at their own speed', () => {
beforeEach(() => {
workItem = new WorkItem({dev: 1});
board.addWorkItems(workItem);
board.addWorkers(new Worker({dev: 0.5}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 0.5})));
});
it('starts instantly', () => {
jest.advanceTimersByTime(0);
Expand Down Expand Up @@ -183,8 +183,8 @@ describe('a typical workflow', () => {
beforeEach(() => {
board = new Board(['dev', 'qa'])
board.addWorkers(
new Worker({dev: 1}),
new Worker({qa: 1}),
new Worker(new SimpleSkillStrategy({dev: 1})),
new Worker(new SimpleSkillStrategy({qa: 1})),
);
workItem1 = new WorkItem({dev: 1, qa: 2});
workItem2 = new WorkItem({dev: 2, qa: 1});
Expand Down
4 changes: 2 additions & 2 deletions spec/limit-wip.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const PubSub = require('pubsub-js');
const Board = require('../src/board');
const {WorkList, Worker, WorkItem} = require('../src/worker');
const {WorkList, Worker, WorkItem, SimpleSkillStrategy} = require('../src/worker');
const {LimitBoardWip} = require('../src/strategies');

describe('limiting overall wip', () => {
Expand All @@ -17,7 +17,7 @@ describe('limiting overall wip', () => {
beforeEach(() => {
board = new Board(['dev', 'qa']);
new LimitBoardWip().initialize(1);
board.addWorkers(new Worker({dev: 1}), new Worker({qa: 1}));
board.addWorkers(new Worker(new SimpleSkillStrategy({dev: 1})), new Worker(new SimpleSkillStrategy({qa: 1})));

item1 = new WorkItem({dev: 1, qa: 1});
item2 = new WorkItem({dev: 1, qa: 1});
Expand Down
17 changes: 11 additions & 6 deletions spec/parsing.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ describe('parseWorkload', () => {

describe('parseWorkers', () => {
it('parses a single worker with a single skill', () => {
expect(parseWorkers('dev')).toEqual([{skills: ['dev']}]);
expect(parseWorkers('qa')).toEqual([{skills: ['qa']}]);
expect(parseWorkers('dev', {workOnUniqueItems: false})).toEqual([{skills: ['dev'], workOnUniqueItems: false}]);
expect(parseWorkers('qa', {workOnUniqueItems: true})).toEqual([{skills: ['qa'], workOnUniqueItems: true}]);
});

it('parses multiple workers with single skills', () => {
expect(parseWorkers('dev, qa')).toEqual([{skills: ['dev']}, {skills: ['qa']}]);
expect(parseWorkers('dev, qa', {workOnUniqueItems: false})).toEqual([{skills: ['dev'], workOnUniqueItems: false}, {skills: ['qa'], workOnUniqueItems: false}]);
});

it('parses a single worker with multiple skills', () => {
expect(parseWorkers('dev+qa')).toEqual([{skills: ['dev', 'qa']}]);
expect(parseWorkers('dev+qa', {workOnUniqueItems: false})).toEqual([{skills: ['dev', 'qa'], workOnUniqueItems: false}]);
});
})

Expand All @@ -37,12 +37,17 @@ describe('parseInput', () => {
workload: 'dev: 3, qa: 1',
workers: 'dev, qa, qa',
wipLimit: '3',
random: true
random: true,
workOnUniqueItems: true
};

const exampleParsedInput = {
title: 'dev: 3, qa: 1',
workers: [{skills: ['dev']}, {skills: ['qa']}, {skills: ['qa']}],
workers: [
{skills: ['dev'], workOnUniqueItems: true},
{skills: ['qa'], workOnUniqueItems: true},
{skills: ['qa'], workOnUniqueItems: true}
],
wipLimit: "3",
distribution: average,
speed: 20,
Expand Down
9 changes: 6 additions & 3 deletions spec/scenario.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('scenario', () => {
beforeEach(() => {
run({
id: 1,
workers: [{ skills: ['dev'] }],
workers: [{ skills: ['dev'], workOnUniqueItems: false }],
stories: {
amount: 10,
work: {'dev': 1}
Expand All @@ -72,7 +72,10 @@ describe('scenario', () => {
beforeEach(() => {
run({
id: 1,
workers: [{ skills: ['dev'] }, { skills: ['qa'] }],
workers: [
{ skills: ['dev'], workOnUniqueItems: false },
{ skills: ['qa'], workOnUniqueItems: false }
],
stories: {
amount: 10,
work: {'dev': 1, 'qa': 1}
Expand All @@ -93,7 +96,7 @@ describe('scenario', () => {
beforeEach(() => {
run({
id: 1,
workers: [{ skills: ['all'] }],
workers: [{ skills: ['all'], workOnUniqueItems: false }],
stories: {
amount: 10,
work: {'dev': 1, 'qa': 1}
Expand Down
16 changes: 8 additions & 8 deletions spec/worker-stats.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const PubSub = require('pubsub-js');
const {Worker} = require('../src/worker');
const {Worker, SimpleSkillStrategy} = require('../src/worker');
const WorkerStats = require('../src/worker-stats');

describe('worker stats', () => {
Expand All @@ -15,19 +15,19 @@ describe('worker stats', () => {
});

it('when worker is idle', () => {
const worker = new Worker({dev: 1});
const worker = new Worker(new SimpleSkillStrategy({dev: 1}));
publishAt(0, 'worker.idle', worker);
expect(latestStats[worker.id]).toMatchObject({efficiency: 0});
});

it('when worker is working', () => {
const worker = new Worker({dev: 1});
const worker = new Worker(new SimpleSkillStrategy({dev: 1}));
publishAt(0, 'worker.working', worker);
expect(latestStats[worker.id]).toMatchObject({efficiency: 1});
});

it('when worker is working 50%', () => {
const worker = new Worker({dev: 1});
const worker = new Worker(new SimpleSkillStrategy({dev: 1}));
publishAt(0, 'worker.working', worker);
publishAt(1, 'worker.idle', worker);
publishAt(2, 'worker.working', worker);
Expand All @@ -36,7 +36,7 @@ describe('worker stats', () => {
});

it('when worker is working 10%', () => {
const worker = new Worker({dev: 1});
const worker = new Worker(new SimpleSkillStrategy({dev: 1}));
publishAt(0, 'worker.working', worker);
publishAt(1, 'worker.idle', worker);
publishAt(10, 'worker.working', worker);
Expand All @@ -45,7 +45,7 @@ describe('worker stats', () => {
});

it('when worker is working 90%', () => {
const worker = new Worker({dev: 1});
const worker = new Worker(new SimpleSkillStrategy({dev: 1}));
publishAt(0, 'worker.working', worker);
publishAt(9, 'worker.idle', worker);
publishAt(10, 'worker.working', worker);
Expand All @@ -54,8 +54,8 @@ describe('worker stats', () => {
});

it('with 2 workers', () => {
const worker1 = new Worker({dev: 1});
const worker2 = new Worker({dev: 1});
const worker1 = new Worker(new SimpleSkillStrategy({dev: 1}));
const worker2 = new Worker(new SimpleSkillStrategy({dev: 1}));
publishAt(0, 'worker.working', worker1);

expect(latestStats[worker1.id]).toMatchObject({efficiency: 1});
Expand Down
Loading