New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@jackfranklin/test-data-bot

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jackfranklin/test-data-bot - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

20

build/index.d.ts

@@ -13,8 +13,8 @@ export interface SequenceGenerator<T> {

}
export declare type FieldGenerator<T> = SequenceGenerator<T> | OneOfGenerator<T> | PerBuildGenerator<T>;
export declare type Field<T = any> = T | FieldGenerator<T> | FieldsConfiguration<T>;
export declare type FieldsConfiguration<FactoryResultType> = {
export type FieldGenerator<T> = SequenceGenerator<T> | OneOfGenerator<T> | PerBuildGenerator<T>;
export type Field<T = any> = T | FieldGenerator<T> | FieldsConfiguration<T>;
export type FieldsConfiguration<FactoryResultType> = {
readonly [Key in keyof FactoryResultType]: Field<FactoryResultType[Key]>;
};
export declare type Overrides<FactoryResultType = any> = {
export type Overrides<FactoryResultType = any> = {
[Key in keyof FactoryResultType]?: Field<FactoryResultType[Key]>;

@@ -38,7 +38,13 @@ };

}
export declare type ValueOf<T> = T[keyof T];
export declare const build: <FactoryResultType>(factoryNameOrConfig: string | BuildConfiguration<FactoryResultType>, configObject?: BuildConfiguration<FactoryResultType> | undefined) => (buildTimeConfig?: BuildTimeConfig<FactoryResultType> | undefined) => FactoryResultType;
export type ValueOf<T> = T[keyof T];
export interface Builder<FactoryResultType> {
(buildTimeConfig?: BuildTimeConfig<FactoryResultType>): FactoryResultType;
reset(): void;
one(buildTimeConfig?: BuildTimeConfig<FactoryResultType>): FactoryResultType;
many(count: number, buildTimeConfig?: BuildTimeConfig<FactoryResultType>): FactoryResultType[];
}
export declare const build: <FactoryResultType>(factoryNameOrConfig: string | BuildConfiguration<FactoryResultType>, configObject?: BuildConfiguration<FactoryResultType> | undefined) => Builder<FactoryResultType>;
export declare const oneOf: <T>(...options: T[]) => OneOfGenerator<T>;
export declare const bool: () => OneOfGenerator<boolean>;
declare type Sequence = {
type Sequence = {
(): SequenceGenerator<number>;

@@ -45,0 +51,0 @@ <T>(userProvidedFunction: (count: number) => T): SequenceGenerator<T>;

@@ -72,2 +72,5 @@ "use strict";

}
if (fieldValue instanceof Date) {
return fieldValue;
}
if (typeof fieldValue === 'object') {

@@ -78,5 +81,22 @@ return expandConfigFields(fieldValue);

};
return (buildTimeConfig = {}) => {
const builder = (buildTimeConfig = {}) => {
const fieldsToReturn = expandConfigFields(config.fields, buildTimeConfig);
const traitsArray = buildTimeTraitsArray(buildTimeConfig);
// A user might define a value in a trait that doesn't exist in the base
// set of fields. So we need to check now if the traits set any values that
// aren't in the base, and set them too.
traitsArray.forEach((traitName) => {
const traitConfig = (config.traits && config.traits[traitName]) || {};
if (!traitConfig.overrides) {
return;
}
for (const stringKey of Object.keys(traitConfig.overrides)) {
const key = stringKey;
// If the key already exists in the base fields, we'll have defined it,
// so we don't need to worry about it.
if (key in config.fields === false) {
fieldsToReturn[key] = expandConfigField(traitConfig.overrides[key]);
}
}
});
const traitPostBuilds = traitsArray.map((traitName) => {

@@ -94,2 +114,12 @@ const traitConfig = (config.traits && config.traits[traitName]) || {};

};
builder.reset = () => {
sequenceCounter = 0;
};
builder.one = (buildTimeConfig) => {
return builder(buildTimeConfig);
};
builder.many = (times, buildTimeConfig) => {
return new Array(times).fill(0).map(() => builder(buildTimeConfig));
};
return builder;
};

@@ -96,0 +126,0 @@ exports.build = build;

{
"name": "@jackfranklin/test-data-bot",
"version": "2.0.0",
"version": "2.1.0",
"license": "MIT",

@@ -11,5 +11,6 @@ "description": "Generate test data for your tests easily.",

"scripts": {
"test": "jest src",
"lint": "eslint 'src/*.ts' && prettier --list-different 'src/*.ts'",
"lint-fix": "eslint --fix 'src/*.ts' && prettier --write 'src/*.ts'",
"test": "tap --no-coverage -R=dot",
"test-with-coverage": "tap -R=dot",
"lint": "eslint '{src,test}/*.ts' && prettier --list-different '{src,test}/*.ts'",
"lint-fix": "eslint --fix '{src,test}/*.ts' && prettier --write '{src,test}/*.ts'",
"build": "tsc --build tsconfig.json",

@@ -19,2 +20,5 @@ "prepare": "npm run build",

},
"tap": {
"ts": true
},
"keywords": [

@@ -37,4 +41,6 @@ "testing",

"devDependencies": {
"@types/jest": "^27.0.3",
"@types/node": "^17.0.9",
"@sinonjs/fake-timers": "^10.0.0",
"@types/node": "^18.0.0",
"@types/sinon": "^10.0.13",
"@types/tap": "^15.0.7",
"@typescript-eslint/eslint-plugin": "^5.6.0",

@@ -45,9 +51,10 @@ "@typescript-eslint/parser": "^5.6.0",

"eslint-config-unobtrusive": "^1.2.5",
"eslint-plugin-jest": "^25.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.4.3",
"eslint-plugin-tap": "^1.2.1",
"prettier": "^2.5.1",
"ts-jest": "^27.1.1",
"typescript": "^4.6.2"
"sinon": "^15.0.1",
"tap": "^16.3.0",
"ts-node": "^10.9.1",
"typescript": "^4.8.4"
}
}
# @jackfranklin/test-data-bot
[![CircleCI](https://circleci.com/gh/jackfranklin/test-data-bot.svg?style=svg)](https://circleci.com/gh/jackfranklin/test-data-bot)
[![npm version](https://badge.fury.io/js/%40jackfranklin%2Ftest-data-bot.svg)](https://badge.fury.io/js/%40jackfranklin%2Ftest-data-bot)

@@ -35,3 +33,3 @@

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -42,3 +40,3 @@ name: 'jack',

const user = userBuilder();
const user = userBuilder.one();
console.log(user);

@@ -50,16 +48,10 @@ // => { name: 'jack'}

**Note**: if you're using *Version 1.2 or higher* you can leave the name of the factory and pass in only the configuration object:
Once you've created a builder, you can call the `one` method it returns to generate an instance of that object - in this case, a `user`.
```js
const userBuilder = build({
fields: {
name: 'jack',
},
});
```
const user = userBuilder.one();
```
Feel free to use the name property if you like, but it's not used for anything in test-data-bot. It will probably get removed in a future major version.
> You can also call the builder directly to get a single instance - `userBuilder()`. v2.1 of test-data-bot shipped with the `one()` method and that is now the recommended way of constructing these objects.
Once you've created a builder, you can call it to generate an instance of that object - in this case, a `user`.
It would be boring though if each user had the same `name` - so test-data-bot lets you generate data via some API methods:

@@ -74,3 +66,3 @@

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -81,4 +73,4 @@ id: sequence(),

const userOne = userBuilder();
const userTwo = userBuilder();
const userOne = userBuilder.one();
const userTwo = userBuilder.one();

@@ -94,3 +86,3 @@ // userOne.id === 1

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -101,4 +93,4 @@ email: sequence(x => `jack${x}@gmail.com`),

const userOne = userBuilder();
const userTwo = userBuilder();
const userOne = userBuilder.one();
const userTwo = userBuilder.one();

@@ -109,4 +101,27 @@ // userOne.email === jack1@gmail.com

### Randomly picking between an option
You can use the `reset` method to reset the counter used internally when generating a sequence:
```js
const { build, sequence } = require('@jackfranklin/test-data-bot');
const userBuilder = build({
fields: {
id: sequence(),
},
});
const userOne = userBuilder.one();
const userTwo = userBuilder.one();
userBuilder.reset();
const userThree = userBuilder.one();
const userFour = userBuilder.one();
// userOne.id === 1
// userTwo.id === 2
// userThree.id === 1 <- the sequence has been reset here
// userFour.id === 2
```
### Randomly picking between an option with `oneOf`
If you want an object to have a random value, picked from a list you control, you can use `oneOf`:

@@ -117,3 +132,3 @@

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -132,3 +147,3 @@ name: oneOf('alice', 'bob', 'charlie'),

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -147,3 +162,3 @@ isAdmin: bool(),

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -159,4 +174,4 @@ name: 'jack',

```js
const userOne = userBuilder();
const userTwo = userBuilder();
const userOne = userBuilder.one();
const userTwo = userBuilder.one();

@@ -171,3 +186,3 @@ userOne.details === userTwo.details; // true

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -181,4 +196,4 @@ name: 'jack',

const userOne = userBuilder();
const userTwo = userBuilder();
const userOne = userBuilder.one();
const userTwo = userBuilder.one();

@@ -194,3 +209,3 @@ userOne.details === userTwo.details; // false

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -202,23 +217,2 @@ name: perBuild(() => myFakeLibrary.randomName()),

### Mapping over all the created objects with `postBuild`
If you need to transform an object in a way that test-data-bot doesn't support out the box, you can pass a `postBuild` function when creating a builder. This builder will run everytime you create an object from it.
```js
const { build, fake } = require('@jackfranklin/test-data-bot');
const userBuilder = build('User', {
fields: {
name: fake(f => f.name.findName()),
},
postBuild: user => {
user.name = user.name.toUpperCase();
return user;
},
});
const user = userBuilder();
// user.name will be uppercase
```
## Overrides per-build

@@ -231,3 +225,3 @@

const userBuilder = build('User', {
const userBuilder = build({
fields: {

@@ -239,3 +233,3 @@ id: sequence(),

const user = userBuilder({
const user = userBuilder.one({
overrides: {

@@ -251,6 +245,6 @@ id: 1,

If you need to edit the object directly, you can pass in a `map` function when you call the builder:
If you need to edit the object directly, you can pass in a `map` function when you call the builder. This will be called after test-data-bot has generated the fake object, and lets you directly change its properties.
```js
const { build, fake, sequence } = require('@jackfranklin/test-data-bot');
const { build, sequence } = require('@jackfranklin/test-data-bot');

@@ -260,7 +254,7 @@ const userBuilder = build('User', {

id: sequence(),
name: fake(f => f.name.findName()),
name: 'jack',
},
});
const user = userBuilder({
const user = userBuilder.one({
map: user => {

@@ -275,2 +269,54 @@ user.name = user.name.toUpperCase();

### Creating multiple instances
If you want to create multiple instances of a builder at once, you can use the `many` method on the builder:
```js
const userBuilder = build({
fields: {
name: 'jack',
},
});
const users = userBuilder.many(20); // Creates an array of 20 users.
```
If you want to pass in any build time configuration, you can pass in a second argument which takes the exact same configuration as calling `userBuilder()` directly:
```js
const userBuilder = build({
fields: {
name: 'jack',
},
});
const users = userBuilder.many(20, {
overrides: {
name: 'bob'
}
}); // Creates an array of 20 users, each called "bob"!
```
### Mapping over all the created objects with `postBuild`
If you need to transform an object in a way that test-data-bot doesn't support out the box, you can pass a `postBuild` function when creating a builder. This builder will run every time you create an object from it.
```js
const { build, fake } = require('@jackfranklin/test-data-bot');
const userBuilder = build({
fields: {
name: fake(f => f.name.findName()),
},
postBuild: user => {
user.name = user.name.toUpperCase();
return user;
},
});
const user = userBuilder.one();
// user.name will be uppercase
```
## Traits (*new in v1.3*)

@@ -289,7 +335,7 @@

name: 'jack',
admin: perBuild(() => false),
admin: false,
},
traits: {
admin: {
overrides: { admin: perBuild(() => true) },
overrides: { admin: true },
},

@@ -303,3 +349,3 @@ },

```js
const adminUser = userBuilder({ overrides: { admin: perBuild(() => true) } });
const adminUser = userBuilder.one({ overrides: { admin: true } });
```

@@ -313,7 +359,7 @@

name: 'jack',
admin: perBuild(() => false),
admin: false,
},
traits: {
admin: {
overrides: { admin: perBuild(() => true) },
overrides: { admin: true },
},

@@ -327,3 +373,3 @@ },

```js
const admin = userBuilder({ traits: 'admin' });
const admin = userBuilder.one({ traits: 'admin' });
```

@@ -335,3 +381,3 @@

// any properties defined in other-trait will override any that admin sets
const admin = userBuilder({ traits: ['admin', 'other-trait'] });
const admin = userBuilder.one({ traits: ['admin', 'other-trait'] });
```

@@ -354,7 +400,7 @@

id: sequence(),
name: fake(f => f.name.findName()),
name: perBuild(() => yourCustomFakerLibary().name)
},
});
const users = userBuilder();
const users = userBuilder.one();
```

@@ -364,124 +410,16 @@

_I'm still quite new to TypeScript so please let me know if you don't get the errors/type hints that you expect!_
## What happened to Faker / the `fake` generator?
# Migrating from `test-data-bot@0.8.0` to `@jackfranklin/test-data-bot@1.0.0`
Prior to v2.0.0 of this library, we shipped built-in support for using Faker.js to generate data. It was removed because it was a big dependency to ship to all users, even those who don't use faker. If you want to use it you can, in combination with the `perBuild` builder:
Firstly: there is no need to migrate immediately if the old version is doing the job for you - but it won't be improved or have bug fixes so it's recommended to migrate slowly to 1.0.0.
You can also run both versions at the same time - they won't conflict. Just make sure you rename the API methods or import everything:
```js
const legacyTestDataBot = require('test-data-bot')
const newTestDataBot = require('@jackfranklin/test-data-bot')
import {build, perBuild} from '@jackfranklin/test-data-bot';
const oldBuilder = legacyTestDataBot.build(...)
// This can be any fake data library you like.
import fake from 'faker';
const newBuilder = newTestDataBot.build(...)
const userBuilder = build({
// Within perBuild, call your faker library directly.
name: perBuild(() => fake().name())
})
```
## Breaking changes in the new version
### Node 10.13 is required
Previously Node 8 was supported, but now the minimum is 10.13.
### API for declaring fields has changed
Before:
```js
const userBuilder = build('User').fields({
name: fake(f => f.name.findName()),
});
```
After:
```js
const userBuilder = build('User', {
fields: {
name: fake(f => f.name.findName()),
},
});
```
### `numberBetween` has been removed
`numberBetween` was a shortcut around `fake`. If you need it back you can easily define it:
```js
const { fake } = require('@jackfranklin/test-data-bot');
const numberBetween = (min, max) => fake(f => f.random.number({ min, max }));
```
It's highly recommended to maintain a library of custom matchers that are useful for your application.
### `incrementingId` has been removed
You can now call `sequence()` with no argument to get the same result:
Before:
```js
id: incrementingId();
```
After:
```js
id: sequence();
```
### `arrayOf` has been removed
It was hard to provide a nice API for `arrayOf` that supported all cases. It's now recommended to use the `postBuild` function if you always want an object to have an array of things:
```js
const blogPostBuilder = build('BlogPost', {...})
const userBuilder = build('User', {
fields: {
name: fake(f => f.name.findName()),
blogPosts: [],
},
postBuild: user => {
user.blogPosts = Array(3).fill(undefined).map(_ => blogPostBuilder())
return user
}
});
```
### The `map` function has been removed
The old version of test-data-bot provided a map function on each object that it generated. This was confusing and awkward as it meant test-data-bot placed a `map` function on generated objects. If your object had a `map` property, it would be overriden!
This is now replaced by the `postBuild` function.
Before:
```js
const userBuilder = build('User')
.fields({
name: fake(f => f.name.findName()),
email: sequence(x => `jack${x}@test.com`),
})
.map(user => ({
name: user.name.toUpperCase(),
email: user.email.toUpperCase(),
}));
```
After:
```js
const userBuilder = build('User', {
fields: {
name: fake(f => f.name.findName()),
email: sequence(x => `jack${x}@test.com`),
},
postBuild: user => ({
name: user.name.toUpperCase(),
email: user.email.toUpperCase(),
}),
});
```

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc