MCPcopy Index your code
hub / github.com/faboulaws/fakingoose

github.com/faboulaws/fakingoose @v3.0.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v3.0.0 ↗ · + Follow
51 symbols 100 edges 15 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

fakingoose

Build Status Coverage Status

An automatic mock data generator for mongoose using schema definition.

Install

npm install fakingoose

Usage

const {
    factory
} = require('fakingoose');
const entityFactory = factory(model, options);

factory(model, options)

  • model \<Schema> or \<Model>: Mongoose model or schema.
  • options \<? Object>: Generation options are optional. The factory would generate data for all fields based on the schema alone. For cases where there is a need for custom values, options can be used to define custom values or data generation setting per field.
  • options.\<propertyName>.value \<mixed>: A static value for each generated mock object.
  • options.\<propertyName>.value: \<function> a function for generating a dynamic value per item. This function receives the mock object as first argument.
  • options.\<propertyName>.skip \<boolean>: When set to true would skip the field.
  • options.\<propertyName>.type \<string>: The sub-type for this field type. For example \<String> schema type supports email , firsname and lastname .
  • options.\<propertyName\>.populateWithSchema: Uses a schema to generate mocks of related models
  • options.\<propertyName\>.populateWithFactory: Uses another factory to generate mocks of related models. This options provides more flexibility than populateWithSchema, taking advantage of custom behaviours of factory via Factory options.
  • options.\<propertyName\>.size \<int>: (Array values only) When specified, will ensure that said array field has given number of elements. By default, this is set to 2.

Usage example

const mongoose = require('mongoose');
const {
    factory
} = require('fakingoose');
const {
    Schema
} = mongoose;

const authorSchema = new Schema({
    id: Schema.Types.ObjectId,
    title: {
        type: String,
        enum: ['Mr', 'Mrs', 'Dr']
    },
    fullname: String,
    username: String,
    email: String,
    favoriteQuote: String,
});

const blogSchema = new Schema({
    title: String,
    author: authorSchema,
    body: String,
    comments: [{
        body: String,
        date: Date
    }],
    date: {
        type: Date,
        default: Date.now
    },
    hidden: Boolean,
    meta: {
        votes: {
            type: Number,
            min: 0
        },
        favs: {
            type: Number,
            min: 0
        }
    }
});

const options = {
    author: {
        email: {
            type: 'email',
        },
        username: {
            value: (object) => {
                return object.fullname.toLowerCase().replace(/\s/g, '.');
            }
        },
        favoriteQuote: {
            skip: true
        }
    },
};
const blogFactory = factory(blogSchema, options);

const mock = blogFactory.generate({
    author: {
        fullname: 'John Doe'
    }
});

sample output

{
  "title":"8tnkcjplr",
  "author":{
    "id":"5d513f762a48134adb1868d7",
    "title":"Dr",
    "fullname":"John Doe",
    "username":"john.doe",
    "email":"re@sisuki.mc",
    "_id":"5d513f762a48134adb1868d8"
  },
  "body":"ebjwad6*keskl",
  "comments":[
    {
      "body":"d$*t9y3",
      "date":"2019-08-12T10:29:10.193Z",
      "_id":"5d513f762a48134adb1868d9"
    },
    {
      "body":"jv5o[",
      "date":"2019-08-12T10:29:10.193Z",
      "_id":"5d513f762a48134adb1868da"
    }
  ],
  "hidden":false,
  "meta":{"votes":-3419053502758912,"favs":3323094479405056},
  "_id":"5d513f762a48134adb1868db"
}
 ```

## Define options for nested properties

 To define options for nested a property use the nested property path (property names sperated by a dot).
 Example: 

```js
const options = {
    "meta.votes": {
        value: 0
    }, // set value for 'votes' property under meta
    "meta.favs": {
        skip: true
    } // skip value for 'favs' property under meta
}

Skipping multiple nested properties

Multiple nested properties can be skipped from parent property. Example:

const accountSchema = new mongoose.Schema({
    user: {
        generalInfo: {
            firstName: String,
            lastName: String,
            age: Number
        },
        address: {
            postCode: String,
            street: String
        }
    }
});
const accountFactory = factory(accountSchema, options);

To generate mocks without an address define options as below you have to override the default factory's options:

const options = {
    'user.address': {
        skip: true
    }
}

or

const options = {
    user: {
        address: {
            skip: true
        }
    }
}

then

const mockObject = accountFactory.generate({}, options);

Generating ObjectId values

When generating ObjectId values, you can choose to Stringify the generated ObjectId by using the tostring option. By default this options is true , so all generated ObjectIds would be converted to a String. Set tostring to false to disable this behaviour.

Example: In the snippet below all ObjectIds generated are not stringified.

const friendSchema = new Schema({
    id: Schema.Types.ObjectId,
    friendIds: [{
        type: Schema.Types.ObjectId
    }],
    bestFriend: {
        id: Schema.Types.ObjectId
    }
});

const amigoFactory = factory(friendSchema, {
    id: {
        tostring: false
    },
    friendIds: {
        tostring: false
    },
    'bestFriend.id': {
        tostring: false
    }
});

Global settings

To disable stringification globally use factory.setGlobalObjectIdOptions .

Example:

const friendSchema = new Schema({
    id: Schema.Types.ObjectId,
    friendIds: [{
        type: Schema.Types.ObjectId
    }],
    bestFriend: {
        id: Schema.Types.ObjectId
    }
});

const amigoFactory = factory(friendSchema).setGlobalObjectIdOptions({
    tostring: false
});

Generating mocks for related models (Populate)

Mongoose provides an API for automatically replacing the specified paths in the document with document(s) from other collection(s). This package provides a similar functionality when generating mocks.

An example: In the snippet below we have two schemas, activitySchema & personSchema .

const activitySchema = new mongoose.Schema({
    name: String,
    value: String,
});

const personSchema = new mongoose.Schema({
    email: String,
    name: {
        type: String,
    },
    activities: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'activity'
    }],
});

When generating mock data from the personSchema we should get the sample below

{
    email: 'l7@eiwtef%(pzitx',
    name: 'ym](ht7ucas*',
    activities: ['60f1e810a8b8ac392c3869b7', '60f1e810a8b8ac392c3869b8'],
    _id: '60f1e810a8b8ac392c3869b9'
}

In some cases we might want to receive activity data instead of activity ID in the activities property, so we have a structure like below.

 {
     email: ')5b2[dj@@)p91(',
     name: 'qo[jk!',
     activities: [{
             name: '7^*8h^@!zp^!*hqwn',
             value: ']55f$hmva',
             _id: '60f1e51dead56f35c7ed4f62'
         },
         {
             name: 'r!cv!k!p#vqfqt4a9k',
             value: '$@6k!z&oflj6',
             _id: '60f1e51dead56f35c7ed4f63'
         }
     ],
     _id: '60f1e51dead56f35c7ed4f64'
 }

Let's look at two seperate ways we can achieve this:

  • options.\<propertyName\>.populateWithSchema: Uses a schema to generate mocks of related models.

  • options.\<propertyName\>.populateWithFactory: Uses another factory to generate mocks of related models. This options provides more flexibility than populateWithSchema, taking advantage of custom behaviors of factory via Factory options.

Example: options.populateWithFactory

  const activityFactory = mocker(activitySchema)

  const personFactory = mocker(personSchema, {
      activities: {
          populateWithFactory: activityFactory
      }
  })
  const mock = personFactory.generate()

Example: options.populateWithSchema

const myFactory = mocker(schema, {
    activities: {
        populateWithSchema: activitySchema
    }
})
const mock = myFactory.generate()

Generating decimal (Decimal128) values

When generating decimal values, you can choose to Stringify the generated number by using the tostring option. By default this options is true , so all generated numbers would be converted to a String. Set tostring to false to disable this behaviour.

Example: In the snippet below all numbers generated are not stringified.

const productSchema = new Schema({
    price: Schema.Types.Decimal128
});

const productFactory = factory(productSchema, {
    price: {
        tostring: false
    }
});

Generating a variable-sized array of items per field

When generating array values, you can specify a size parameter to ensure the array field has that many elements. By default, this is set to 2.

Example: Each new user will now have 10 new statuses to start.

const userSchema = new mongoose.Schema({
    email: String,
    name: {
        type: String,
    },
    activities: [{
        type: String,
    }],
});

const userFactory = factory(userSchema, {
    activities: {
        size: 10
    }
});

Global settings

To disable stringification globally use factory.setGlobalDecimal128Options .

Example:

const productSchema = new Schema({
    price: Schema.Types.Decimal128
});

const productFactory = factory(productSchema).setGlobalDecimal128Options({
    tostring: false
});

Override factory options per mock generated

I some cases we want to override options that we used to initialise a factory. These options can be overridden in the generate() method of the factory.

Example

const schema = new Schema({
    updated: {
        type: Date,
        default: Date.now
    },
    title: String,
    content: String,
});

const options = {
    updated: {
        skip: true
    }
};

const myFactory = mocker(schema, options);
const mockWithoutUpdated = myFactory.generate({}); // here use options used to initilize the factory. We skip the "updated: field

const mockWithoutTitle = myFactory.generate({}, { // here use custom options. We skip the "title: field
    title: {
        skip: true
    }
});

Supported Types

  • String
  • Array
  • Number
  • Decimal128
  • ObjectId
  • Boolean
  • Mixed
  • Buffer
  • Embedded
  • Date
  • Map

Mongoose version Support

Version Supported
7.x :white_check_mark:
6.x :white_check_mark:
5.x :white_check_mark:
4.x :white_check_mark:

Extension points exported contracts — how you extend this code

SkipFieldOptions (Interface)
(no doc)
lib/types.ts
ISomeThing (Interface)
(no doc)
test/mocker.test.ts
Parent (Interface)
(no doc)
examples/parent.ts
FieldValueOptions (Interface)
(no doc)
lib/types.ts
Isch (Interface)
(no doc)
test/mocker.test.ts
StringFieldOptions (Interface)
(no doc)
lib/types.ts
IEntity (Interface)
(no doc)
test/mocker.test.ts
SizeFieldOptions (Interface)
(no doc)
lib/types.ts

Core symbols most depended-on inside this repo

generate
called by 47
lib/mocker.ts
getPropertyByPath
called by 4
lib/generate.ts
getPropertyByName
called by 4
lib/generate.ts
generate
called by 4
lib/generate.ts
factory
called by 3
lib/mocker.ts
populateField
called by 2
lib/generate.ts
setIndirectValues
called by 2
lib/generate.ts
setGlobalObjectIdOptions
called by 2
lib/mocker.ts

Shape

Interface 24
Function 20
Method 4
Class 2
Enum 1

Languages

TypeScript100%

Modules by API surface

test/mocker.test.ts20 symbols
lib/types.ts11 symbols
lib/generate.ts11 symbols
lib/mocker.ts8 symbols
examples/parent.ts1 symbols

Datastores touched

ArrayThingCollection · 1 repos
EntityCollection · 1 repos
MapModelCollection · 1 repos
StringThingCollection · 1 repos
ThingCollection · 1 repos

For agents

$ claude mcp add fakingoose \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page