@storybook/angular 7.0.0-beta.40 → 7.0.0-beta.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/angular-beta/AbstractRenderer.js +7 -12
- package/dist/client/angular-beta/__testfixtures__/test.module.d.ts +4 -0
- package/dist/client/angular-beta/__testfixtures__/test.module.js +34 -0
- package/dist/client/angular-beta/utils/PropertyExtractor.d.ts +22 -6
- package/dist/client/angular-beta/utils/PropertyExtractor.js +99 -22
- package/dist/client/angular-beta/utils/PropertyExtractor.test.js +95 -13
- package/jest.config.js +19 -0
- package/package.json +15 -15
- package/template/stories/core/moduleMetadata/with-noop-browser-animations.stories.ts +27 -0
|
@@ -27,12 +27,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
27
27
|
exports.AbstractRenderer = void 0;
|
|
28
28
|
const core_1 = require("@angular/core");
|
|
29
29
|
const platform_browser_1 = require("@angular/platform-browser");
|
|
30
|
-
const animations_1 = require("@angular/platform-browser/animations");
|
|
31
30
|
const rxjs_1 = require("rxjs");
|
|
32
31
|
const telejson_1 = require("telejson");
|
|
33
32
|
const StorybookModule_1 = require("./StorybookModule");
|
|
34
33
|
const StorybookProvider_1 = require("./StorybookProvider");
|
|
35
34
|
const StorybookWrapperComponent_1 = require("./StorybookWrapperComponent");
|
|
35
|
+
const PropertyExtractor_1 = require("./utils/PropertyExtractor");
|
|
36
36
|
const applicationRefs = new Set();
|
|
37
37
|
class AbstractRenderer {
|
|
38
38
|
/**
|
|
@@ -72,11 +72,6 @@ class AbstractRenderer {
|
|
|
72
72
|
async render({ storyFnAngular, forced, parameters, component, targetDOMNode, }) {
|
|
73
73
|
const targetSelector = this.generateTargetSelectorFromStoryId(targetDOMNode.id);
|
|
74
74
|
const newStoryProps$ = new rxjs_1.BehaviorSubject(storyFnAngular.props);
|
|
75
|
-
const hasAnimationsDefined = !!storyFnAngular.moduleMetadata?.imports?.includes(animations_1.BrowserAnimationsModule);
|
|
76
|
-
if (hasAnimationsDefined && storyFnAngular?.moduleMetadata?.imports) {
|
|
77
|
-
// eslint-disable-next-line no-param-reassign
|
|
78
|
-
storyFnAngular.moduleMetadata.imports = storyFnAngular.moduleMetadata.imports.filter((importedModule) => importedModule !== animations_1.BrowserAnimationsModule);
|
|
79
|
-
}
|
|
80
75
|
if (!this.fullRendererRequired({
|
|
81
76
|
storyFnAngular,
|
|
82
77
|
moduleMetadata: {
|
|
@@ -93,13 +88,13 @@ class AbstractRenderer {
|
|
|
93
88
|
}
|
|
94
89
|
this.storyProps$ = newStoryProps$;
|
|
95
90
|
this.initAngularRootElement(targetDOMNode, targetSelector);
|
|
91
|
+
const providers = [
|
|
92
|
+
// Providers for BrowserAnimations & NoopAnimationsModule
|
|
93
|
+
(0, PropertyExtractor_1.extractSingletons)(storyFnAngular.moduleMetadata),
|
|
94
|
+
(0, StorybookProvider_1.storyPropsProvider)(newStoryProps$),
|
|
95
|
+
];
|
|
96
96
|
const application = (0, StorybookModule_1.getApplication)({ storyFnAngular, component, targetSelector });
|
|
97
|
-
const applicationRef = await (0, platform_browser_1.bootstrapApplication)(application, {
|
|
98
|
-
providers: [
|
|
99
|
-
...(hasAnimationsDefined ? [(0, animations_1.provideAnimations)()] : []),
|
|
100
|
-
(0, StorybookProvider_1.storyPropsProvider)(newStoryProps$),
|
|
101
|
-
],
|
|
102
|
-
});
|
|
97
|
+
const applicationRef = await (0, platform_browser_1.bootstrapApplication)(application, { providers });
|
|
103
98
|
applicationRefs.add(applicationRef);
|
|
104
99
|
await this.afterFullRender();
|
|
105
100
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.WithOfficialModule = exports.WithAnimationsModule = void 0;
|
|
10
|
+
const common_1 = require("@angular/common");
|
|
11
|
+
const http_1 = require("@angular/common/http");
|
|
12
|
+
const core_1 = require("@angular/core");
|
|
13
|
+
const platform_browser_1 = require("@angular/platform-browser");
|
|
14
|
+
const animations_1 = require("@angular/platform-browser/animations");
|
|
15
|
+
let WithAnimationsModule = class WithAnimationsModule {
|
|
16
|
+
};
|
|
17
|
+
WithAnimationsModule = __decorate([
|
|
18
|
+
(0, core_1.NgModule)({
|
|
19
|
+
imports: [
|
|
20
|
+
//
|
|
21
|
+
platform_browser_1.BrowserModule,
|
|
22
|
+
animations_1.BrowserAnimationsModule,
|
|
23
|
+
],
|
|
24
|
+
})
|
|
25
|
+
], WithAnimationsModule);
|
|
26
|
+
exports.WithAnimationsModule = WithAnimationsModule;
|
|
27
|
+
let WithOfficialModule = class WithOfficialModule {
|
|
28
|
+
};
|
|
29
|
+
WithOfficialModule = __decorate([
|
|
30
|
+
(0, core_1.NgModule)({
|
|
31
|
+
imports: [common_1.CommonModule, http_1.HttpClientModule],
|
|
32
|
+
})
|
|
33
|
+
], WithOfficialModule);
|
|
34
|
+
exports.WithOfficialModule = WithOfficialModule;
|
|
@@ -1,13 +1,29 @@
|
|
|
1
|
-
import { Provider } from '@angular/core';
|
|
1
|
+
import { InjectionToken, Provider } from '@angular/core';
|
|
2
2
|
import { NgModuleMetadata } from '../../types';
|
|
3
|
+
export declare const REMOVED_MODULES: InjectionToken<unknown>;
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* Analyze NgModule Metadata
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
+
* - Removes Restricted Imports
|
|
8
|
+
* - Extracts providers from ModuleWithProviders
|
|
9
|
+
* - Flattens imports
|
|
10
|
+
* - Returns a new NgModuleMetadata object
|
|
7
11
|
*
|
|
8
|
-
* metadata.imports are flattened deeply and extracted into a new array
|
|
9
12
|
*
|
|
10
|
-
|
|
13
|
+
*/
|
|
14
|
+
export declare const analyzeMetadata: (metadata: NgModuleMetadata) => {
|
|
15
|
+
imports: any;
|
|
16
|
+
providers: any[];
|
|
17
|
+
singletons: any[];
|
|
18
|
+
declarations: any[];
|
|
19
|
+
entryComponents?: any[];
|
|
20
|
+
schemas?: any[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Extract Imports from NgModule
|
|
24
|
+
*
|
|
25
|
+
* CommonModule is always imported
|
|
26
|
+
* Only standalone components are imported
|
|
11
27
|
*
|
|
12
28
|
*/
|
|
13
29
|
export declare const extractImports: (metadata: NgModuleMetadata) => any[];
|
|
@@ -18,10 +34,10 @@ export declare const extractImports: (metadata: NgModuleMetadata) => any[];
|
|
|
18
34
|
* - metadata.providers
|
|
19
35
|
* - providers from each **ModuleWithProviders** (e.g. forRoot() & forChild() )
|
|
20
36
|
*
|
|
21
|
-
* - Use this in combination with extractImports to get all providers for a specific module
|
|
22
37
|
*
|
|
23
38
|
*/
|
|
24
39
|
export declare const extractProviders: (metadata: NgModuleMetadata) => Provider[];
|
|
40
|
+
export declare const extractSingletons: (metadata: NgModuleMetadata) => Provider[];
|
|
25
41
|
/**
|
|
26
42
|
* Extract declarations from NgModule
|
|
27
43
|
*
|
|
@@ -1,32 +1,109 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.extractDeclarations = exports.extractProviders = exports.extractImports = void 0;
|
|
3
|
+
exports.extractDeclarations = exports.extractSingletons = exports.extractProviders = exports.extractImports = exports.analyzeMetadata = exports.REMOVED_MODULES = void 0;
|
|
4
4
|
const common_1 = require("@angular/common");
|
|
5
|
+
const core_1 = require("@angular/core");
|
|
6
|
+
const platform_browser_1 = require("@angular/platform-browser");
|
|
7
|
+
const animations_1 = require("@angular/platform-browser/animations");
|
|
5
8
|
const NgComponentAnalyzer_1 = require("./NgComponentAnalyzer");
|
|
6
9
|
const NgModulesAnalyzer_1 = require("./NgModulesAnalyzer");
|
|
7
10
|
const uniqueArray = (arr) => {
|
|
8
11
|
return arr.flat(Number.MAX_VALUE).filter((value, index, self) => self.indexOf(value) === index);
|
|
9
12
|
};
|
|
13
|
+
const analyzeRestricted = (ngModule) => {
|
|
14
|
+
/**
|
|
15
|
+
* BrowserModule is restricted,
|
|
16
|
+
* because bootstrapApplication API, which mounts the component to the DOM,
|
|
17
|
+
* automatically imports BrowserModule
|
|
18
|
+
*/
|
|
19
|
+
if (ngModule === platform_browser_1.BrowserModule) {
|
|
20
|
+
return [true];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* BrowserAnimationsModule imports BrowserModule, which is restricted,
|
|
24
|
+
* because bootstrapApplication API, which mounts the component to the DOM,
|
|
25
|
+
* automatically imports BrowserModule
|
|
26
|
+
*/
|
|
27
|
+
if (ngModule === animations_1.BrowserAnimationsModule) {
|
|
28
|
+
return [true, (0, animations_1.provideAnimations)()];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* NoopAnimationsModule imports BrowserModule, which is restricted,
|
|
32
|
+
* because bootstrapApplication API, which mounts the component to the DOM,
|
|
33
|
+
* automatically imports BrowserModule
|
|
34
|
+
*/
|
|
35
|
+
if (ngModule === animations_1.NoopAnimationsModule) {
|
|
36
|
+
return [true, (0, animations_1.provideNoopAnimations)()];
|
|
37
|
+
}
|
|
38
|
+
return [false];
|
|
39
|
+
};
|
|
40
|
+
exports.REMOVED_MODULES = new core_1.InjectionToken('REMOVED_MODULES');
|
|
10
41
|
/**
|
|
11
|
-
*
|
|
42
|
+
* Analyze NgModule Metadata
|
|
12
43
|
*
|
|
13
|
-
*
|
|
44
|
+
* - Removes Restricted Imports
|
|
45
|
+
* - Extracts providers from ModuleWithProviders
|
|
46
|
+
* - Flattens imports
|
|
47
|
+
* - Returns a new NgModuleMetadata object
|
|
14
48
|
*
|
|
15
|
-
* metadata.imports are flattened deeply and extracted into a new array
|
|
16
49
|
*
|
|
17
|
-
|
|
50
|
+
*/
|
|
51
|
+
const analyzeMetadata = (metadata) => {
|
|
52
|
+
const declarations = [...(metadata?.declarations || [])];
|
|
53
|
+
const providers = [...(metadata?.providers || [])];
|
|
54
|
+
const singletons = [];
|
|
55
|
+
const imports = [...(metadata?.imports || [])]
|
|
56
|
+
.reduce((acc, ngModule) => {
|
|
57
|
+
// remove ngModule and use only its providers if it is restricted
|
|
58
|
+
// (e.g. BrowserModule, BrowserAnimationsModule, NoopAnimationsModule, ...etc)
|
|
59
|
+
const [isRestricted, restrictedProviders] = analyzeRestricted(ngModule);
|
|
60
|
+
if (isRestricted) {
|
|
61
|
+
singletons.unshift(restrictedProviders || []);
|
|
62
|
+
return acc;
|
|
63
|
+
}
|
|
64
|
+
// destructure into ngModule & providers if it is a ModuleWithProviders
|
|
65
|
+
if (ngModule?.providers) {
|
|
66
|
+
providers.unshift(ngModule.providers || []);
|
|
67
|
+
// eslint-disable-next-line no-param-reassign
|
|
68
|
+
ngModule = ngModule.ngModule;
|
|
69
|
+
}
|
|
70
|
+
// extract providers, declarations, singletons from ngModule
|
|
71
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
72
|
+
const ngMetadata = ngModule?.__annotations__?.[0];
|
|
73
|
+
if (ngMetadata) {
|
|
74
|
+
const newMetadata = (0, exports.analyzeMetadata)(ngMetadata);
|
|
75
|
+
acc.unshift(...newMetadata.imports);
|
|
76
|
+
providers.unshift(...newMetadata.providers);
|
|
77
|
+
singletons.unshift(...newMetadata.singletons);
|
|
78
|
+
declarations.unshift(...newMetadata.declarations);
|
|
79
|
+
if (ngMetadata.standalone === true) {
|
|
80
|
+
acc.push(ngModule);
|
|
81
|
+
}
|
|
82
|
+
// keeping a copy of the removed module
|
|
83
|
+
providers.push({ provide: exports.REMOVED_MODULES, useValue: ngModule, multi: true });
|
|
84
|
+
return acc;
|
|
85
|
+
}
|
|
86
|
+
// include Angular official modules as-is
|
|
87
|
+
if (ngModule.ɵmod) {
|
|
88
|
+
acc.push(ngModule);
|
|
89
|
+
return acc;
|
|
90
|
+
}
|
|
91
|
+
return acc;
|
|
92
|
+
}, [])
|
|
93
|
+
.flat(Number.MAX_VALUE);
|
|
94
|
+
return { ...metadata, imports, providers, singletons, declarations };
|
|
95
|
+
};
|
|
96
|
+
exports.analyzeMetadata = analyzeMetadata;
|
|
97
|
+
/**
|
|
98
|
+
* Extract Imports from NgModule
|
|
99
|
+
*
|
|
100
|
+
* CommonModule is always imported
|
|
101
|
+
* Only standalone components are imported
|
|
18
102
|
*
|
|
19
103
|
*/
|
|
20
104
|
const extractImports = (metadata) => {
|
|
21
|
-
const imports =
|
|
22
|
-
|
|
23
|
-
const withProviders = modules.filter((moduleDef) => !!moduleDef?.ngModule);
|
|
24
|
-
const withoutProviders = modules.filter((moduleDef) => !withProviders.includes(moduleDef));
|
|
25
|
-
return uniqueArray([
|
|
26
|
-
imports,
|
|
27
|
-
withoutProviders,
|
|
28
|
-
withProviders.map((moduleDef) => moduleDef.ngModule),
|
|
29
|
-
]);
|
|
105
|
+
const { imports } = (0, exports.analyzeMetadata)(metadata);
|
|
106
|
+
return uniqueArray([common_1.CommonModule, imports]);
|
|
30
107
|
};
|
|
31
108
|
exports.extractImports = extractImports;
|
|
32
109
|
/**
|
|
@@ -36,18 +113,18 @@ exports.extractImports = extractImports;
|
|
|
36
113
|
* - metadata.providers
|
|
37
114
|
* - providers from each **ModuleWithProviders** (e.g. forRoot() & forChild() )
|
|
38
115
|
*
|
|
39
|
-
* - Use this in combination with extractImports to get all providers for a specific module
|
|
40
116
|
*
|
|
41
117
|
*/
|
|
42
118
|
const extractProviders = (metadata) => {
|
|
43
|
-
const providers = (
|
|
44
|
-
|
|
45
|
-
.flat(Number.MAX_VALUE)
|
|
46
|
-
.filter((moduleDef) => !!moduleDef?.ngModule)
|
|
47
|
-
.map((moduleDef) => moduleDef.providers || []);
|
|
48
|
-
return uniqueArray([].concat(moduleProviders, providers));
|
|
119
|
+
const { providers } = (0, exports.analyzeMetadata)(metadata);
|
|
120
|
+
return uniqueArray(providers);
|
|
49
121
|
};
|
|
50
122
|
exports.extractProviders = extractProviders;
|
|
123
|
+
const extractSingletons = (metadata) => {
|
|
124
|
+
const { singletons } = (0, exports.analyzeMetadata)(metadata);
|
|
125
|
+
return uniqueArray(singletons);
|
|
126
|
+
};
|
|
127
|
+
exports.extractSingletons = extractSingletons;
|
|
51
128
|
/**
|
|
52
129
|
* Extract declarations from NgModule
|
|
53
130
|
*
|
|
@@ -58,7 +135,7 @@ exports.extractProviders = extractProviders;
|
|
|
58
135
|
*
|
|
59
136
|
*/
|
|
60
137
|
const extractDeclarations = (metadata, storyComponent) => {
|
|
61
|
-
const declarations = metadata
|
|
138
|
+
const { declarations } = (0, exports.analyzeMetadata)(metadata);
|
|
62
139
|
if (storyComponent) {
|
|
63
140
|
const isStandalone = (0, NgComponentAnalyzer_1.isStandaloneComponent)(storyComponent);
|
|
64
141
|
const isDeclared = (0, NgModulesAnalyzer_1.isComponentAlreadyDeclared)(storyComponent, declarations, metadata.imports);
|
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const common_1 = require("@angular/common");
|
|
4
4
|
const core_1 = require("@angular/core");
|
|
5
|
+
const platform_browser_1 = require("@angular/platform-browser");
|
|
6
|
+
const animations_1 = require("@angular/platform-browser/animations");
|
|
7
|
+
const http_1 = require("@angular/common/http");
|
|
5
8
|
const PropertyExtractor_1 = require("./PropertyExtractor");
|
|
9
|
+
const test_module_1 = require("../__testfixtures__/test.module");
|
|
6
10
|
const TEST_TOKEN = new core_1.InjectionToken('testToken');
|
|
7
11
|
const TestTokenProvider = { provide: TEST_TOKEN, useValue: 123 };
|
|
8
12
|
const TestService = (0, core_1.Injectable)()(class {
|
|
@@ -23,43 +27,103 @@ const TestModuleWithImportsAndProviders = (0, core_1.NgModule)({
|
|
|
23
27
|
})(class {
|
|
24
28
|
});
|
|
25
29
|
describe('PropertyExtractor', () => {
|
|
30
|
+
describe('analyzeMetadata', () => {
|
|
31
|
+
it('should remove BrowserModule', () => {
|
|
32
|
+
const metadata = {
|
|
33
|
+
imports: [platform_browser_1.BrowserModule],
|
|
34
|
+
};
|
|
35
|
+
const { imports, providers, singletons } = (0, PropertyExtractor_1.analyzeMetadata)(metadata);
|
|
36
|
+
expect(imports.flat(Number.MAX_VALUE)).toEqual([]);
|
|
37
|
+
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
|
|
38
|
+
expect(singletons.flat(Number.MAX_VALUE)).toEqual([]);
|
|
39
|
+
});
|
|
40
|
+
it('should remove BrowserAnimationsModule and use its providers instead', () => {
|
|
41
|
+
const metadata = {
|
|
42
|
+
imports: [animations_1.BrowserAnimationsModule],
|
|
43
|
+
};
|
|
44
|
+
const { imports, providers, singletons } = (0, PropertyExtractor_1.analyzeMetadata)(metadata);
|
|
45
|
+
expect(imports.flat(Number.MAX_VALUE)).toEqual([]);
|
|
46
|
+
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
|
|
47
|
+
expect(singletons.flat(Number.MAX_VALUE)).toEqual((0, animations_1.provideAnimations)());
|
|
48
|
+
});
|
|
49
|
+
it('should remove NoopAnimationsModule and use its providers instead', () => {
|
|
50
|
+
const metadata = {
|
|
51
|
+
imports: [animations_1.NoopAnimationsModule],
|
|
52
|
+
};
|
|
53
|
+
const { imports, providers, singletons } = (0, PropertyExtractor_1.analyzeMetadata)(metadata);
|
|
54
|
+
expect(imports.flat(Number.MAX_VALUE)).toEqual([]);
|
|
55
|
+
expect(providers.flat(Number.MAX_VALUE)).toEqual([]);
|
|
56
|
+
expect(singletons.flat(Number.MAX_VALUE)).toEqual((0, animations_1.provideNoopAnimations)());
|
|
57
|
+
});
|
|
58
|
+
it('should remove Browser/Animations modules recursively', () => {
|
|
59
|
+
const metadata = {
|
|
60
|
+
imports: [test_module_1.WithAnimationsModule],
|
|
61
|
+
};
|
|
62
|
+
const { imports, providers, singletons } = (0, PropertyExtractor_1.analyzeMetadata)(metadata);
|
|
63
|
+
expect(imports.flat(Number.MAX_VALUE)).toEqual([]);
|
|
64
|
+
expect(providers.flat(Number.MAX_VALUE)).toEqual([
|
|
65
|
+
{ provide: PropertyExtractor_1.REMOVED_MODULES, useValue: test_module_1.WithAnimationsModule, multi: true },
|
|
66
|
+
]);
|
|
67
|
+
expect(singletons.flat(Number.MAX_VALUE)).toEqual((0, animations_1.provideAnimations)());
|
|
68
|
+
});
|
|
69
|
+
it('should not destructure Angular official module', () => {
|
|
70
|
+
const metadata = {
|
|
71
|
+
imports: [test_module_1.WithOfficialModule],
|
|
72
|
+
};
|
|
73
|
+
const { imports, providers, singletons } = (0, PropertyExtractor_1.analyzeMetadata)(metadata);
|
|
74
|
+
expect(imports.flat(Number.MAX_VALUE)).toEqual([common_1.CommonModule, http_1.HttpClientModule]);
|
|
75
|
+
expect(providers.flat(Number.MAX_VALUE)).toEqual([
|
|
76
|
+
{ provide: PropertyExtractor_1.REMOVED_MODULES, useValue: test_module_1.WithOfficialModule, multi: true },
|
|
77
|
+
]);
|
|
78
|
+
expect(singletons.flat(Number.MAX_VALUE)).toEqual([]);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
26
81
|
describe('extractImports', () => {
|
|
27
|
-
it('should return
|
|
82
|
+
it('should return Angular official modules', () => {
|
|
28
83
|
const imports = (0, PropertyExtractor_1.extractImports)({ imports: [TestModuleWithImportsAndProviders] });
|
|
29
|
-
expect(imports).toEqual([common_1.CommonModule
|
|
84
|
+
expect(imports).toEqual([common_1.CommonModule]);
|
|
85
|
+
});
|
|
86
|
+
it('should return standalone components', () => {
|
|
87
|
+
const imports = (0, PropertyExtractor_1.extractImports)({
|
|
88
|
+
imports: [TestModuleWithImportsAndProviders, StandaloneTestComponent],
|
|
89
|
+
});
|
|
90
|
+
expect(imports).toEqual([common_1.CommonModule, StandaloneTestComponent]);
|
|
30
91
|
});
|
|
31
|
-
it('should return
|
|
92
|
+
it('should not return any regular modules (they get destructured)', () => {
|
|
32
93
|
const imports = (0, PropertyExtractor_1.extractImports)({
|
|
33
94
|
imports: [
|
|
34
|
-
|
|
95
|
+
TestModuleWithDeclarations,
|
|
35
96
|
{ ngModule: TestModuleWithImportsAndProviders, providers: [] },
|
|
36
97
|
],
|
|
37
98
|
});
|
|
38
|
-
expect(imports).toEqual([common_1.CommonModule
|
|
99
|
+
expect(imports).toEqual([common_1.CommonModule]);
|
|
39
100
|
});
|
|
40
101
|
});
|
|
41
102
|
describe('extractDeclarations', () => {
|
|
42
|
-
it('should return an array of declarations', () => {
|
|
103
|
+
it('should return an array of declarations that contains `storyComponent`', () => {
|
|
43
104
|
const declarations = (0, PropertyExtractor_1.extractDeclarations)({ declarations: [TestComponent1] }, TestComponent2);
|
|
44
105
|
expect(declarations).toEqual([TestComponent1, TestComponent2]);
|
|
45
106
|
});
|
|
46
|
-
it('should ignore
|
|
47
|
-
// TestComponent1 is declared as part of TestModuleWithDeclarations
|
|
48
|
-
// TestModuleWithDeclarations is imported by TestModuleWithImportsAndProviders
|
|
107
|
+
it('should ignore `storyComponent` if it is already declared', () => {
|
|
49
108
|
const declarations = (0, PropertyExtractor_1.extractDeclarations)({
|
|
50
109
|
imports: [TestModuleWithImportsAndProviders],
|
|
51
110
|
declarations: [TestComponent2, StandaloneTestComponent, TestDirective],
|
|
52
111
|
}, TestComponent1);
|
|
53
|
-
expect(declarations).toEqual([
|
|
112
|
+
expect(declarations).toEqual([
|
|
113
|
+
TestComponent1,
|
|
114
|
+
TestComponent2,
|
|
115
|
+
StandaloneTestComponent,
|
|
116
|
+
TestDirective,
|
|
117
|
+
]);
|
|
54
118
|
});
|
|
55
|
-
it('should ignore standalone
|
|
119
|
+
it('should ignore `storyComponent` if it is standalone', () => {
|
|
56
120
|
const declarations = (0, PropertyExtractor_1.extractDeclarations)({
|
|
57
121
|
imports: [TestModuleWithImportsAndProviders],
|
|
58
122
|
declarations: [TestComponent1, TestComponent2, TestDirective],
|
|
59
123
|
}, StandaloneTestComponent);
|
|
60
124
|
expect(declarations).toEqual([TestComponent1, TestComponent2, TestDirective]);
|
|
61
125
|
});
|
|
62
|
-
it('should ignore
|
|
126
|
+
it('should ignore `storyComponent` if it is not a component/directive/pipe', () => {
|
|
63
127
|
const declarations = (0, PropertyExtractor_1.extractDeclarations)({
|
|
64
128
|
imports: [TestModuleWithImportsAndProviders],
|
|
65
129
|
declarations: [TestComponent1, TestComponent2, StandaloneTestComponent],
|
|
@@ -78,7 +142,12 @@ describe('PropertyExtractor', () => {
|
|
|
78
142
|
const providers = (0, PropertyExtractor_1.extractProviders)({
|
|
79
143
|
imports: [{ ngModule: TestModuleWithImportsAndProviders, providers: [TestService] }],
|
|
80
144
|
});
|
|
81
|
-
expect(providers).toEqual([
|
|
145
|
+
expect(providers).toEqual([
|
|
146
|
+
{ provide: TEST_TOKEN, useValue: 123 },
|
|
147
|
+
{ provide: PropertyExtractor_1.REMOVED_MODULES, useValue: TestModuleWithDeclarations, multi: true },
|
|
148
|
+
TestService,
|
|
149
|
+
{ provide: PropertyExtractor_1.REMOVED_MODULES, useValue: TestModuleWithImportsAndProviders, multi: true },
|
|
150
|
+
]);
|
|
82
151
|
});
|
|
83
152
|
it('should return an array of unique providers', () => {
|
|
84
153
|
const providers = (0, PropertyExtractor_1.extractProviders)({
|
|
@@ -86,12 +155,25 @@ describe('PropertyExtractor', () => {
|
|
|
86
155
|
providers: [TestService, { provide: TEST_TOKEN, useValue: 123 }],
|
|
87
156
|
});
|
|
88
157
|
expect(providers).toEqual([
|
|
158
|
+
{ provide: TEST_TOKEN, useValue: 123 },
|
|
159
|
+
{ provide: PropertyExtractor_1.REMOVED_MODULES, useValue: TestModuleWithDeclarations, multi: true },
|
|
89
160
|
TestService,
|
|
90
161
|
{
|
|
91
162
|
provide: new core_1.InjectionToken('testToken'),
|
|
92
163
|
useValue: 123,
|
|
93
164
|
},
|
|
165
|
+
{
|
|
166
|
+
provide: PropertyExtractor_1.REMOVED_MODULES,
|
|
167
|
+
useValue: TestModuleWithImportsAndProviders,
|
|
168
|
+
multi: true,
|
|
169
|
+
},
|
|
94
170
|
]);
|
|
95
171
|
});
|
|
172
|
+
it('should return an array of singletons extracted', () => {
|
|
173
|
+
const singeltons = (0, PropertyExtractor_1.extractSingletons)({
|
|
174
|
+
imports: [animations_1.BrowserAnimationsModule],
|
|
175
|
+
});
|
|
176
|
+
expect(singeltons).toEqual((0, animations_1.provideAnimations)());
|
|
177
|
+
});
|
|
96
178
|
});
|
|
97
179
|
});
|
package/jest.config.js
CHANGED
|
@@ -9,4 +9,23 @@ module.exports = {
|
|
|
9
9
|
escapeString: true,
|
|
10
10
|
printBasicPrototype: true,
|
|
11
11
|
},
|
|
12
|
+
globals: {
|
|
13
|
+
'ts-jest': {
|
|
14
|
+
tsconfig: '<rootDir>/tsconfig.spec.json',
|
|
15
|
+
stringifyContentPathRegex: '\\.(html|svg)$',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
coverageDirectory: './coverage/testapp',
|
|
19
|
+
transform: {
|
|
20
|
+
'^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
|
|
21
|
+
},
|
|
22
|
+
snapshotSerializers: [
|
|
23
|
+
'jest-preset-angular/build/serializers/no-ng-attributes',
|
|
24
|
+
'jest-preset-angular/build/serializers/ng-snapshot',
|
|
25
|
+
'jest-preset-angular/build/serializers/html-comment',
|
|
26
|
+
],
|
|
27
|
+
testMatch: [
|
|
28
|
+
'<rootDir>/src/**/__tests__/**/*.[jt]s?(x)',
|
|
29
|
+
'<rootDir>/src/**/?(*.)+(spec|test).[jt]s?(x)',
|
|
30
|
+
],
|
|
12
31
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/angular",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
3
|
+
"version": "7.0.0-beta.42",
|
|
4
4
|
"description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook",
|
|
@@ -36,20 +36,20 @@
|
|
|
36
36
|
"prep": "../../../scripts/prepare/tsc.ts"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@storybook/builder-webpack5": "7.0.0-beta.
|
|
40
|
-
"@storybook/cli": "7.0.0-beta.
|
|
41
|
-
"@storybook/client-logger": "7.0.0-beta.
|
|
42
|
-
"@storybook/core-client": "7.0.0-beta.
|
|
43
|
-
"@storybook/core-common": "7.0.0-beta.
|
|
44
|
-
"@storybook/core-events": "7.0.0-beta.
|
|
45
|
-
"@storybook/core-server": "7.0.0-beta.
|
|
46
|
-
"@storybook/core-webpack": "7.0.0-beta.
|
|
47
|
-
"@storybook/docs-tools": "7.0.0-beta.
|
|
39
|
+
"@storybook/builder-webpack5": "7.0.0-beta.42",
|
|
40
|
+
"@storybook/cli": "7.0.0-beta.42",
|
|
41
|
+
"@storybook/client-logger": "7.0.0-beta.42",
|
|
42
|
+
"@storybook/core-client": "7.0.0-beta.42",
|
|
43
|
+
"@storybook/core-common": "7.0.0-beta.42",
|
|
44
|
+
"@storybook/core-events": "7.0.0-beta.42",
|
|
45
|
+
"@storybook/core-server": "7.0.0-beta.42",
|
|
46
|
+
"@storybook/core-webpack": "7.0.0-beta.42",
|
|
47
|
+
"@storybook/docs-tools": "7.0.0-beta.42",
|
|
48
48
|
"@storybook/global": "^5.0.0",
|
|
49
|
-
"@storybook/manager-api": "7.0.0-beta.
|
|
50
|
-
"@storybook/node-logger": "7.0.0-beta.
|
|
51
|
-
"@storybook/preview-api": "7.0.0-beta.
|
|
52
|
-
"@storybook/types": "7.0.0-beta.
|
|
49
|
+
"@storybook/manager-api": "7.0.0-beta.42",
|
|
50
|
+
"@storybook/node-logger": "7.0.0-beta.42",
|
|
51
|
+
"@storybook/preview-api": "7.0.0-beta.42",
|
|
52
|
+
"@storybook/types": "7.0.0-beta.42",
|
|
53
53
|
"@types/node": "^16.0.0",
|
|
54
54
|
"@types/react": "^16.14.34",
|
|
55
55
|
"@types/react-dom": "^16.9.14",
|
|
@@ -123,5 +123,5 @@
|
|
|
123
123
|
"bundler": {
|
|
124
124
|
"tsConfig": "tsconfig.build.json"
|
|
125
125
|
},
|
|
126
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "0b8d11c61742ba9283a6889d0bdac9ac5a8a508f"
|
|
127
127
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Meta, StoryFn } from '@storybook/angular';
|
|
2
|
+
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
|
3
|
+
import { within, userEvent } from '@storybook/testing-library';
|
|
4
|
+
import { expect } from '@storybook/jest';
|
|
5
|
+
import { OpenCloseComponent } from './angular-src/open-close-component/open-close.component';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
component: OpenCloseComponent,
|
|
9
|
+
} as Meta;
|
|
10
|
+
|
|
11
|
+
export const WithNoopBrowserAnimations: StoryFn = () => ({
|
|
12
|
+
template: `<app-open-close></app-open-close>`,
|
|
13
|
+
moduleMetadata: {
|
|
14
|
+
declarations: [OpenCloseComponent],
|
|
15
|
+
imports: [NoopAnimationsModule],
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
WithNoopBrowserAnimations.play = async ({ canvasElement }) => {
|
|
20
|
+
const canvas = within(canvasElement);
|
|
21
|
+
const opened = canvas.getByText('The box is now Open!');
|
|
22
|
+
expect(opened).toBeDefined();
|
|
23
|
+
const submitButton = canvas.getByRole('button');
|
|
24
|
+
await userEvent.click(submitButton);
|
|
25
|
+
const closed = canvas.getByText('The box is now Closed!');
|
|
26
|
+
expect(closed).toBeDefined();
|
|
27
|
+
};
|