Skip to content

Commit d4bdc78

Browse files
authored
Add overwritePolicy for Registry (apache-superset#37)
BREAKING CHANGE: Change Registry constructor API to take object instead of single string name. feat: Add overwritePolicy for Registry so developer can customize whether overwriting is ALLOW, WARN or PROHIBIT.
1 parent 7072c8b commit d4bdc78

File tree

9 files changed

+121
-16
lines changed

9 files changed

+121
-16
lines changed

packages/superset-ui-chart/src/registries/ChartBuildQueryRegistrySingleton.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Registry, makeSingleton } from '@superset-ui/core';
22

33
class ChartBuildQueryRegistry extends Registry {
44
constructor() {
5-
super('ChartBuildQuery');
5+
super({ name: 'ChartBuildQuery' });
66
}
77
}
88

packages/superset-ui-chart/src/registries/ChartComponentRegistrySingleton.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Registry, makeSingleton } from '@superset-ui/core';
22

33
class ChartComponentRegistry extends Registry {
44
constructor() {
5-
super('ChartComponent');
5+
super({ name: 'ChartComponent' });
66
}
77
}
88

packages/superset-ui-chart/src/registries/ChartMetadataRegistrySingleton.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Registry, makeSingleton } from '@superset-ui/core';
22

33
class ChartMetadataRegistry extends Registry {
44
constructor() {
5-
super('ChartMetadata');
5+
super({ name: 'ChartMetadata' });
66
}
77
}
88

packages/superset-ui-chart/src/registries/ChartTransformPropsRegistrySingleton.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Registry, makeSingleton } from '@superset-ui/core';
22

33
class ChartTransformPropsRegistry extends Registry {
44
constructor() {
5-
super('ChartTransformProps');
5+
super({ name: 'ChartTransformProps' });
66
}
77
}
88

packages/superset-ui-core/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
"publishConfig": {
2626
"access": "public"
2727
},
28+
"devDependencies": {
29+
"jest-mock-console": "^0.4.0"
30+
},
2831
"dependencies": {
2932
"lodash": "^4.17.11"
3033
}

packages/superset-ui-core/src/models/Registry.js

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
/* eslint no-console: 0 */
2+
3+
const OverwritePolicy = {
4+
ALLOW: 'ALLOW',
5+
PROHIBIT: 'PROHIBIT',
6+
WARN: 'WARN',
7+
};
8+
19
export default class Registry {
2-
constructor(name = '') {
10+
constructor({ name = '', overwritePolicy = OverwritePolicy.ALLOW } = {}) {
11+
this.overwritePolicy = overwritePolicy;
312
this.name = name;
413
this.items = {};
514
this.promises = {};
@@ -20,6 +29,13 @@ export default class Registry {
2029

2130
registerValue(key, value) {
2231
const item = this.items[key];
32+
if (item && item.value !== value) {
33+
if (this.overwritePolicy === OverwritePolicy.WARN) {
34+
console.warn(`Item with key "${key}" already exists. You are assigning a new value.`);
35+
} else if (this.overwritePolicy === OverwritePolicy.PROHIBIT) {
36+
throw new Error(`Item with key "${key}" already exists. Cannot overwrite.`);
37+
}
38+
}
2339
if (!item || item.value !== value) {
2440
this.items[key] = { value };
2541
delete this.promises[key];
@@ -30,6 +46,13 @@ export default class Registry {
3046

3147
registerLoader(key, loader) {
3248
const item = this.items[key];
49+
if (item && item.loader !== loader) {
50+
if (this.overwritePolicy === OverwritePolicy.WARN) {
51+
console.warn(`Item with key "${key}" already exists. You are assigning a new value.`);
52+
} else if (this.overwritePolicy === OverwritePolicy.PROHIBIT) {
53+
throw new Error(`Item with key "${key}" already exists. Cannot overwrite.`);
54+
}
55+
}
3356
if (!item || item.loader !== loader) {
3457
this.items[key] = { loader };
3558
delete this.promises[key];
@@ -122,3 +145,5 @@ export default class Registry {
122145
return this;
123146
}
124147
}
148+
149+
Registry.OverwritePolicy = OverwritePolicy;

packages/superset-ui-core/src/models/RegistryWithDefaultKey.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import Registry from './Registry';
22

33
export default class RegistryWithDefaultKey extends Registry {
4-
constructor({ name, initialDefaultKey = undefined, setFirstItemAsDefault = false } = {}) {
5-
super(name);
4+
constructor({ initialDefaultKey = undefined, setFirstItemAsDefault = false, ...rest } = {}) {
5+
super(rest);
66
this.initialDefaultKey = initialDefaultKey;
77
this.defaultKey = initialDefaultKey;
88
this.setFirstItemAsDefault = setFirstItemAsDefault;

packages/superset-ui-core/test/models/Registry.test.js

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1+
/* eslint no-console: 0 */
2+
import mockConsole from 'jest-mock-console';
13
import Registry from '../../src/models/Registry';
24

35
describe('Registry', () => {
46
it('exists', () => {
57
expect(Registry !== undefined).toBe(true);
68
});
79

8-
describe('new Registry(name)', () => {
9-
it('can create a new registry when name is not given', () => {
10+
describe('new Registry(config)', () => {
11+
it('can create a new registry when config.name is not given', () => {
1012
const registry = new Registry();
1113
expect(registry).toBeInstanceOf(Registry);
1214
});
13-
it('can create a new registry when name is given', () => {
14-
const registry = new Registry('abc');
15+
it('can create a new registry when config.name is given', () => {
16+
const registry = new Registry({ name: 'abc' });
1517
expect(registry).toBeInstanceOf(Registry);
1618
expect(registry.name).toBe('abc');
1719
});
@@ -265,4 +267,79 @@ describe('Registry', () => {
265267
expect(registry.remove('a')).toBe(registry);
266268
});
267269
});
270+
271+
describe('config.overwritePolicy', () => {
272+
describe('=ALLOW', () => {
273+
describe('.registerValue(key, value)', () => {
274+
it('registers normally', () => {
275+
const restoreConsole = mockConsole();
276+
const registry = new Registry();
277+
registry.registerValue('a', 'testValue');
278+
expect(() => registry.registerValue('a', 'testValue2')).not.toThrow();
279+
expect(registry.get('a')).toEqual('testValue2');
280+
expect(console.warn).not.toHaveBeenCalled();
281+
restoreConsole();
282+
});
283+
});
284+
describe('.registerLoader(key, loader)', () => {
285+
it('registers normally', () => {
286+
const restoreConsole = mockConsole();
287+
const registry = new Registry();
288+
registry.registerLoader('a', () => 'testValue');
289+
expect(() => registry.registerLoader('a', () => 'testValue2')).not.toThrow();
290+
expect(registry.get('a')).toEqual('testValue2');
291+
expect(console.warn).not.toHaveBeenCalled();
292+
restoreConsole();
293+
});
294+
});
295+
});
296+
describe('=WARN', () => {
297+
describe('.registerValue(key, value)', () => {
298+
it('warns when overwrite', () => {
299+
const restoreConsole = mockConsole();
300+
const registry = new Registry({
301+
overwritePolicy: Registry.OverwritePolicy.WARN,
302+
});
303+
registry.registerValue('a', 'testValue');
304+
expect(() => registry.registerValue('a', 'testValue2')).not.toThrow();
305+
expect(registry.get('a')).toEqual('testValue2');
306+
expect(console.warn).toHaveBeenCalled();
307+
restoreConsole();
308+
});
309+
});
310+
describe('.registerLoader(key, loader)', () => {
311+
it('warns when overwrite', () => {
312+
const restoreConsole = mockConsole();
313+
const registry = new Registry({
314+
overwritePolicy: Registry.OverwritePolicy.WARN,
315+
});
316+
registry.registerLoader('a', () => 'testValue');
317+
expect(() => registry.registerLoader('a', () => 'testValue2')).not.toThrow();
318+
expect(registry.get('a')).toEqual('testValue2');
319+
expect(console.warn).toHaveBeenCalled();
320+
restoreConsole();
321+
});
322+
});
323+
});
324+
describe('=PROHIBIT', () => {
325+
describe('.registerValue(key, value)', () => {
326+
it('throws error when overwrite', () => {
327+
const registry = new Registry({
328+
overwritePolicy: Registry.OverwritePolicy.PROHIBIT,
329+
});
330+
registry.registerValue('a', 'testValue');
331+
expect(() => registry.registerValue('a', 'testValue2')).toThrow();
332+
});
333+
});
334+
describe('.registerLoader(key, loader)', () => {
335+
it('warns when overwrite', () => {
336+
const registry = new Registry({
337+
overwritePolicy: Registry.OverwritePolicy.PROHIBIT,
338+
});
339+
registry.registerLoader('a', () => 'testValue');
340+
expect(() => registry.registerLoader('a', () => 'testValue2')).toThrow();
341+
});
342+
});
343+
});
344+
});
268345
});

packages/superset-ui-core/test/models/RegistryWithDefaultKey.test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ describe('RegistryWithDefaultKey', () => {
1212
registry = new RegistryWithDefaultKey();
1313
});
1414

15-
describe('new RegistryWithDefaultKey(options)', () => {
15+
describe('new RegistryWithDefaultKey(config)', () => {
1616
it('returns a class that extends from Registry', () => {
1717
expect(registry).toBeInstanceOf(Registry);
1818
});
@@ -61,7 +61,7 @@ describe('RegistryWithDefaultKey', () => {
6161
});
6262
});
6363

64-
describe('options.defaultKey', () => {
64+
describe('config.defaultKey', () => {
6565
describe('when not set', () => {
6666
it(`After creation, default key is undefined`, () => {
6767
expect(registry.defaultKey).toBeUndefined();
@@ -72,22 +72,22 @@ describe('RegistryWithDefaultKey', () => {
7272
expect(registry.getDefaultKey()).toBeUndefined();
7373
});
7474
});
75-
describe('when options.initialDefaultKey is set', () => {
75+
describe('when config.initialDefaultKey is set', () => {
7676
const registry2 = new RegistryWithDefaultKey({
7777
initialDefaultKey: 'def',
7878
});
7979
it(`After creation, default key is undefined`, () => {
8080
expect(registry2.defaultKey).toEqual('def');
8181
});
82-
it('.clear() reset defaultKey to this options.defaultKey', () => {
82+
it('.clear() reset defaultKey to this config.defaultKey', () => {
8383
registry2.setDefaultKey('abc');
8484
registry2.clear();
8585
expect(registry2.getDefaultKey()).toEqual('def');
8686
});
8787
});
8888
});
8989

90-
describe('options.setFirstItemAsDefault', () => {
90+
describe('config.setFirstItemAsDefault', () => {
9191
describe('when true', () => {
9292
const registry2 = new RegistryWithDefaultKey({ setFirstItemAsDefault: true });
9393
beforeEach(() => {

0 commit comments

Comments
 (0)