Skip to content

Commit 8a2a103

Browse files
committed
add selectTasksWithColor (generates color for the linked tasks)
1 parent b1e245a commit 8a2a103

File tree

8 files changed

+4704
-0
lines changed

8 files changed

+4704
-0
lines changed

babel.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
"env": {
3+
"test": {
4+
"presets": [
5+
["@babel/preset-env", {
6+
"targets": {
7+
"node": "current",
8+
}
9+
}]
10+
]
11+
}
12+
}
13+
}

index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { selectTasksWithColor } from './src/redux/Dispatch/selectors'
2+
3+
export {
4+
selectTasksWithColor
5+
}

jest.config.js

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// For a detailed explanation regarding each configuration property, visit:
2+
// https://jestjs.io/docs/en/configuration.html
3+
4+
module.exports = {
5+
// All imported modules in your tests should be mocked automatically
6+
// automock: false,
7+
8+
// Stop running tests after the first failure
9+
// bail: false,
10+
11+
// Respect "browser" field in package.json when resolving modules
12+
// browser: false,
13+
14+
// The directory where Jest should store its cached dependency information
15+
// cacheDirectory: "/tmp/jest_0",
16+
17+
// Automatically clear mock calls and instances between every test
18+
clearMocks: true,
19+
20+
// Indicates whether the coverage information should be collected while executing the test
21+
// collectCoverage: false,
22+
23+
// An array of glob patterns indicating a set of files for which coverage information should be collected
24+
// collectCoverageFrom: null,
25+
26+
// The directory where Jest should output its coverage files
27+
// coverageDirectory: null,
28+
29+
// An array of regexp pattern strings used to skip coverage collection
30+
// coveragePathIgnorePatterns: [
31+
// "/node_modules/"
32+
// ],
33+
34+
// A list of reporter names that Jest uses when writing coverage reports
35+
// coverageReporters: [
36+
// "json",
37+
// "text",
38+
// "lcov",
39+
// "clover"
40+
// ],
41+
42+
// An object that configures minimum threshold enforcement for coverage results
43+
// coverageThreshold: null,
44+
45+
// Make calling deprecated APIs throw helpful error messages
46+
// errorOnDeprecated: false,
47+
48+
// Force coverage collection from ignored files usin a array of glob patterns
49+
// forceCoverageMatch: [],
50+
51+
// A path to a module which exports an async function that is triggered once before all test suites
52+
// globalSetup: null,
53+
54+
// A path to a module which exports an async function that is triggered once after all test suites
55+
// globalTeardown: null,
56+
57+
// A set of global variables that need to be available in all test environments
58+
// globals: {},
59+
60+
// An array of directory names to be searched recursively up from the requiring module's location
61+
// moduleDirectories: [
62+
// "node_modules"
63+
// ],
64+
65+
// An array of file extensions your modules use
66+
// moduleFileExtensions: [
67+
// "js",
68+
// "json",
69+
// "jsx",
70+
// "node"
71+
// ],
72+
73+
// A map from regular expressions to module names that allow to stub out resources with a single module
74+
// moduleNameMapper: {},
75+
76+
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
77+
// modulePathIgnorePatterns: [],
78+
79+
// Activates notifications for test results
80+
// notify: false,
81+
82+
// An enum that specifies notification mode. Requires { notify: true }
83+
// notifyMode: "always",
84+
85+
// A preset that is used as a base for Jest's configuration
86+
// preset: null,
87+
88+
// Run tests from one or more projects
89+
// projects: null,
90+
91+
// Use this configuration option to add custom reporters to Jest
92+
// reporters: undefined,
93+
94+
// Automatically reset mock state between every test
95+
// resetMocks: false,
96+
97+
// Reset the module registry before running each individual test
98+
// resetModules: false,
99+
100+
// A path to a custom resolver
101+
// resolver: null,
102+
103+
// Automatically restore mock state between every test
104+
// restoreMocks: false,
105+
106+
// The root directory that Jest should scan for tests and modules within
107+
// rootDir: null,
108+
109+
// A list of paths to directories that Jest should use to search for files in
110+
roots: [
111+
"src/"
112+
],
113+
114+
// Allows you to use a custom runner instead of Jest's default test runner
115+
// runner: "jest-runner",
116+
117+
// The paths to modules that run some code to configure or set up the testing environment before each test
118+
// setupFiles: [],
119+
120+
// The path to a module that runs some code to configure or set up the testing framework before each test
121+
// setupTestFrameworkScriptFile: null,
122+
123+
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
124+
// snapshotSerializers: [],
125+
126+
// The test environment that will be used for testing
127+
// testEnvironment: "jest-environment-jsdom",
128+
129+
// Options that will be passed to the testEnvironment
130+
// testEnvironmentOptions: {},
131+
132+
// Adds a location field to test results
133+
// testLocationInResults: false,
134+
135+
// The glob patterns Jest uses to detect test files
136+
// testMatch: [
137+
// "**/__tests__/**/*.js?(x)",
138+
// "**/?(*.)+(spec|test).js?(x)"
139+
// ],
140+
141+
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
142+
testPathIgnorePatterns: [
143+
"/node_modules/",
144+
"/vendor/"
145+
],
146+
147+
// The regexp pattern Jest uses to detect test files
148+
// testRegex: "",
149+
150+
// This option allows the use of a custom results processor
151+
// testResultsProcessor: null,
152+
153+
// This option allows use of a custom test runner
154+
// testRunner: "jasmine2",
155+
156+
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
157+
// testURL: "http://localhost",
158+
159+
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
160+
// timers: "real",
161+
162+
// A map from regular expressions to paths to transformers
163+
// transform: null,
164+
165+
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
166+
// transformIgnorePatterns: [
167+
// "/node_modules/"
168+
// ],
169+
170+
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
171+
// unmockedModulePathPatterns: undefined,
172+
173+
// Indicates whether each individual test should be reported during the run
174+
// verbose: null,
175+
176+
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
177+
// watchPathIgnorePatterns: [],
178+
179+
// Whether to use watchman for file crawling
180+
// watchman: true,
181+
};

package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "coopcycle-frontend-js",
3+
"version": "1.0.1",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "jest --config jest.config.js"
8+
},
9+
"author": "",
10+
"license": "ISC",
11+
"dependencies": {
12+
"lodash": "^4.17.15",
13+
"redux": "^4.0.5",
14+
"reselect": "^4.0.0"
15+
},
16+
"devDependencies": {
17+
"@babel/core": "^7.10.4",
18+
"@babel/preset-env": "^7.10.4",
19+
"babel-jest": "^26.1.0",
20+
"jest": "^26.1.0"
21+
}
22+
}

src/redux/Dispatch/__tests__/utils.js

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import {
2+
groupLinkedTasks,
3+
} from '../utils.js'
4+
5+
describe('groupLinkedTasks', () => {
6+
7+
it('should group when tasks are ordered', () => {
8+
9+
const tasks = [
10+
{
11+
'@id': '/api/tasks/1',
12+
id : 1,
13+
next: '/api/tasks/2',
14+
}, {
15+
'@id': '/api/tasks/2',
16+
id : 2,
17+
previous: '/api/tasks/1',
18+
}, {
19+
'@id': '/api/tasks/3',
20+
id : 3,
21+
}
22+
]
23+
24+
const groups = groupLinkedTasks(tasks)
25+
26+
expect(groups).toEqual({
27+
'/api/tasks/1': [ 1, 2 ],
28+
'/api/tasks/2': [ 1, 2 ],
29+
})
30+
})
31+
32+
it('should group when tasks are not ordered', () => {
33+
34+
const tasks = [
35+
{
36+
'@id': '/api/tasks/2',
37+
id : 2,
38+
previous: '/api/tasks/1',
39+
}, {
40+
'@id': '/api/tasks/1',
41+
id : 1,
42+
next: '/api/tasks/2',
43+
}, {
44+
'@id': '/api/tasks/3',
45+
id : 3,
46+
}
47+
]
48+
49+
const groups = groupLinkedTasks(tasks)
50+
51+
expect(groups).toEqual({
52+
'/api/tasks/1': [ 1, 2 ],
53+
'/api/tasks/2': [ 1, 2 ],
54+
})
55+
})
56+
57+
it('should group when there are more than 2 tasks', () => {
58+
59+
const tasks = [
60+
{
61+
'@id': '/api/tasks/1',
62+
id : 1,
63+
next: '/api/tasks/2',
64+
}, {
65+
'@id': '/api/tasks/2',
66+
id : 2,
67+
previous: '/api/tasks/1',
68+
next: '/api/tasks/3',
69+
}, {
70+
'@id': '/api/tasks/3',
71+
id : 3,
72+
previous: '/api/tasks/2',
73+
}
74+
]
75+
76+
const groups = groupLinkedTasks(tasks)
77+
78+
expect(groups).toEqual({
79+
'/api/tasks/1': [ 1, 2, 3 ],
80+
'/api/tasks/2': [ 1, 2, 3 ],
81+
'/api/tasks/3': [ 1, 2, 3 ],
82+
})
83+
})
84+
85+
it('should group multiple', () => {
86+
87+
const tasks = [
88+
{
89+
'@id': '/api/tasks/1',
90+
id : 1,
91+
next: '/api/tasks/2',
92+
}, {
93+
'@id': '/api/tasks/2',
94+
id : 2,
95+
previous: '/api/tasks/1',
96+
}, {
97+
'@id': '/api/tasks/3',
98+
id : 3,
99+
},{
100+
'@id': '/api/tasks/4',
101+
id : 4,
102+
next: '/api/tasks/5',
103+
}, {
104+
'@id': '/api/tasks/5',
105+
id : 5,
106+
previous: '/api/tasks/4',
107+
}
108+
]
109+
110+
const groups = groupLinkedTasks(tasks)
111+
112+
expect(groups).toEqual({
113+
'/api/tasks/1': [ 1, 2 ],
114+
'/api/tasks/2': [ 1, 2 ],
115+
'/api/tasks/4': [ 4, 5 ],
116+
'/api/tasks/5': [ 4, 5 ],
117+
})
118+
})
119+
120+
})

src/redux/Dispatch/selectors.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createSelector } from 'reselect'
2+
import { mapValues } from 'lodash'
3+
import { integerToColor, groupLinkedTasks } from './utils'
4+
5+
export const selectTasksWithColor = createSelector(
6+
state => state.allTasks,
7+
allTasks =>
8+
mapValues(groupLinkedTasks(allTasks), taskIds => integerToColor(taskIds.reduce((accumulator, value) => accumulator + value)))
9+
)

0 commit comments

Comments
 (0)