Skip to content

Commit 5ff00cf

Browse files
committed
unit test (and fix bugs) storage & fallbacks
1 parent 3b56686 commit 5ff00cf

File tree

4 files changed

+379
-12
lines changed

4 files changed

+379
-12
lines changed

Diff for: .circleci/config.yml

+6-2
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@ jobs:
5555
pylint tests/unit tests/integration/devtools tests/integration/renderer tests/integration/dash_assets -d all -e C0410,C0411,C0412,C0413,W0109
5656
cd dash-renderer && npm install --ignore-scripts && npm run lint:test && npm run format:test
5757
- run:
58-
name: 🔎 Unit Tests
58+
name: 🐍 Python Unit Tests
5959
command: |
6060
. venv/bin/activate
6161
PYTHONPATH=~/dash/tests/assets pytest tests/unit
62+
- run:
63+
name: ☕ JS Unit Tests
64+
command: |
65+
cd dash-renderer && npm run test:js
6266
6367
"lint-unit-36":
6468
<<: *lint-unit
@@ -262,4 +266,4 @@ workflows:
262266
- "test-27":
263267
requires:
264268
- build-core-27
265-
- build-misc-27
269+
- build-misc-27

Diff for: dash-renderer/jest.config.js

+181
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: "/var/folders/8m/wrr89jfx5kg5xhp7q2127bcc0000gn/T/jest_dx",
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: "coverage",
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+
"\\.(css|less)$": "identity-obj-proxy"
76+
},
77+
78+
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
79+
// modulePathIgnorePatterns: [],
80+
81+
// Activates notifications for test results
82+
// notify: false,
83+
84+
// An enum that specifies notification mode. Requires { notify: true }
85+
// notifyMode: "always",
86+
87+
// A preset that is used as a base for Jest's configuration
88+
// preset: null,
89+
90+
// Run tests from one or more projects
91+
// projects: null,
92+
93+
// Use this configuration option to add custom reporters to Jest
94+
// reporters: undefined,
95+
96+
// Automatically reset mock state between every test
97+
// resetMocks: false,
98+
99+
// Reset the module registry before running each individual test
100+
// resetModules: false,
101+
102+
// A path to a custom resolver
103+
// resolver: null,
104+
105+
// Automatically restore mock state between every test
106+
// restoreMocks: false,
107+
108+
// The root directory that Jest should scan for tests and modules within
109+
// rootDir: null,
110+
111+
// A list of paths to directories that Jest should use to search for files in
112+
roots: [
113+
"<rootDir>/tests"
114+
],
115+
116+
// Allows you to use a custom runner instead of Jest's default test runner
117+
// runner: "jest-runner",
118+
119+
// The paths to modules that run some code to configure or set up the testing environment before each test
120+
// setupFiles: ['<rootDir>/tests/setupTests.js'],
121+
122+
// The path to a module that runs some code to configure or set up the testing framework before each test
123+
// setupTestFrameworkScriptFile: null,
124+
125+
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
126+
// snapshotSerializers: [],
127+
128+
// The test environment that will be used for testing
129+
testEnvironment: "jsdom",
130+
131+
// Options that will be passed to the testEnvironment
132+
// testEnvironmentOptions: {},
133+
134+
// Adds a location field to test results
135+
// testLocationInResults: false,
136+
137+
// The glob patterns Jest uses to detect test files
138+
testMatch: [
139+
"**/?(*.)+(spec|test).js?(x)"
140+
],
141+
142+
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
143+
// testPathIgnorePatterns: [
144+
// "/node_modules/"
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+
};

Diff for: dash-renderer/src/persistence.js

+11-10
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ import uniqid from 'uniqid';
7070

7171
import Registry from './registry';
7272

73-
const storePrefix = '_dash_persistence.';
74-
const UNDEFINED = 'U';
73+
export const storePrefix = '_dash_persistence.';
7574

7675
function err(e) {
7776
const error = typeof e === 'string' ? new Error(e) : e;
@@ -100,6 +99,10 @@ function keyPrefixMatch(prefix, separator) {
10099
return key => key === prefix || key.substr(0, fullLen) === fullStr;
101100
}
102101

102+
const UNDEFINED = 'U';
103+
const _parse = val => val === UNDEFINED ? void 0 : JSON.parse(val || null);
104+
const _stringify = val => val === void 0 ? UNDEFINED : JSON.stringify(val);
105+
103106
class WebStore {
104107
constructor(backEnd) {
105108
this._name = backEnd;
@@ -113,18 +116,16 @@ class WebStore {
113116
getItem(key) {
114117
// note: _storage.getItem returns null on missing keys
115118
// and JSON.parse(null) returns null as well
116-
const gotVal = this._storage.getItem(storePrefix + key);
117-
return gotVal === UNDEFINED ? void 0 : JSON.parse(gotVal);
119+
return _parse(this._storage.getItem(storePrefix + key));
118120
}
119121

120122
/*
121123
* In addition to the regular key->value to set, setItem takes
122124
* dispatch as a parameter, so it can report OOM to devtools
123125
*/
124126
setItem(key, value, dispatch) {
125-
const setVal = value === void 0 ? UNDEFINED : JSON.stringify(value);
126127
try {
127-
this._storage.setItem(storePrefix + key, setVal);
128+
this._storage.setItem(storePrefix + key, _stringify(value));
128129
} catch (e) {
129130
if (dispatch) {
130131
dispatch(err(e));
@@ -173,11 +174,11 @@ class MemStore {
173174
getItem(key) {
174175
// run this storage through JSON too so we know we get a fresh object
175176
// each retrieval
176-
return JSON.parse(this._data[key] || null);
177+
return _parse(this._data[key]);
177178
}
178179

179180
setItem(key, value) {
180-
this._data[key] = JSON.stringify(value);
181+
this._data[key] = _stringify(value);
181182
}
182183

183184
removeItem(key) {
@@ -208,7 +209,7 @@ function longString() {
208209
return s;
209210
}
210211

211-
const stores = {
212+
export const stores = {
212213
memory: new MemStore(),
213214
// Defer testing & making local/session stores until requested.
214215
// That way if we have errors here they can show up in devtools.
@@ -223,7 +224,7 @@ function tryGetWebStore(backEnd, dispatch) {
223224
const store = new WebStore(backEnd);
224225
const fallbackStore = stores.memory;
225226
const storeTest = longString();
226-
const testKey = 'x.x';
227+
const testKey = storePrefix + 'x.x';
227228
try {
228229
store.setItem(testKey, storeTest);
229230
if (store.getItem(testKey) !== storeTest) {

0 commit comments

Comments
 (0)