artillery-plugin-fake-data 1.23.0 → 1.24.0-a33c503
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/README.md +8 -2
- package/index.ts +156 -0
- package/package.json +7 -5
- package/index.js +0 -59
package/README.md
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# artillery-plugin-fake-data
|
|
2
2
|
|
|
3
|
-
## Easy randomised test data leveraging
|
|
3
|
+
## Easy randomised test data leveraging Faker
|
|
4
4
|
|
|
5
|
-
With this plugin, you can add random test data using [
|
|
5
|
+
With this plugin, you can add random test data using [Faker](https://fakerjs.dev/api/) straight into YAML, giving you a wide range of test data options to choose from. You'll also be able to use the same functions in your `beforeRequest`/`afterResponse` hooks. Check the documentation for more information.
|
|
6
|
+
|
|
7
|
+
Faker functions are exposed with flattened names: `faker.internet.email()` becomes `$internetEmail()`, `faker.person.fullName()` becomes `$personFullName()`, and so on.
|
|
8
|
+
|
|
9
|
+
### Migrating from falso
|
|
10
|
+
|
|
11
|
+
Earlier versions of this plugin used [falso](https://ngneat.github.io/falso/). The most commonly used falso-style names (e.g. `$randEmail`, `$randFullName`, `$randPassword`) still work as deprecated aliases, but will be removed in a future release. Function configuration options now use Faker's option shapes (e.g. `internetPassword: { length: 5 }` instead of `randPassword: { size: 5 }`). See the [plugin documentation](https://www.artillery.io/docs/reference/extensions/fake-data) for a migration table.
|
|
6
12
|
|
|
7
13
|
## Documentation
|
|
8
14
|
|
package/index.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { faker } from '@faker-js/faker';
|
|
2
|
+
|
|
3
|
+
// Modules that don't expose simple data-generation functions
|
|
4
|
+
const SKIPPED_MODULES = new Set(['helpers', 'definitions', 'rawDefinitions']);
|
|
5
|
+
|
|
6
|
+
// Deprecated falso-style aliases kept for backwards compatibility.
|
|
7
|
+
// Maps legacy `$rand*` names to their faker equivalents (flattened names).
|
|
8
|
+
// NOTE: configuration options are NOT translated - options must be provided
|
|
9
|
+
// using the faker option shape, under the faker function name.
|
|
10
|
+
const DEPRECATED_ALIASES = {
|
|
11
|
+
randEmail: 'internetEmail',
|
|
12
|
+
randFullName: 'personFullName',
|
|
13
|
+
randFirstName: 'personFirstName',
|
|
14
|
+
randLastName: 'personLastName',
|
|
15
|
+
randUserName: 'internetUsername',
|
|
16
|
+
randPassword: 'internetPassword',
|
|
17
|
+
randUuid: 'stringUuid',
|
|
18
|
+
randPhoneNumber: 'phoneNumber',
|
|
19
|
+
randCity: 'locationCity',
|
|
20
|
+
randCountry: 'locationCountry',
|
|
21
|
+
randStreetAddress: 'locationStreetAddress',
|
|
22
|
+
randZipCode: 'locationZipCode',
|
|
23
|
+
randCompanyName: 'companyName',
|
|
24
|
+
randNumber: 'numberInt',
|
|
25
|
+
randBoolean: 'datatypeBoolean',
|
|
26
|
+
randUrl: 'internetUrl',
|
|
27
|
+
randIp: 'internetIpv4',
|
|
28
|
+
randWord: 'loremWord',
|
|
29
|
+
randSentence: 'loremSentence',
|
|
30
|
+
randParagraph: 'loremParagraph',
|
|
31
|
+
randText: 'loremText',
|
|
32
|
+
randJobTitle: 'personJobTitle',
|
|
33
|
+
randColor: 'colorHuman',
|
|
34
|
+
randProductName: 'commerceProductName'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const flattenName = (moduleName, functionName) =>
|
|
38
|
+
`${moduleName}${functionName[0].toUpperCase()}${functionName.slice(1)}`;
|
|
39
|
+
|
|
40
|
+
// Builds a map of flattened function names (e.g. `internetEmail`) to
|
|
41
|
+
// zero/one-argument faker functions (e.g. `faker.internet.email`)
|
|
42
|
+
const buildFakerFunctionMap = () => {
|
|
43
|
+
const functions = {};
|
|
44
|
+
|
|
45
|
+
for (const moduleName of Object.keys(faker)) {
|
|
46
|
+
if (SKIPPED_MODULES.has(moduleName) || moduleName.startsWith('_')) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const mod = faker[moduleName];
|
|
51
|
+
if (!mod || typeof mod !== 'object') {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Walk the prototype chain: some faker modules inherit methods
|
|
56
|
+
// (e.g. DateModule extends SimpleDateModule)
|
|
57
|
+
let proto = Object.getPrototypeOf(mod);
|
|
58
|
+
while (proto && proto !== Object.prototype) {
|
|
59
|
+
for (const functionName of Object.getOwnPropertyNames(proto)) {
|
|
60
|
+
if (functionName === 'constructor' || functionName.startsWith('_')) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (typeof mod[functionName] !== 'function') {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Only functions taking at most one argument are supported, as
|
|
69
|
+
// configuration is passed as a single (object) argument
|
|
70
|
+
if (mod[functionName].length > 1) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const flatName = flattenName(moduleName, functionName);
|
|
75
|
+
if (!functions[flatName]) {
|
|
76
|
+
functions[flatName] = mod[functionName].bind(mod);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
proto = Object.getPrototypeOf(proto);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return functions;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const fakerFunctionMap = buildFakerFunctionMap();
|
|
88
|
+
|
|
89
|
+
const getFakerFunctions = () => Object.keys(fakerFunctionMap);
|
|
90
|
+
|
|
91
|
+
const warnedAliases = new Set();
|
|
92
|
+
|
|
93
|
+
function ArtilleryPluginFakeData(script, events) {
|
|
94
|
+
this.script = script;
|
|
95
|
+
this.events = events;
|
|
96
|
+
|
|
97
|
+
const pluginConfig =
|
|
98
|
+
script.config['fake-data'] || script.config.plugins['fake-data'];
|
|
99
|
+
|
|
100
|
+
function fakeDataHandler(context, _ee, next) {
|
|
101
|
+
for (const [funcName, fakerFunc] of Object.entries(
|
|
102
|
+
fakerFunctionMap
|
|
103
|
+
) as [string, any][]) {
|
|
104
|
+
context.funcs[`$${funcName}`] = () => {
|
|
105
|
+
if (pluginConfig[funcName]) {
|
|
106
|
+
return fakerFunc(pluginConfig[funcName]);
|
|
107
|
+
}
|
|
108
|
+
return fakerFunc();
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const [aliasName, funcName] of Object.entries(DEPRECATED_ALIASES)) {
|
|
113
|
+
context.funcs[`$${aliasName}`] = () => {
|
|
114
|
+
if (!warnedAliases.has(aliasName)) {
|
|
115
|
+
warnedAliases.add(aliasName);
|
|
116
|
+
console.warn(
|
|
117
|
+
`[fake-data] $${aliasName} is deprecated and will be removed in a future release. Use $${funcName} instead.`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return context.funcs[`$${funcName}`]();
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
next();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
script.scenarios = script.scenarios.map((scenario) => {
|
|
129
|
+
scenario.beforeScenario = [].concat(scenario.beforeScenario || []);
|
|
130
|
+
scenario.beforeScenario.push('fakeDataHandler');
|
|
131
|
+
return scenario;
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
if (!script.config.processor) {
|
|
135
|
+
script.config.processor = {};
|
|
136
|
+
}
|
|
137
|
+
// In the main thread config.processor may still be an unresolved
|
|
138
|
+
// path (a string). Attaching functions to it was a silent no-op
|
|
139
|
+
// under sloppy mode; ES modules are strict, so guard explicitly.
|
|
140
|
+
// Workers load the processor into an object before plugins run.
|
|
141
|
+
const canAttach = typeof script.config.processor === 'object';
|
|
142
|
+
|
|
143
|
+
if (canAttach) {
|
|
144
|
+
script.config.processor.fakeDataHandler = fakeDataHandler;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const getDeprecatedAliases = () => ({ ...DEPRECATED_ALIASES });
|
|
151
|
+
|
|
152
|
+
export {
|
|
153
|
+
ArtilleryPluginFakeData as Plugin,
|
|
154
|
+
getFakerFunctions,
|
|
155
|
+
getDeprecatedAliases
|
|
156
|
+
};
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artillery-plugin-fake-data",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0-a33c503",
|
|
4
4
|
"description": "Add fake test data easily to your Artillery test scripts.",
|
|
5
|
-
"main": "index.
|
|
5
|
+
"main": "index.ts",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "
|
|
10
|
+
"test": "node --test --test-timeout=120000 \"test/*.spec.js\""
|
|
11
11
|
},
|
|
12
12
|
"license": "MPL-2.0",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@
|
|
15
|
-
}
|
|
14
|
+
"@faker-js/faker": "10.4.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {},
|
|
17
|
+
"type": "module"
|
|
16
18
|
}
|
package/index.js
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
const falso = require('@ngneat/falso');
|
|
2
|
-
|
|
3
|
-
const getFalsoFunctions = () =>
|
|
4
|
-
Object.keys(falso).filter((funcName) => {
|
|
5
|
-
//functions that have the function signature we expect start with rand and aren't == rand (which takes an array)
|
|
6
|
-
if (!funcName.startsWith('rand') && funcName !== 'rand') {
|
|
7
|
-
return false;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
//don't add functions that have more than 1 argument, as we only support 1 argument
|
|
11
|
-
//we can look into adding support for more arguments later, but most of the functions available use 1 argument anyway
|
|
12
|
-
if (falso[funcName].length > 1) {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return true;
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const falsoFunctions = getFalsoFunctions();
|
|
20
|
-
|
|
21
|
-
function ArtilleryPluginFakeData(script, events) {
|
|
22
|
-
this.script = script;
|
|
23
|
-
this.events = events;
|
|
24
|
-
|
|
25
|
-
const pluginConfig =
|
|
26
|
-
script.config['fake-data'] || script.config.plugins['fake-data'];
|
|
27
|
-
|
|
28
|
-
function falsoHandler(context, _ee, next) {
|
|
29
|
-
falsoFunctions.forEach((funcName) => {
|
|
30
|
-
context.funcs[`$${funcName}`] = () => {
|
|
31
|
-
if (pluginConfig[funcName]) {
|
|
32
|
-
return falso[funcName](pluginConfig[funcName]);
|
|
33
|
-
}
|
|
34
|
-
return falso[funcName]();
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
next();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
script.scenarios = script.scenarios.map((scenario) => {
|
|
42
|
-
scenario.beforeScenario = [].concat(scenario.beforeScenario || []);
|
|
43
|
-
scenario.beforeScenario.push('falsoHandler');
|
|
44
|
-
return scenario;
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
if (!script.config.processor) {
|
|
48
|
-
script.config.processor = {};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
script.config.processor.falsoHandler = falsoHandler;
|
|
52
|
-
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
module.exports = {
|
|
57
|
-
Plugin: ArtilleryPluginFakeData,
|
|
58
|
-
getFalsoFunctions
|
|
59
|
-
};
|