-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addon-actions: Fix types and refactor #2438
Merged
Hypnosphi
merged 34 commits into
storybookjs:release/3.3
from
rhalff:fix-types-and-refactor
Dec 14, 2017
Merged
Changes from 12 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
ad89dca
Addon-actions: display enumerable properties from prototype chain
Hypnosphi 84244f3
Merge remote-tracking branch 'origin/action-list-all-enumerable-props…
rhalff 24c0868
refactor code to better support all types
rhalff 611a021
add global dependency
rhalff af94539
add buttons to test each type individually
rhalff 440b333
moved to All types
rhalff 1c3ed2d
separate tests
rhalff a398583
import from global instead of using eslint
rhalff 9bda5ab
do not list non-enumerable properties
rhalff 9a46c6e
Revert "do not list non-enumerable properties"
rhalff 9f577c3
do not list non-enumerable properties & ignore non own functions
rhalff 238367b
fix typos & rename some values
rhalff 4279540
include direct action call in examples
rhalff 6403dd3
Merge branch 'release/3.3' into fix-types-and-refactor
Hypnosphi 84f3343
prefer configure to eval
rhalff 442df6e
update storyshot
rhalff db9e5ad
Merge remote-tracking branch 'origin/fix-types-and-refactor' into fix…
rhalff 8f98583
remove obsolete indexOf check
rhalff 7463bdf
invert property check
rhalff 415c34f
create named function safely
rhalff 11170f2
Merge branch 'release/3.3' into fix-types-and-refactor
danielduan 5b9e213
rename/move class to objectType
rhalff 8e1e167
Merge branch 'fix-types-and-refactor' of github.com:rhalff/storybook …
rhalff 0ce1ad2
Merge branch 'release/3.3' into fix-types-and-refactor
Hypnosphi a35d8e4
add error handling
rhalff d693516
Merge remote-tracking branch 'upstream/release/3.3' into fix-types-an…
rhalff 9d9a728
Merge remote-tracking branch 'origin/fix-types-and-refactor' into fix…
rhalff 1a10635
Update lockfile
rhalff a9022b5
Merge branch 'release/3.3' into fix-types-and-refactor
Hypnosphi 8aba7c8
update storyshots
rhalff 7dab15f
Merge remote-tracking branch 'origin/fix-types-and-refactor' into fix…
rhalff b08bc28
Merge branch 'release/3.3' into fix-types-and-refactor
Hypnosphi d35e696
ignore __mocks__/ folders
rhalff ddb21db
Merge remote-tracking branch 'origin/fix-types-and-refactor' into fix…
rhalff File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { File } from 'global'; | ||
|
||
const date = '2017-12-02T11:13:22.492Z'; | ||
const file = new File([''], 'filename.txt', { | ||
type: 'text/plain', | ||
lastModified: new Date(date), | ||
}); | ||
|
||
const input = { | ||
a: 'A', | ||
b: 1, | ||
c: true, | ||
d: /AA/g, | ||
e: date, | ||
f: file, | ||
}; | ||
input.circular = input; | ||
|
||
const output = { | ||
'$___storybook.className': 'Object', | ||
'$___storybook.isCyclic': true, | ||
a: 'A', | ||
b: 1, | ||
c: true, | ||
circular: { | ||
$ref: '$', | ||
}, | ||
d: { | ||
'$___storybook.regExpKey': '/AA/g', | ||
}, | ||
e: '2017-12-02T11:13:22.492Z', | ||
f: { | ||
'$___storybook.className': 'File', | ||
isClosed: false, | ||
lastModified: 1512213202492, | ||
name: 'filename.txt', | ||
size: 0, | ||
type: 'text/plain', | ||
}, | ||
}; | ||
|
||
export default { | ||
input, | ||
output, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import decycle from '../decycle'; | ||
import example from '../__mocks__/example'; | ||
|
||
describe('Decycle', () => { | ||
it('can handle cyclic object', () => { | ||
expect(decycle(example.input)).toEqual(example.output); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import retrocycle from '../retrocycle'; | ||
import example from '../__mocks__/example'; | ||
|
||
describe('Retrocycle', () => { | ||
it('can restore cyclic object', () => { | ||
const FileMock = function File() { | ||
this.close = function close() {}; | ||
this.isClosed = example.input.f.isClosed; | ||
this.lastModified = example.input.f.lastModified; | ||
this.name = example.input.f.name; | ||
this.size = 0; | ||
this.type = 'text/plain'; | ||
}; | ||
|
||
const file = new FileMock(); | ||
|
||
const result = { | ||
a: example.input.a, | ||
b: example.input.b, | ||
c: example.input.c, | ||
d: example.input.d, | ||
e: example.input.e, | ||
f: file, | ||
}; | ||
|
||
result.circular = result; | ||
|
||
const revived = retrocycle(JSON.stringify(example.output)); | ||
|
||
expect(revived.a).toEqual(example.input.a); | ||
expect(revived.b).toEqual(example.input.b); | ||
expect(revived.c).toEqual(example.input.c); | ||
expect(revived.d).toEqual(example.input.d); | ||
expect(revived.e).toEqual(example.input.e); | ||
expect(revived.f.constructor.name).toEqual('File'); | ||
expect(revived.f.isClosed).toEqual(example.input.f.isClosed); | ||
expect(revived.f.lastModified).toEqual(example.input.f.lastModified); | ||
expect(revived.f.name).toEqual(example.input.f.name); | ||
expect(revived.f.size).toEqual(example.input.f.size); | ||
expect(revived.f.type).toEqual(example.input.f.type); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { getPropertiesList, typeReplacer } from './util'; | ||
|
||
import { CYCLIC_KEY } from './'; | ||
|
||
import { classType } from './types'; | ||
|
||
export default function decycle(object, depth = 10) { | ||
const objects = new WeakMap(); | ||
let isCyclic = false; | ||
|
||
const res = (function derez(value, path, _depth) { | ||
let oldPath; | ||
let obj; | ||
|
||
if (Object(value) === value && _depth > depth) { | ||
const name = value.constructor ? value.constructor.name : typeof value; | ||
|
||
return `[${name}...]`; | ||
} | ||
|
||
const result = typeReplacer(value); | ||
|
||
if (result) { | ||
return result.value; | ||
} | ||
|
||
const type = typeof value; | ||
|
||
if (value instanceof Boolean || value instanceof Number || value instanceof String) { | ||
return value; | ||
} | ||
|
||
if (type === 'object' && value !== null) { | ||
oldPath = objects.get(value); | ||
if (oldPath !== undefined) { | ||
isCyclic = true; | ||
|
||
return { $ref: oldPath }; | ||
} | ||
|
||
objects.set(value, path); | ||
|
||
if (Array.isArray(value)) { | ||
obj = []; | ||
for (let i = 0; i < value.length; i += 1) { | ||
obj[i] = derez(value[i], `${path}[${i}]`, _depth + 1); | ||
} | ||
} else { | ||
obj = classType.serialize(value); | ||
|
||
getPropertiesList(value).forEach(name => { | ||
obj[name] = derez(value[name], `${path}[${JSON.stringify(name)}]`, _depth + 1); | ||
}); | ||
} | ||
|
||
if (_depth === 0 && value instanceof Object && isCyclic) { | ||
obj[CYCLIC_KEY] = true; | ||
} | ||
|
||
return obj; | ||
} | ||
|
||
return value; | ||
})(object, '$', 0); | ||
|
||
return res; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export const CYCLIC_KEY = '$___storybook.isCyclic'; | ||
export decycle from './decycle'; | ||
export retrocycle from './retrocycle'; | ||
export reviver from './reviver'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import reviver from './reviver'; | ||
import { muteProperty } from './util'; | ||
import { CYCLIC_KEY } from './'; | ||
|
||
const pathReg = /^\$(?:\[(?:\d+|"(?:[^\\"\u0000-\u001f]|\\([\\"/bfnrt]|u[0-9a-zA-Z]{4}))*")])*$/; | ||
|
||
export default function retrocycle(json) { | ||
const $ = JSON.parse(json, reviver); | ||
|
||
if (typeof $ !== 'object' || $ === null) { | ||
return $; | ||
} | ||
|
||
(function rez(value) { | ||
if (value && typeof value === 'object') { | ||
if (Array.isArray(value)) { | ||
for (let i = 0; i < value.length; i += 1) { | ||
const item = value[i]; | ||
if (item && typeof item === 'object') { | ||
const path = item.$ref; | ||
if (typeof path === 'string' && pathReg.test(path)) { | ||
value[i] = eval(path); // eslint-disable-line no-eval, no-param-reassign | ||
} else { | ||
rez(item); | ||
} | ||
} | ||
} | ||
} else { | ||
// eslint-disable-next-line no-restricted-syntax, guard-for-in | ||
for (const name in value) { | ||
const item = value[name]; | ||
|
||
if (typeof item === 'object' && item !== null) { | ||
const path = item.$ref; | ||
|
||
if (typeof path === 'string' && pathReg.test(path)) { | ||
value[name] = eval(path); // eslint-disable-line no-eval, no-param-reassign | ||
} else { | ||
rez(item); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
})($); | ||
|
||
muteProperty(CYCLIC_KEY, $); | ||
|
||
return $; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { isObject, typeReviver } from './util'; | ||
|
||
function reviver(key, value) { | ||
if (isObject(value)) { | ||
const result = typeReviver(value); | ||
|
||
if (result) { | ||
return result.value; | ||
} | ||
} | ||
|
||
return value; | ||
} | ||
|
||
export default reviver; |
14 changes: 14 additions & 0 deletions
14
addons/actions/src/lib/types/class/__tests__/createFakeConstructor.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import createFakeConstructor from '../createFakeConstructor'; | ||
|
||
describe('createFakeConstructor', () => { | ||
it('creates fake constructor', () => { | ||
expect( | ||
createFakeConstructor( | ||
{ | ||
name_key: 'A', | ||
}, | ||
'name_key' | ||
).constructor.name | ||
).toEqual('A'); | ||
}); | ||
}); |
26 changes: 26 additions & 0 deletions
26
addons/actions/src/lib/types/class/__tests__/getClassName.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import getClassName from '../getClassName'; | ||
|
||
class A {} | ||
const a = new A(); | ||
function B() {} | ||
const b = new B(); | ||
|
||
describe('getClassName', () => { | ||
/* Transpiled cannot be tested. | ||
it('get name of class',() => { | ||
expect(getClassName(A)).toBe('A') | ||
}); | ||
*/ | ||
|
||
it('get name of class instance', () => { | ||
expect(getClassName(a)).toBe('A'); | ||
}); | ||
|
||
it('get name of function', () => { | ||
expect(getClassName(B)).toBe('B'); | ||
}); | ||
|
||
it('get constructor name', () => { | ||
expect(getClassName(b)).toBe('B'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import classType from '../'; | ||
|
||
describe('Class', () => { | ||
it('Serializes Class', () => { | ||
class C {} | ||
const c = new C(); | ||
|
||
expect(classType.serialize(c)).toEqual({ [classType.KEY]: 'C' }); | ||
}); | ||
|
||
it('Deserializes Class', () => { | ||
const value = { [classType.KEY]: 'C' }; | ||
const c = classType.deserialize(value); | ||
|
||
expect(c.constructor.name).toEqual('C'); | ||
|
||
expect(value).toEqual({}); | ||
}); | ||
}); |
13 changes: 13 additions & 0 deletions
13
addons/actions/src/lib/types/class/createFakeConstructor.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export default function createFakeConstructor(obj, key) { | ||
function FakeConstructor(data) { | ||
Object.assign(this, data); | ||
} | ||
|
||
Object.defineProperty(FakeConstructor, 'name', { | ||
value: obj[key], | ||
}); | ||
|
||
delete obj[key]; // eslint-disable-line no-param-reassign | ||
|
||
return new FakeConstructor(obj); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export default function getClassName(value) { | ||
if (value.toString) { | ||
const stringValue = value.toString(); | ||
|
||
if (stringValue.slice(0, 5) === 'class') { | ||
return stringValue.slice(6, -3); | ||
} | ||
|
||
const type = stringValue.slice(8, -1); | ||
|
||
if (stringValue.slice(1, 7) === 'object' && type !== 'Object') { | ||
return type; | ||
} | ||
|
||
const parts = stringValue.match(/function (\w+).*/); | ||
|
||
if (parts && parts.length === 2) { | ||
return parts[1]; | ||
} | ||
} | ||
|
||
return value.constructor ? value.constructor.name : 'Object'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import createFakeConstructor from './createFakeConstructor'; | ||
import getClassName from './getClassName'; | ||
|
||
const KEY = '$___storybook.className'; | ||
|
||
const classType = { | ||
KEY, | ||
// is: (value) => , // not used | ||
serialize: value => ({ [KEY]: getClassName(value) }), | ||
deserialize: value => createFakeConstructor(value, KEY), | ||
}; | ||
|
||
export default classType; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import dateType from '../'; | ||
|
||
const date = new Date(1512137134873); | ||
const isoString = date.toISOString(); | ||
|
||
describe('Date', () => { | ||
it('Recognizes Date', () => { | ||
expect(dateType.is(date)).toBe(true); | ||
expect(dateType.is(1)).toBe(false); | ||
}); | ||
|
||
it('Serializes Date', () => { | ||
expect(dateType.serialize(date)).toEqual({ [dateType.KEY]: isoString }); | ||
}); | ||
|
||
it('Deserializes Date', () => { | ||
expect(dateType.deserialize({ [dateType.KEY]: isoString })).toEqual(date); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will break in android emulator, see #2324
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding
canConfigureName
check should solve thisThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also be fixed now, I didn't test it on android though.