@o3r/testing 13.0.0-next.5 → 13.0.0-prerelease.1
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/core/angular/angular-materials/autocomplete-material.js +9 -20
- package/core/angular/angular-materials/autocomplete-material.js.map +1 -1
- package/core/angular/angular-materials/index.js +1 -1
- package/core/angular/angular-materials/select-material.js +42 -91
- package/core/angular/angular-materials/select-material.js.map +1 -1
- package/core/angular/angular-materials/slider-material.js +8 -11
- package/core/angular/angular-materials/slider-material.js.map +1 -1
- package/core/angular/component-fixture.js +68 -148
- package/core/angular/component-fixture.js.map +1 -1
- package/core/angular/element.js +44 -50
- package/core/angular/element.js.map +1 -1
- package/core/angular/elements/checkbox-element.js +12 -16
- package/core/angular/elements/checkbox-element.js.map +1 -1
- package/core/angular/elements/index.js +1 -1
- package/core/angular/elements/radio-element.js +12 -16
- package/core/angular/elements/radio-element.js.map +1 -1
- package/core/angular/elements/select-element.js +28 -49
- package/core/angular/elements/select-element.js.map +1 -1
- package/core/angular/elements/slider-element.js +38 -42
- package/core/angular/elements/slider-element.js.map +1 -1
- package/core/angular/group.js +9 -14
- package/core/angular/group.js.map +1 -1
- package/core/angular/groups/index.js +1 -1
- package/core/angular/groups/radio-group.js +25 -62
- package/core/angular/groups/radio-group.js.map +1 -1
- package/core/angular/index.js +1 -1
- package/core/angular/page-fixture.js +8 -11
- package/core/angular/page-fixture.js.map +1 -1
- package/core/angular-materials/autocomplete-material.js +8 -11
- package/core/angular-materials/autocomplete-material.js.map +1 -1
- package/core/angular-materials/index.js +1 -1
- package/core/angular-materials/select-material.js +12 -15
- package/core/angular-materials/select-material.js.map +1 -1
- package/core/angular-materials/slider-material.js +5 -8
- package/core/angular-materials/slider-material.js.map +1 -1
- package/core/component-fixture.js +28 -33
- package/core/component-fixture.js.map +1 -1
- package/core/element.js +24 -26
- package/core/element.js.map +1 -1
- package/core/elements/checkbox-element.js +12 -16
- package/core/elements/checkbox-element.js.map +1 -1
- package/core/elements/index.js +1 -1
- package/core/elements/radio-element.js +12 -16
- package/core/elements/radio-element.js.map +1 -1
- package/core/elements/select-element.js +10 -13
- package/core/elements/select-element.js.map +1 -1
- package/core/elements/slider-element.js +5 -8
- package/core/elements/slider-element.js.map +1 -1
- package/core/group.js +9 -15
- package/core/group.js.map +1 -1
- package/core/groups/index.js +1 -1
- package/core/groups/radio-group.js +8 -11
- package/core/groups/radio-group.js.map +1 -1
- package/core/helpers.js +11 -16
- package/core/helpers.js.map +1 -1
- package/core/index.js +1 -1
- package/core/page-fixture.js +8 -11
- package/core/page-fixture.js.map +1 -1
- package/core/playwright/angular-materials/autocomplete-material.js +26 -56
- package/core/playwright/angular-materials/autocomplete-material.js.map +1 -1
- package/core/playwright/angular-materials/index.js +1 -1
- package/core/playwright/angular-materials/select-material.js +48 -110
- package/core/playwright/angular-materials/select-material.js.map +1 -1
- package/core/playwright/angular-materials/slider-material.js +7 -10
- package/core/playwright/angular-materials/slider-material.js.map +1 -1
- package/core/playwright/component-fixture.js +88 -173
- package/core/playwright/component-fixture.js.map +1 -1
- package/core/playwright/element.js +38 -90
- package/core/playwright/element.js.map +1 -1
- package/core/playwright/elements/checkbox-element.js +49 -94
- package/core/playwright/elements/checkbox-element.js.map +1 -1
- package/core/playwright/elements/index.js +1 -1
- package/core/playwright/elements/radio-element.js +18 -34
- package/core/playwright/elements/radio-element.js.map +1 -1
- package/core/playwright/elements/select-element.js +14 -21
- package/core/playwright/elements/select-element.js.map +1 -1
- package/core/playwright/elements/slider-element.js +78 -157
- package/core/playwright/elements/slider-element.js.map +1 -1
- package/core/playwright/group.js +9 -14
- package/core/playwright/group.js.map +1 -1
- package/core/playwright/groups/index.js +1 -1
- package/core/playwright/groups/radio-group.js +27 -64
- package/core/playwright/groups/radio-group.js.map +1 -1
- package/core/playwright/index.js +1 -1
- package/core/playwright/page-fixture.js +8 -18
- package/core/playwright/page-fixture.js.map +1 -1
- package/errors/fixture-usage-error.js +5 -10
- package/errors/fixture-usage-error.js.map +1 -1
- package/errors/index.js +1 -1
- package/errors/transpilation-purpose-only.js +5 -10
- package/errors/transpilation-purpose-only.js.map +1 -1
- package/kassette/index.js +1 -1
- package/kassette/update-dates-in-mocks.js +66 -85
- package/kassette/update-dates-in-mocks.js.map +1 -1
- package/localization/index.js +1 -1
- package/localization/localization-mock.js +38 -60
- package/localization/localization-mock.js.map +1 -1
- package/mocks/index.js +1 -1
- package/mocks/mock-component-generator.js +54 -53
- package/mocks/mock-component-generator.js.map +1 -1
- package/package.json +68 -61
- package/public_api.js +1 -1
- package/schematics/add-functions-to-fixture/models.d.ts.map +1 -1
- package/schematics/add-functions-to-fixture/models.js.map +1 -1
- package/schematics/ng-add/index.d.ts.map +1 -1
- package/schematics/ng-add/index.js +7 -7
- package/schematics/ng-add/index.js.map +1 -1
- package/schematics/ng-add/playwright/index.d.ts.map +1 -1
- package/schematics/ng-add/playwright/index.js +3 -4
- package/schematics/ng-add/playwright/index.js.map +1 -1
- package/schematics/ng-add/schema.json +2 -1
- package/schematics/playwright/sanity/schema.json +2 -1
- package/schematics/playwright/scenario/schema.json +2 -1
- package/store/index.js +1 -1
- package/store/testable-select.js +13 -13
- package/store/testable-select.js.map +1 -1
- package/tools/index.js +1 -1
- package/tools/path-replacement/index.js +1 -1
- package/tools/path-replacement/path-replacement.js +24 -20
- package/tools/path-replacement/path-replacement.js.map +1 -1
- package/visual-test/index.js +1 -1
- package/visual-test/utils.js +18 -7
- package/visual-test/utils.js.map +1 -1
- package/visual-test/visual-test.d.ts.map +1 -1
- package/visual-test/visual-test.js +30 -35
- package/visual-test/visual-test.js.map +1 -1
- package/visual-testing-reporter/index.d.ts.map +1 -1
- package/visual-testing-reporter/index.js +37 -40
- package/visual-testing-reporter/index.js.map +1 -1
@@ -1,98 +1,79 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.updateDatesInMocks = updateDatesInMocks;
|
4
|
-
|
5
|
-
var temporal_polyfill_1 = require("temporal-polyfill");
|
4
|
+
const temporal_polyfill_1 = require("temporal-polyfill");
|
6
5
|
/**
|
7
6
|
* Update mock checksum and response body to keep using the same mocks every day with updated dates
|
8
7
|
* @param mock the mock instance provided by the hook method of Kassette
|
9
8
|
* @param inputOptions default options will extract ISO strings and use 'day-offset' mode
|
10
9
|
*/
|
11
|
-
function updateDatesInMocks(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
10
|
+
async function updateDatesInMocks(mock, inputOptions = {}) {
|
11
|
+
const plainDateLength = 'YYYY-MM-DDThh:mm:ss'.length;
|
12
|
+
const options = {
|
13
|
+
mode: 'day-offset',
|
14
|
+
extractor: /\b(\d{4}-\d{2}-\d{2})[^"]*/g,
|
15
|
+
converter: {
|
16
|
+
fromDate: (date) => date.toString().substring(0, plainDateLength),
|
17
|
+
toDate: (input) => {
|
18
|
+
input = input.replace(/\.\d+/, '').replace(/Z/, '+00:00');
|
19
|
+
return input.length > plainDateLength
|
20
|
+
? temporal_polyfill_1.Temporal.ZonedDateTime.from(`${input.replace(/(\.\d+)/, '')}[${input.replace(/^.*(\+\d{2}:\d{2}).*$/, '$1') || '+00:00'}]`)
|
21
|
+
: temporal_polyfill_1.Temporal.PlainDate.from(input);
|
22
|
+
}
|
23
|
+
},
|
24
|
+
...inputOptions
|
25
|
+
};
|
26
|
+
const todayTime = temporal_polyfill_1.Temporal.Now.plainDateISO();
|
27
|
+
// Update request
|
28
|
+
const replaceDatesInInput = (input) => {
|
29
|
+
switch (options.mode) {
|
30
|
+
case 'any': {
|
31
|
+
return input.replace(options.extractor, '<any>');
|
32
|
+
}
|
33
|
+
case 'day-offset': {
|
34
|
+
return input.replace(options.extractor, (match) => `<t+${temporal_polyfill_1.Temporal.PlainDate.from(todayTime).until(options.converter.toDate(match)).toString()}>`);
|
35
|
+
}
|
36
|
+
case 'same-day-of-week': {
|
37
|
+
return input.replace(options.extractor, (match) => `<day ${options.converter.toDate(match).dayOfWeek} next week>`);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
return input;
|
41
|
+
};
|
42
|
+
const checksum = await mock.checksum({
|
43
|
+
headers: false,
|
44
|
+
body: { filter: (body) => replaceDatesInInput(body.toString()) },
|
45
|
+
query: { filter: (params) => Object.fromEntries(Object.entries(params).map(([key, value]) => [key, replaceDatesInInput(value)])) },
|
46
|
+
customData: { updateDatesMode: options.mode }
|
47
|
+
});
|
48
|
+
mock.setLocalPath([mock.localPath, checksum]);
|
49
|
+
// Update response
|
50
|
+
if (/get|post/.test(mock.request.method) && (await mock.hasLocalMock())) {
|
51
|
+
const localPayload = (await mock.readLocalPayload())?.payload;
|
52
|
+
if (localPayload && localPayload.data.creationDateTime) {
|
53
|
+
const referenceTime = temporal_polyfill_1.Temporal.PlainDate.from(localPayload.data.creationDateTime.toISOString().substring(0, 10));
|
54
|
+
const timeOffset = temporal_polyfill_1.Temporal.PlainDate.from(referenceTime).until(todayTime, { smallestUnit: 'days', largestUnit: 'days' });
|
55
|
+
if (timeOffset.days !== 0) {
|
56
|
+
mock.setMode('manual');
|
57
|
+
const replaceDatesInOutput = (output) => {
|
58
|
+
switch (options.mode) {
|
59
|
+
case 'any':
|
60
|
+
case 'day-offset': {
|
61
|
+
return output.replace(options.extractor, (match) => options.converter.fromDate(options.converter.toDate(match).add(timeOffset)));
|
41
62
|
}
|
42
|
-
|
43
|
-
|
44
|
-
return [4 /*yield*/, mock.checksum({
|
45
|
-
headers: false,
|
46
|
-
body: { filter: function (body) { return replaceDatesInInput(body.toString()); } },
|
47
|
-
query: { filter: function (params) { return Object.fromEntries(Object.entries(params).map(function (_a) {
|
48
|
-
var key = _a[0], value = _a[1];
|
49
|
-
return [key, replaceDatesInInput(value)];
|
50
|
-
})); } },
|
51
|
-
customData: { updateDatesMode: options.mode }
|
52
|
-
})];
|
53
|
-
case 1:
|
54
|
-
checksum = _d.sent();
|
55
|
-
mock.setLocalPath([mock.localPath, checksum]);
|
56
|
-
_a = /get|post/.test(mock.request.method);
|
57
|
-
if (!_a) return [3 /*break*/, 3];
|
58
|
-
return [4 /*yield*/, mock.hasLocalMock()];
|
59
|
-
case 2:
|
60
|
-
_a = (_d.sent());
|
61
|
-
_d.label = 3;
|
62
|
-
case 3:
|
63
|
-
if (!_a) return [3 /*break*/, 6];
|
64
|
-
return [4 /*yield*/, mock.readLocalPayload()];
|
65
|
-
case 4:
|
66
|
-
localPayload = (_b = (_d.sent())) === null || _b === void 0 ? void 0 : _b.payload;
|
67
|
-
if (!(localPayload && localPayload.data.creationDateTime)) return [3 /*break*/, 6];
|
68
|
-
referenceTime = temporal_polyfill_1.Temporal.PlainDate.from(localPayload.data.creationDateTime.toISOString().substring(0, 10));
|
69
|
-
timeOffset_1 = temporal_polyfill_1.Temporal.PlainDate.from(referenceTime).until(todayTime, { smallestUnit: 'days', largestUnit: 'days' });
|
70
|
-
if (!(timeOffset_1.days !== 0)) return [3 /*break*/, 6];
|
71
|
-
mock.setMode('manual');
|
72
|
-
replaceDatesInOutput = function (output) {
|
73
|
-
switch (options.mode) {
|
74
|
-
case 'any':
|
75
|
-
case 'day-offset': {
|
76
|
-
return output.replace(options.extractor, function (match) { return options.converter.fromDate(options.converter.toDate(match).add(timeOffset_1)); });
|
77
|
-
}
|
78
|
-
case 'same-day-of-week': {
|
79
|
-
return output.replace(options.extractor, function (match) { return options.converter.fromDate(options.converter.toDate(match).add("P".concat(Math.ceil(timeOffset_1.days / 7), "W"))); });
|
80
|
-
}
|
63
|
+
case 'same-day-of-week': {
|
64
|
+
return output.replace(options.extractor, (match) => options.converter.fromDate(options.converter.toDate(match).add(`P${Math.ceil(timeOffset.days / 7)}W`)));
|
81
65
|
}
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
_d.sent();
|
92
|
-
_d.label = 6;
|
93
|
-
case 6: return [2 /*return*/];
|
66
|
+
}
|
67
|
+
return output;
|
68
|
+
};
|
69
|
+
const wrappedPayload = mock.createPayload({
|
70
|
+
data: localPayload.data,
|
71
|
+
body: replaceDatesInOutput(localPayload.body?.toString() || '')
|
72
|
+
});
|
73
|
+
mock.fillResponseFromPayload(wrappedPayload);
|
74
|
+
await mock.sendResponse();
|
94
75
|
}
|
95
|
-
}
|
96
|
-
}
|
76
|
+
}
|
77
|
+
}
|
97
78
|
}
|
98
79
|
//# sourceMappingURL=update-dates-in-mocks.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"update-dates-in-mocks.js","sourceRoot":"","sources":["../../src/kassette/update-dates-in-mocks.ts"],"names":[],"mappings":";;AA2CA,gDAsEC
|
1
|
+
{"version":3,"file":"update-dates-in-mocks.js","sourceRoot":"","sources":["../../src/kassette/update-dates-in-mocks.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IMock,\n} from '@amadeus-it-group/kassette';\nimport {\n Temporal,\n} from 'temporal-polyfill';\n\n/**\n * Options to be passed to `updateDatesInMocks`\n */\nexport interface UpdateDatesInMocksOptions {\n /**\n * 'any': dates in inputs will be ignored when computing checksum, the dates on the output will be updated to keep the same day offset\n * 'day-offset': dates in inputs will be converted to day offsets, the dates on the output will be updated to keep the same day offset\n * 'same-day-of-week': dates in inputs will be converted to day of week, the dates on the output will be updated to keep the same day of week but increment the week\n */\n mode: 'any' | 'day-offset' | 'same-day-of-week';\n /**\n * RegExp used to extract dates from request and response\n */\n extractor: RegExp;\n /**\n * Functions to be used to convert from Temporal objects to strings, and strings to temporal objects\n */\n converter: {\n /**\n * Converter from Temporal to string\n * @param input\n */\n fromDate: (input: Temporal.ZonedDateTime | Temporal.PlainDate) => string;\n /**\n * Converter from string to Temporal\n * @param input\n */\n toDate: (input: string) => Temporal.ZonedDateTime | Temporal.PlainDate;\n };\n}\n\n/**\n * Update mock checksum and response body to keep using the same mocks every day with updated dates\n * @param mock the mock instance provided by the hook method of Kassette\n * @param inputOptions default options will extract ISO strings and use 'day-offset' mode\n */\nexport async function updateDatesInMocks(mock: IMock, inputOptions: Partial<UpdateDatesInMocksOptions> = {}) {\n const plainDateLength = 'YYYY-MM-DDThh:mm:ss'.length;\n const options = {\n mode: 'day-offset',\n extractor: /\\b(\\d{4}-\\d{2}-\\d{2})[^\"]*/g,\n converter: {\n fromDate: (date) => date.toString().substring(0, plainDateLength),\n toDate: (input) => {\n input = input.replace(/\\.\\d+/, '').replace(/Z/, '+00:00');\n return input.length > plainDateLength\n ? Temporal.ZonedDateTime.from(`${input.replace(/(\\.\\d+)/, '')}[${input.replace(/^.*(\\+\\d{2}:\\d{2}).*$/, '$1') || '+00:00'}]`)\n : Temporal.PlainDate.from(input);\n }\n },\n ...inputOptions\n } as const satisfies UpdateDatesInMocksOptions;\n const todayTime = Temporal.Now.plainDateISO();\n\n // Update request\n const replaceDatesInInput = (input: string): string => {\n switch (options.mode) {\n case 'any': {\n return input.replace(options.extractor, '<any>');\n }\n case 'day-offset': {\n return input.replace(options.extractor, (match) => `<t+${Temporal.PlainDate.from(todayTime).until(options.converter.toDate(match)).toString()}>`);\n }\n case 'same-day-of-week': {\n return input.replace(options.extractor, (match) => `<day ${options.converter.toDate(match).dayOfWeek} next week>`);\n }\n }\n return input;\n };\n const checksum = await mock.checksum({\n headers: false,\n body: { filter: (body) => replaceDatesInInput(body.toString()) },\n query: { filter: (params) => Object.fromEntries(Object.entries(params).map(([key, value]) => [key, replaceDatesInInput(value)])) },\n customData: { updateDatesMode: options.mode }\n });\n mock.setLocalPath([mock.localPath, checksum]);\n\n // Update response\n if (/get|post/.test(mock.request.method) && (await mock.hasLocalMock())) {\n const localPayload = (await mock.readLocalPayload())?.payload;\n if (localPayload && localPayload.data.creationDateTime) {\n const referenceTime = Temporal.PlainDate.from(localPayload.data.creationDateTime.toISOString().substring(0, 10));\n const timeOffset = Temporal.PlainDate.from(referenceTime).until(todayTime, { smallestUnit: 'days', largestUnit: 'days' });\n if (timeOffset.days !== 0) {\n mock.setMode('manual');\n const replaceDatesInOutput = (output: string): string => {\n switch (options.mode) {\n case 'any':\n case 'day-offset': {\n return output.replace(options.extractor, (match) => options.converter.fromDate(options.converter.toDate(match).add(timeOffset)));\n }\n case 'same-day-of-week': {\n return output.replace(options.extractor, (match) => options.converter.fromDate(options.converter.toDate(match).add(`P${Math.ceil(timeOffset.days / 7)}W`)));\n }\n }\n return output;\n };\n const wrappedPayload = mock.createPayload({\n data: localPayload.data,\n body: replaceDatesInOutput(localPayload.body?.toString() || '')\n });\n mock.fillResponseFromPayload(wrappedPayload);\n await mock.sendResponse();\n }\n }\n }\n}\n"]}
|
package/localization/index.js
CHANGED
@@ -1,71 +1,52 @@
|
|
1
1
|
"use strict";
|
2
|
+
var LocalizationDependencyMocks_1;
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
4
|
exports.LocalizationDependencyMocks = exports.O3rTranslatePipeMock = exports.TranslatePipeMock = void 0;
|
4
5
|
exports.mockTranslationModules = mockTranslationModules;
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
const tslib_1 = require("tslib");
|
7
|
+
const core_1 = require("@angular/core");
|
8
|
+
const core_2 = require("@ngx-translate/core");
|
9
|
+
const localization_1 = require("@o3r/localization");
|
10
|
+
const rxjs_1 = require("rxjs");
|
11
|
+
const defaultLocalizationConfiguration = {
|
11
12
|
supportedLocales: ['en'],
|
12
13
|
language: 'en',
|
13
14
|
endPointUrl: '',
|
14
15
|
fallbackLanguage: 'en'
|
15
16
|
};
|
16
|
-
|
17
|
-
|
17
|
+
let TranslatePipeMock = class TranslatePipeMock {
|
18
|
+
transform(...args) {
|
19
|
+
return args && args.map((arg) => JSON.parse(arg)).join(', ');
|
18
20
|
}
|
19
|
-
|
20
|
-
var args = [];
|
21
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
22
|
-
args[_i] = arguments[_i];
|
23
|
-
}
|
24
|
-
return args && args.map(function (arg) { return JSON.parse(arg); }).join(', ');
|
25
|
-
};
|
26
|
-
TranslatePipeMock = tslib_1.__decorate([
|
27
|
-
(0, core_1.Pipe)({ name: 'translate' })
|
28
|
-
], TranslatePipeMock);
|
29
|
-
return TranslatePipeMock;
|
30
|
-
}());
|
21
|
+
};
|
31
22
|
exports.TranslatePipeMock = TranslatePipeMock;
|
32
|
-
|
33
|
-
|
23
|
+
exports.TranslatePipeMock = TranslatePipeMock = tslib_1.__decorate([
|
24
|
+
(0, core_1.Pipe)({ name: 'translate' })
|
25
|
+
], TranslatePipeMock);
|
26
|
+
let O3rTranslatePipeMock = class O3rTranslatePipeMock {
|
27
|
+
transform(...args) {
|
28
|
+
return args && args.map((arg) => JSON.parse(arg)).join(', ');
|
34
29
|
}
|
35
|
-
|
36
|
-
var args = [];
|
37
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
38
|
-
args[_i] = arguments[_i];
|
39
|
-
}
|
40
|
-
return args && args.map(function (arg) { return JSON.parse(arg); }).join(', ');
|
41
|
-
};
|
42
|
-
O3rTranslatePipeMock = tslib_1.__decorate([
|
43
|
-
(0, core_1.Pipe)({ name: 'o3rTranslate' })
|
44
|
-
], O3rTranslatePipeMock);
|
45
|
-
return O3rTranslatePipeMock;
|
46
|
-
}());
|
30
|
+
};
|
47
31
|
exports.O3rTranslatePipeMock = O3rTranslatePipeMock;
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if (pipeWithPrefix === void 0) { pipeWithPrefix = false; }
|
32
|
+
exports.O3rTranslatePipeMock = O3rTranslatePipeMock = tslib_1.__decorate([
|
33
|
+
(0, core_1.Pipe)({ name: 'o3rTranslate' })
|
34
|
+
], O3rTranslatePipeMock);
|
35
|
+
let LocalizationDependencyMocks = LocalizationDependencyMocks_1 = class LocalizationDependencyMocks {
|
36
|
+
static forTest(pipeWithPrefix = false) {
|
54
37
|
return {
|
55
38
|
ngModule: LocalizationDependencyMocks_1,
|
56
39
|
providers: [{ provide: localization_1.O3rLocalizationTranslatePipe, useClass: pipeWithPrefix ? O3rTranslatePipeMock : TranslatePipeMock }]
|
57
40
|
};
|
58
|
-
}
|
59
|
-
|
60
|
-
LocalizationDependencyMocks = LocalizationDependencyMocks_1 = tslib_1.__decorate([
|
61
|
-
(0, core_1.NgModule)({
|
62
|
-
declarations: [TranslatePipeMock, O3rTranslatePipeMock],
|
63
|
-
exports: [TranslatePipeMock, O3rTranslatePipeMock]
|
64
|
-
})
|
65
|
-
], LocalizationDependencyMocks);
|
66
|
-
return LocalizationDependencyMocks;
|
67
|
-
}());
|
41
|
+
}
|
42
|
+
};
|
68
43
|
exports.LocalizationDependencyMocks = LocalizationDependencyMocks;
|
44
|
+
exports.LocalizationDependencyMocks = LocalizationDependencyMocks = LocalizationDependencyMocks_1 = tslib_1.__decorate([
|
45
|
+
(0, core_1.NgModule)({
|
46
|
+
declarations: [TranslatePipeMock, O3rTranslatePipeMock],
|
47
|
+
exports: [TranslatePipeMock, O3rTranslatePipeMock]
|
48
|
+
})
|
49
|
+
], LocalizationDependencyMocks);
|
69
50
|
/**
|
70
51
|
* Function to get the list of modules required to test component using Localization module
|
71
52
|
* @param localizationConfiguration Localization configuration
|
@@ -75,22 +56,19 @@ exports.LocalizationDependencyMocks = LocalizationDependencyMocks;
|
|
75
56
|
* @param pipeWithPrefix Enable pipe with prefix
|
76
57
|
* @returns List of modules to import in the TestBed
|
77
58
|
*/
|
78
|
-
function mockTranslationModules(localizationConfiguration, translations, translationCompilerProvider, mockPipe, pipeWithPrefix) {
|
79
|
-
|
80
|
-
|
81
|
-
if (mockPipe === void 0) { mockPipe = false; }
|
82
|
-
if (pipeWithPrefix === void 0) { pipeWithPrefix = false; }
|
83
|
-
return tslib_1.__spreadArray([
|
84
|
-
localization_1.LocalizationModule.forRoot(function () { return localizationConfiguration; }),
|
59
|
+
function mockTranslationModules(localizationConfiguration = defaultLocalizationConfiguration, translations = {}, translationCompilerProvider, mockPipe = false, pipeWithPrefix = false) {
|
60
|
+
return [
|
61
|
+
localization_1.LocalizationModule.forRoot(() => localizationConfiguration),
|
85
62
|
core_2.TranslateModule.forRoot({
|
86
63
|
loader: {
|
87
64
|
provide: core_2.TranslateLoader,
|
88
65
|
useValue: {
|
89
|
-
getTranslation:
|
66
|
+
getTranslation: (lang) => (0, rxjs_1.of)(translations[lang])
|
90
67
|
}
|
91
68
|
},
|
92
69
|
compiler: translationCompilerProvider
|
93
|
-
})
|
94
|
-
|
70
|
+
}),
|
71
|
+
...(mockPipe ? [LocalizationDependencyMocks.forTest(pipeWithPrefix)] : [])
|
72
|
+
];
|
95
73
|
}
|
96
74
|
//# sourceMappingURL=localization-mock.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"localization-mock.js","sourceRoot":"","sources":["../../src/localization/localization-mock.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"localization-mock.js","sourceRoot":"","sources":["../../src/localization/localization-mock.ts"],"names":[],"mappings":";;;;AAsEA,wDAoBC;;AA1FD,wCAMuB;AACvB,8CAG6B;AAC7B,oDAI2B;AAC3B,+BAEc;AAEd,MAAM,gCAAgC,GAAG;IACvC,gBAAgB,EAAE,CAAC,IAAI,CAAC;IACxB,QAAQ,EAAE,IAAI;IACd,WAAW,EAAE,EAAE;IACf,gBAAgB,EAAE,IAAI;CAC+B,CAAC;AAGjD,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IACrB,SAAS,CAAC,GAAG,IAAW;QAC7B,OAAO,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;CACF,CAAA;AAJY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,WAAI,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;GACf,iBAAiB,CAI7B;AAGM,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACxB,SAAS,CAAC,GAAG,IAAW;QAC7B,OAAO,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;CACF,CAAA;AAJY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,WAAI,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;GAClB,oBAAoB,CAIhC;AAMM,IAAM,2BAA2B,mCAAjC,MAAM,2BAA2B;IAC/B,MAAM,CAAC,OAAO,CAAC,cAAc,GAAG,KAAK;QAC1C,OAAO;YACL,QAAQ,EAAE,6BAA2B;YACrC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,2CAA4B,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;SAC5H,CAAC;IACJ,CAAC;CACF,CAAA;AAPY,kEAA2B;sCAA3B,2BAA2B;IAJvC,IAAA,eAAQ,EAAC;QACR,YAAY,EAAE,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;QACvD,OAAO,EAAE,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;KACnD,CAAC;GACW,2BAA2B,CAOvC;AASD;;;;;;;;GAQG;AACH,SAAgB,sBAAsB,CACpC,4BAAgE,gCAAgC,EAChG,eAAiC,EAAE,EACnC,2BAAsC,EACtC,QAAQ,GAAG,KAAK,EAChB,cAAc,GAAG,KAAK;IAEtB,OAAO;QACL,iCAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,yBAAyB,CAAC;QAC3D,sBAAe,CAAC,OAAO,CAAC;YACtB,MAAM,EAAE;gBACN,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE;oBACR,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAA,SAAE,EAAC,YAAY,CAAC,IAAI,CAAC,CAAC;iBACzD;aACF;YACD,QAAQ,EAAE,2BAA2B;SACtC,CAAC;QACF,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC;AACJ,CAAC","sourcesContent":["import {\n ModuleWithProviders,\n NgModule,\n Pipe,\n PipeTransform,\n Provider,\n} from '@angular/core';\nimport {\n TranslateLoader,\n TranslateModule,\n} from '@ngx-translate/core';\nimport {\n LocalizationConfiguration,\n LocalizationModule,\n O3rLocalizationTranslatePipe,\n} from '@o3r/localization';\nimport {\n of,\n} from 'rxjs';\n\nconst defaultLocalizationConfiguration = {\n supportedLocales: ['en'],\n language: 'en',\n endPointUrl: '',\n fallbackLanguage: 'en'\n} as const satisfies Partial<LocalizationConfiguration>;\n\n@Pipe({ name: 'translate' })\nexport class TranslatePipeMock implements PipeTransform {\n public transform(...args: any[]): string | undefined {\n return args && args.map((arg) => JSON.parse(arg)).join(', ');\n }\n}\n\n@Pipe({ name: 'o3rTranslate' })\nexport class O3rTranslatePipeMock implements PipeTransform {\n public transform(...args: any[]): string | undefined {\n return args && args.map((arg) => JSON.parse(arg)).join(', ');\n }\n}\n\n@NgModule({\n declarations: [TranslatePipeMock, O3rTranslatePipeMock],\n exports: [TranslatePipeMock, O3rTranslatePipeMock]\n})\nexport class LocalizationDependencyMocks {\n public static forTest(pipeWithPrefix = false): ModuleWithProviders<LocalizationDependencyMocks> {\n return {\n ngModule: LocalizationDependencyMocks,\n providers: [{ provide: O3rLocalizationTranslatePipe, useClass: pipeWithPrefix ? O3rTranslatePipeMock : TranslatePipeMock }]\n };\n }\n}\n\n/** Mock to provide to the MockTranslation module */\nexport interface MockTranslations {\n [lang: string]: {\n [key: string]: any;\n };\n}\n\n/**\n * Function to get the list of modules required to test component using Localization module\n * @param localizationConfiguration Localization configuration\n * @param translations Translations to use\n * @param translationCompilerProvider Provider for translations compiler\n * @param mockPipe Enable translation pipe mocking\n * @param pipeWithPrefix Enable pipe with prefix\n * @returns List of modules to import in the TestBed\n */\nexport function mockTranslationModules(\n localizationConfiguration: Partial<LocalizationConfiguration> = defaultLocalizationConfiguration,\n translations: MockTranslations = {},\n translationCompilerProvider?: Provider,\n mockPipe = false,\n pipeWithPrefix = false\n): ModuleWithProviders<LocalizationModule>[] {\n return [\n LocalizationModule.forRoot(() => localizationConfiguration),\n TranslateModule.forRoot({\n loader: {\n provide: TranslateLoader,\n useValue: {\n getTranslation: (lang: string) => of(translations[lang])\n }\n },\n compiler: translationCompilerProvider\n }),\n ...(mockPipe ? [LocalizationDependencyMocks.forTest(pipeWithPrefix)] : [])\n ];\n}\n"]}
|
package/mocks/index.js
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.generateMockComponent = generateMockComponent;
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
var ts = require("typescript");
|
4
|
+
const core_1 = require("@angular/core");
|
5
|
+
const forms_1 = require("@angular/forms");
|
6
|
+
const ts = require("typescript");
|
8
7
|
/**
|
9
8
|
* Determine if the node in an input field
|
10
9
|
* @param node Typescript AST Node
|
@@ -28,18 +27,18 @@ function isOutputNode(node, source) {
|
|
28
27
|
* @param source Typescript source file
|
29
28
|
*/
|
30
29
|
function getIOName(currentNode, decorator, source) {
|
31
|
-
|
30
|
+
const nameInDecorator = decorator.getText(source).match(/@(input|output) *\( *(["'](.*)["'])? *\) */i);
|
32
31
|
if (nameInDecorator && nameInDecorator[3]) {
|
33
32
|
return nameInDecorator[3];
|
34
33
|
}
|
35
34
|
else {
|
36
|
-
|
37
|
-
currentNode.forEachChild(
|
35
|
+
let name;
|
36
|
+
currentNode.forEachChild((node) => {
|
38
37
|
if (ts.isIdentifier(node)) {
|
39
|
-
|
38
|
+
name = node.getText(source);
|
40
39
|
}
|
41
40
|
});
|
42
|
-
return
|
41
|
+
return name;
|
43
42
|
}
|
44
43
|
}
|
45
44
|
/**
|
@@ -48,30 +47,30 @@ function getIOName(currentNode, decorator, source) {
|
|
48
47
|
* @param source Typescript source file
|
49
48
|
*/
|
50
49
|
function parseIO(parentNode, source) {
|
51
|
-
|
52
|
-
|
53
|
-
parentNode.forEachChild(
|
50
|
+
const outputs = [];
|
51
|
+
const inputs = [];
|
52
|
+
parentNode.forEachChild((node) => {
|
54
53
|
if (isInputNode(node, source)) {
|
55
|
-
|
56
|
-
if (
|
57
|
-
inputs.push(
|
54
|
+
const name = getIOName(parentNode, node, source);
|
55
|
+
if (name) {
|
56
|
+
inputs.push(name);
|
58
57
|
}
|
59
58
|
}
|
60
59
|
else if (isOutputNode(node, source)) {
|
61
|
-
|
62
|
-
if (
|
63
|
-
outputs.push(
|
60
|
+
const name = getIOName(parentNode, node, source);
|
61
|
+
if (name) {
|
62
|
+
outputs.push(name);
|
64
63
|
}
|
65
64
|
}
|
66
65
|
else {
|
67
|
-
|
68
|
-
inputs.push
|
69
|
-
outputs.push
|
66
|
+
const childrenResult = parseIO(node, source);
|
67
|
+
inputs.push(...childrenResult.inputs);
|
68
|
+
outputs.push(...childrenResult.outputs);
|
70
69
|
}
|
71
70
|
});
|
72
71
|
return {
|
73
|
-
outputs
|
74
|
-
inputs
|
72
|
+
outputs,
|
73
|
+
inputs
|
75
74
|
};
|
76
75
|
}
|
77
76
|
/**
|
@@ -81,13 +80,11 @@ function parseIO(parentNode, source) {
|
|
81
80
|
* @param isInDecorator true if the recursive execution is in a decorator
|
82
81
|
* @param isInComponentConfig true if the recursive execution is in a component decorator configuration
|
83
82
|
*/
|
84
|
-
function getSelector(parentNode, source, isInDecorator, isInComponentConfig) {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
var ret;
|
90
|
-
parentNode.forEachChild(function (node) {
|
83
|
+
function getSelector(parentNode, source, isInDecorator = false, isInComponentConfig = false) {
|
84
|
+
let foundDecorator = false;
|
85
|
+
let foundSelector = false;
|
86
|
+
let ret;
|
87
|
+
parentNode.forEachChild((node) => {
|
91
88
|
if (isInDecorator && isInComponentConfig && ts.isIdentifier(node) && node.getText(source) === 'selector') {
|
92
89
|
foundSelector = true;
|
93
90
|
}
|
@@ -128,35 +125,39 @@ function getSelector(parentNode, source, isInDecorator, isInComponentConfig) {
|
|
128
125
|
* ```
|
129
126
|
*/
|
130
127
|
function generateMockComponent(componentPath, config) {
|
131
|
-
|
132
|
-
|
128
|
+
const program = ts.createProgram([componentPath], {});
|
129
|
+
const source = program.getSourceFile(componentPath);
|
133
130
|
if (!source) {
|
134
131
|
throw new Error('No Source found');
|
135
132
|
}
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
var _this = this;
|
133
|
+
const { outputs, inputs } = parseIO(source, source);
|
134
|
+
const mock = class {
|
135
|
+
constructor() {
|
140
136
|
Object.keys(outputs)
|
141
|
-
.forEach(
|
137
|
+
.forEach((outputName) => this[outputName] = new core_1.EventEmitter());
|
142
138
|
if (config && config.isControlValueAccessor) {
|
143
|
-
this.writeValue =
|
144
|
-
this.registerOnChange =
|
145
|
-
this.registerOnTouched =
|
139
|
+
this.writeValue = () => { };
|
140
|
+
this.registerOnChange = () => { };
|
141
|
+
this.registerOnTouched = () => { };
|
146
142
|
}
|
147
143
|
}
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
144
|
+
};
|
145
|
+
return (0, core_1.Component)({
|
146
|
+
template: config?.template || '',
|
147
|
+
selector: getSelector(source, source) || '',
|
148
|
+
inputs,
|
149
|
+
outputs,
|
150
|
+
...(config && config.isControlValueAccessor)
|
151
|
+
? {
|
152
|
+
providers: [
|
153
|
+
{
|
154
|
+
provide: forms_1.NG_VALUE_ACCESSOR,
|
155
|
+
useExisting: (0, core_1.forwardRef)(() => mock),
|
156
|
+
multi: true
|
157
|
+
}
|
158
|
+
]
|
159
|
+
}
|
160
|
+
: {}
|
161
|
+
})(mock);
|
161
162
|
}
|
162
163
|
//# sourceMappingURL=mock-component-generator.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mock-component-generator.js","sourceRoot":"","sources":["../../src/mocks/mock-component-generator.ts"],"names":[],"mappings":";;AAmIA,sDAyCC
|
1
|
+
{"version":3,"file":"mock-component-generator.js","sourceRoot":"","sources":["../../src/mocks/mock-component-generator.ts"],"names":[],"mappings":";;AAmIA,sDAyCC;AA5KD,wCAKuB;AACvB,0CAEwB;AACxB,iCAAiC;AAEjC;;;;GAIG;AACH,SAAS,WAAW,CAAC,IAAa,EAAE,MAAqB;IACvD,OAAO,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAa,EAAE,MAAqB;IACxD,OAAO,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC5E,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,WAAoB,EAAE,SAAuB,EAAE,MAAqB;IACrF,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACvG,IAAI,eAAe,IAAI,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,IAAI,IAAwB,CAAC;QAC7B,WAAW,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,OAAO,CAAC,UAAmB,EAAE,MAAqB;IACzD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,UAAU,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACjD,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACjD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAC,UAAmB,EAAE,MAAqB,EAAE,aAAa,GAAG,KAAK,EAAE,mBAAmB,GAAG,KAAK;IACjH,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,GAAuB,CAAC;IAC5B,UAAU,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,EAAE;QAC/B,IAAI,aAAa,IAAI,mBAAmB,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC;YACzG,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;aAAM,IAAI,aAAa,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACnD,CAAC;aAAM,IAAI,aAAa,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,WAAW,EAAE,CAAC;YAC1F,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;aAAM,IAAI,aAAa,IAAI,cAAc,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;YACjF,GAAG,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACrG,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,qBAAqB,CAA8B,aAAqB,EAAE,MAAgE;IACxJ,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG;QAKX;YACE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;iBACjB,OAAO,CAAC,CAAC,UAAU,EAAE,EAAE,CAAE,IAAY,CAAC,UAAU,CAAC,GAAG,IAAI,mBAAY,EAAO,CAAC,CAAC;YAChF,IAAI,MAAM,IAAI,MAAM,CAAC,sBAAsB,EAAE,CAAC;gBAC5C,IAAI,CAAC,UAAU,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;gBAC3B,IAAI,CAAC,gBAAgB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;gBACjC,IAAI,CAAC,iBAAiB,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;KACF,CAAC;IAEF,OAAO,IAAA,gBAAS,EAAC;QACf,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE;QAChC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;QAC3C,MAAM;QACN,OAAO;QACP,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,sBAAsB,CAAC;YAC1C,CAAC,CAAC;gBACA,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,yBAAiB;wBAC1B,WAAW,EAAE,IAAA,iBAAU,EAAC,GAAG,EAAE,CAAC,IAAI,CAAC;wBACnC,KAAK,EAAE,IAAI;qBACZ;iBACF;aACF;YACD,CAAC,CAAC,EAAE;KACP,CAAC,CAAC,IAAI,CAAY,CAAC;AACtB,CAAC","sourcesContent":["import {\n Component,\n EventEmitter,\n forwardRef,\n Type,\n} from '@angular/core';\nimport {\n NG_VALUE_ACCESSOR,\n} from '@angular/forms';\nimport * as ts from 'typescript';\n\n/**\n * Determine if the node in an input field\n * @param node Typescript AST Node\n * @param source Typescript source file\n */\nfunction isInputNode(node: ts.Node, source: ts.SourceFile): node is ts.Decorator {\n return ts.isDecorator(node) && node.getText(source).startsWith('@Input');\n}\n\n/**\n * Determine if the node in an output field\n * @param node Typescript AST Node\n * @param source Typescript source file\n */\nfunction isOutputNode(node: ts.Node, source: ts.SourceFile): node is ts.Decorator {\n return ts.isDecorator(node) && node.getText(source).startsWith('@Output');\n}\n\n/**\n * Get the name of the input / output\n * @param currentNode Typescript AST Node\n * @param decorator Current Input/Output decorator node\n * @param source Typescript source file\n */\nfunction getIOName(currentNode: ts.Node, decorator: ts.Decorator, source: ts.SourceFile): string | undefined {\n const nameInDecorator = decorator.getText(source).match(/@(input|output) *\\( *([\"'](.*)[\"'])? *\\) */i);\n if (nameInDecorator && nameInDecorator[3]) {\n return nameInDecorator[3];\n } else {\n let name: string | undefined;\n currentNode.forEachChild((node) => {\n if (ts.isIdentifier(node)) {\n name = node.getText(source);\n }\n });\n return name;\n }\n}\n\n/**\n * Get the list of Input and Output of a component\n * @param parentNode Typescript AST Node\n * @param source Typescript source file\n */\nfunction parseIO(parentNode: ts.Node, source: ts.SourceFile): { outputs: string[]; inputs: string[] } {\n const outputs: string[] = [];\n const inputs: string[] = [];\n\n parentNode.forEachChild((node) => {\n if (isInputNode(node, source)) {\n const name = getIOName(parentNode, node, source);\n if (name) {\n inputs.push(name);\n }\n } else if (isOutputNode(node, source)) {\n const name = getIOName(parentNode, node, source);\n if (name) {\n outputs.push(name);\n }\n } else {\n const childrenResult = parseIO(node, source);\n inputs.push(...childrenResult.inputs);\n outputs.push(...childrenResult.outputs);\n }\n });\n\n return {\n outputs,\n inputs\n };\n}\n\n/**\n * Get the selector of an angular class\n * @param parentNode Typescript AST Node\n * @param source Typescript source file\n * @param isInDecorator true if the recursive execution is in a decorator\n * @param isInComponentConfig true if the recursive execution is in a component decorator configuration\n */\nfunction getSelector(parentNode: ts.Node, source: ts.SourceFile, isInDecorator = false, isInComponentConfig = false) {\n let foundDecorator = false;\n let foundSelector = false;\n let ret: string | undefined;\n parentNode.forEachChild((node) => {\n if (isInDecorator && isInComponentConfig && ts.isIdentifier(node) && node.getText(source) === 'selector') {\n foundSelector = true;\n } else if (foundSelector && ts.isStringLiteral(node)) {\n ret = node.getText(source).replace(/[\"']/gi, '');\n } else if (isInDecorator && ts.isIdentifier(node) && node.getText(source) === 'Component') {\n foundDecorator = true;\n } else if (isInDecorator && foundDecorator && ts.isObjectLiteralExpression(node)) {\n ret = ret || getSelector(node, source, isInDecorator, true);\n } else {\n ret = ret || getSelector(node, source, isInDecorator || ts.isDecorator(node), isInComponentConfig);\n }\n });\n return ret;\n}\n\n/**\n * Generate a mock class base on a component file\n * @param componentPath Path to the component file to mock\n * @param config Object containing the following configurations:\n * template: should be provided if the template contain `<ng-content></ng-content>`\n * isControlValueAccessor: should be provided if the component extends ControlValueAccessor\n * @param config.template\n * @param config.isControlValueAccessor\n * @example\n * ```typescript\n * // hero.component.ts\n * \\@Component({selector: 'hero'})\n * class HeroComponent {\n * \\@Input() name: string;\n * \\@Output() doSomething: EventEmitter<void>\n * }\n *\n * // mock generation\n * class MockComponent extends generateMockComponent('hero.component.ts') {}\n * ```\n */\nexport function generateMockComponent<T = Record<string, unknown>>(componentPath: string, config?: { template?: string; isControlValueAccessor?: boolean }): Type<T> {\n const program = ts.createProgram([componentPath], {});\n const source = program.getSourceFile(componentPath);\n if (!source) {\n throw new Error('No Source found');\n }\n\n const { outputs, inputs } = parseIO(source, source);\n const mock = class {\n public writeValue: any;\n public registerOnChange: any;\n public registerOnTouched: any;\n\n constructor() {\n Object.keys(outputs)\n .forEach((outputName) => (this as any)[outputName] = new EventEmitter<any>());\n if (config && config.isControlValueAccessor) {\n this.writeValue = () => {};\n this.registerOnChange = () => {};\n this.registerOnTouched = () => {};\n }\n }\n };\n\n return Component({\n template: config?.template || '',\n selector: getSelector(source, source) || '',\n inputs,\n outputs,\n ...(config && config.isControlValueAccessor)\n ? {\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => mock),\n multi: true\n }\n ]\n }\n : {}\n })(mock) as Type<T>;\n}\n"]}
|