UNPKG

3.6 kBJavaScriptView Raw
1const {compile, and, or, root, arg0, setter} = require('../../index');
2const {currentValues, funcLibrary, expectTapFunctionToHaveBeenCalled, rand, evalOrLoad} = require('../test-utils');
3
4const _ = require('lodash');
5
6describe('simple todo', () => {
7 function TodosModel() {
8 const todos = root.get('todos');
9 const pendingTodos = todos.filterBy(val => val.get('done').not());
10 const blockedBy = todos.mapValues(val => val.get('blockedBy'));
11 const todosDone = todos.mapValues(val => val.get('done'));
12 const isNotDone = val =>
13 and(
14 val,
15 todos
16 .get(val)
17 .get('done')
18 .not()
19 );
20 const isNotDone2 = val => and(val, todosDone.get(val).not());
21 const isNotDone3 = val => pendingTodos.get(val);
22 const isBlocked = blockedBy.mapValues(isNotDone);
23 const isBlocked2 = blockedBy.mapValues(isNotDone2);
24 const isBlocked3 = blockedBy.mapValues(isNotDone3);
25 const canItemBeWorkedOn = val =>
26 and(val.get('done').not(), or(val.get('blockedBy').not(), todosDone.get(val.get('blockedBy'))));
27 const canBeWorkedOn = todos.mapValues(canItemBeWorkedOn);
28
29 const shownTodo = or(and(root.get('showCompleted'), canBeWorkedOn), pendingTodos);
30
31 const currentTask = root.get('currentTask');
32 const currentTaskTodo = todos.get(currentTask);
33 const statusOfCurrentTask = or(
34 and(currentTaskTodo.get('done'), 'done'),
35 and(isBlocked.get(currentTask), 'blocked'),
36 'not done'
37 );
38
39 const blockedGrouped = pendingTodos.mapValues((val, key) =>
40 todos.filterBy((val, key, context) => val.get('blockedBy').eq(context), key) //eslint-disable-line no-shadow
41 );
42
43 return {
44 isBlocked,
45 isBlocked2,
46 isBlocked3,
47 blockedBy,
48 canBeWorkedOn,
49 shownTodo,
50 pendingTodos,
51 blockedGrouped,
52 setTodo: setter('todos', arg0),
53 setShowCompleted: setter('showCompleted'),
54 setCurrentTask: setter('currentTask')
55 };
56 }
57 const countItems = 20;
58
59 function randomTodoItem(idx) {
60 return {
61 text: `todo_${idx}`,
62 done: rand.range(2) === 0,
63 blockedBy: rand.range(4) === 2 ? `${(idx + rand.range(countItems - 1)) % countItems}` : false
64 };
65 }
66
67 function generateTestTodoItems(count) {
68 const res = {};
69 for (let idx = 0; idx < count; idx++) {
70 res[`${idx}`] = randomTodoItem(idx);
71 }
72 return res;
73 }
74
75 it('compare naive and optimized', () => {
76 const naiveFunc = evalOrLoad(compile(TodosModel(), true));
77 const optFunc = evalOrLoad(compile(TodosModel()));
78 const initialState = {
79 todos: generateTestTodoItems(countItems),
80 currentTask: '1',
81 showCompleted: false
82 };
83 const naive = naiveFunc(initialState);
84 const opt = optFunc(initialState);
85 expect(currentValues(naive)).toEqual(currentValues(opt));
86 const actionTypes = [
87 () => {
88 const idx = rand.range(countItems);
89 const todoItem = randomTodoItem(idx);
90 return inst => {
91 inst.setTodo(`${idx}`, todoItem);
92 };
93 },
94 () => {
95 const current = rand.range(countItems);
96 return inst => {
97 inst.setCurrentTask(current);
98 };
99 },
100 () => {
101 const show = rand.range(2) === 1;
102 return inst => {
103 inst.setShowCompleted(show);
104 };
105 }
106 ];
107 new Array(countItems * 10).fill().forEach((__, idx) => {
108 const action = actionTypes[rand.range(actionTypes.length)]();
109 action(naive);
110 action(opt);
111 expect(currentValues(naive)).toEqual(currentValues(opt));
112 });
113 });
114});