blinkux / sequelize-mock Goto Github PK
View Code? Open in Web Editor NEWA simple mock interface specifically for testing code relying on Sequelize models
Home Page: https://sequelize-mock.readthedocs.io
License: MIT License
A simple mock interface specifically for testing code relying on Sequelize models
Home Page: https://sequelize-mock.readthedocs.io
License: MIT License
To do have proper support for unit testing, we need a system to queue up what results would come from what queries. This needs planning around how to support what kinds of queries (upsert vs sum vs findAll, etc).
TypeError: user.setDataValue is not a function
I'm getting this error while setting value
User.findOne().then((user) =>{
user.setDataValue("logged_in", true);
user.save();
})
But its working in normal sequelize.
We need to do more data type mocking. This should include being able to turn on/off validation for properties coming into the mock item, and mimicing Sequelize functionality related to data type handling.
I'm currently working with some methods that do not appear to be mocked onto the model - findAndCount/findAndCountAll. I tried adding them via the instanceMethods when defining the mock, but that did not appear to work for me either. Don't know if that's a separate issue (or something I'm doing wrong) but kept getting undefined when trying to call the created method.
Hello everyone!
I started using your library, because seems to be extremely useful in my project. Unfortunately, while running jest
test, an error occurs:
TypeError: Utils.stack(...).getFileName is not a function
at Sequelize.Object.<anonymous>.Sequelize.import (node_modules/sequelize-mock/src/sequelize.js:332:44)
It points to line:
sequelize-mock/src/sequelize.js
Line 332 in edac5af
Reference to original sequelize
models looks like:
this.DB.import(`./{modelName}`)
All import paths were overriden by $overrideImport
method in many ways, but none succeeded.
What could be the reason of that behaviour?
Thank you in advance for any response.
Sequelize findOrCreate function looks for one element and if it is found, returns an Array that contains [elementFound, created]
.
Where elementFound is an Instance and created is a boolean. If the conditions of the query match more than one element, it just returns the first one (array index 0), like noted in the comment:
In the example above, the array spread on line 3 divides the array into its 2 parts and passes them
as arguments to the callback function defined beginning at line 39, which treats them as "user" and
"created" in this case. (So "user" will be the object from index 0 of the returned array and
"created" will equal "true".)
http://docs.sequelizejs.com/manual/models-usage.html
In Sequelize-mock docs the findOrCreate reflects that it returns Promise.<Array.<Instance, Boolean>>
but it actually returns Promise.<Array.<Array<Instance>, Boolean>>
.
That second Array is not supposed to be there. Must return the 0 index of that array.
Currently the examples are very limited and it is not clear how one could have multiple rows in their mock data. Neither the readme nor the documentation seem to cover how that would be possible.
For example the below example only describes the usage of a single row
var UserMock = DBConnectionMock.define('users', {
'email': '[email protected]',
'username': 'blink',
'picture': 'user-picture.jpg',
}, {
instanceMethods: {
myTestFunc: function () {
return 'Test User';
},
},
});
Whereas directly below we have a WHERE
example which is completely unclear on how to actually reproduce. This is because there is neither information on adding multiple rows, nor is the example condition and fields valid for the above row.
UserMock.findOne({
where: {
username: 'my-user',
},
}).then(function (user) {
// `user` is a Sequelize Model-like object
user.get('id'); // Auto-Incrementing ID available on all Models
user.get('email'); // '[email protected]'; Pulled from default values
user.get('username'); // 'my-user'; Pulled from the `where` in the query
user.myTestFunc(); // Will return 'Test User' as defined above
});
Sorry if this is a dumb issue, but I'm having trouble getting tests working for retrieval. The idea below is to insert a user, then test that retrieving the user works correctly.
Condensing the code:
const mockDatabase = () => {
const connection = new DBConnectionMock();
return {
user: connection.define("user")
};
};
describe("getUser", () => {
it("gets an existing user", async () => {
// Arrange
const database = mockDatabase();
const stubUser = {
authId: "foo"
};
database.user.upsert(stubUser);
// Act
const retrieved = await database.user.findOne({
where: {
{ userId: { $eq: stubUser.authId } }
}
});
// Assert
// Is it either of these?
expect(retrieved.authId)).to.be.equal(stubUser.authId);
expect(retrieved.get("authId")).to.be.equal(stubUser.authId);
});
});
I'm trying to use sequelize-mock
as a drop-in replacement of regular sequelize
. Following snippet is from models/index.js
that is using either sequelize-mock or sequelize based on environment
const Sequelize = isTest ? require('sequelize-mock') : require('sequelize');
const sequelize = new Sequelize(dbConfig);
loadFiles(modelsDir).forEach(file => {
const model = sequelize.import(file);
db[model.name] = model;
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
All works great except that Sequelize.define
from sequelize-mock
behaves different. It using its second argument as columns default values, while the one from sequelize
using second argument as columns configuration. So given model's code is
Sequelize.define('Class', {
name: {
type: Sequelize.STRING,
field: 'class_name'
},
...
});
then sequelize-mock
will be using { type: Sequelize.STRING, field: 'class_name' }
as a default value for name
column.
Question: Is it something that never supposed to work this way or am I missing something?
P.S. Since apart from that it works for me I've overridden define
method to reset _defaults
field that there're no default values for columns:
const { define } = SequelizeMock.prototype;
SequelizeMock.prototype.define = (...args) => {
const model = define(...args);
model._defaults = {}; // or going through model attributes and using `defaultValue` if it exists
return model;
};
Following example outputs "update" from console:
const dbMock = new SequelizeMock();
const User = dbMock.define('user', {
username: 'myTestUsername',
email: '[email protected]',
});
User.$queryInterface.$useHandler((query, options) => {
console.log(query);
});
User.update({ username: 'newUsername' });
and this does not output anything:
const dbMock = new SequelizeMock();
const User = dbMock.define('user', {
username: 'myTestUsername',
email: '[email protected]',
});
User.$queryInterface.$useHandler((query, options) => {
console.log(query);
});
User.create({ username: 'newUsername' });
(the difference is the method called on User model in the last line)
Funny enough, upsert works too, also the documentation is not clear about which methods are being mocked and why would 'create' be ignored.
I created my model such this:
var domainMock = dbMock.define('domains',{
'domain':simpletest.com',
},{
'$autoQueryFallback':false
});
So when i try to search domainMock.findOne({domain:"anotherdomain.com"}), instance create a new record
Or I wrote a wrong code?
I feel like I'm being an idiot :), but I've setup my test as close to the docs as possible, yet I'm getting an TypeError: User.$useHandler is not a function
error any time I try to run tests. I've dug through the code trying see if I'm using it at the right place and I'm stuck. Any help is appreciated, the library looks super useful!
var SequelizeMock = require('sequelize-mock');
var dbMock = new SequelizeMock();
var User = dbMock.define('User', {
title: 'hi',
});
User.$useHandler(function(query, queryOptions, done) {
if (query === "findOne") {
return Promise.resolve('test');
} else if (query === "destroy") {
return Promise.reject(new SequelizeMock.Error("DB down"));
} else {
// This handler can handle this query
return;
}
});
Hey folks,
here's my configuration:
"dependencies": {
"sequelize": "^4.41.1",
"sequelize-mock": "^0.10.2"
}
Here is my test case:
const createData = require("../index.js");
const SequelizeMock = require("sequelize-mock");
const dbMock = new SequelizeMock();
const mockData = require('./mock');
describe("Create Data", () => {
it("Should create data in sequelize", async done => {
try {
const result = await createData(mockData);
expect(result).toBeDefined();
} catch (err) {
expect(err).toBeNull();
}
});
});
The test case passes, but jest console returns:
Jest did not exit one second after the test run has completed.
It might be something I missed from the tutorial.
Any pointers?
Let me know if I missed something above, I'll share it asap.
Your GitHub README getting started instructions state ...
var SequelizeMock = require('sequelize-mock');
var DBConnectionMock = new SequelizeMock();
... but your ReadTheDocs instructions state ...
Because Sequelize Mock is meant ... .... any actual connection data.
var SequelizeMock = require('sequelize-mock')();
var dbMock = new SequelizeMock();
If I follow the second version's require
, with its trailing function parenthesis, I get the error:
TypeError: Cannot set property 'queryInterface' of undefined
To be a drop in replacement, it should be a drop in replacement for all the components. Need investigation into if we can do DB connection style testing and simulation and allows for greater control in testing functionality. It should accept the same options as Sequelize and mimic all the core functionality around DB connection management
Import supports when a module is exported with the Node module.exports
syntax but not the export default
ES6 syntax. Sequelize supports both methods under the hood by checking for the type of the export on require. We should be doing the same thing.
First reported in issue #35
When I try to specify an associations, for example belongsTo or hasOne, I get an error:
"Can not set property "getUser" of undefined"
And a pointer to the "model.js" file: 560: 37
I want to make a mock with multiple records.
What kind of method is there?
The following code is the behavior image.
var UserMock = DBConnectionMock.define('users', {
'email': '[email protected]',
'username': 'one'
});
var UserMock = DBConnectionMock.define('users', {
'email': '[email protected]',
'username': 'two'
});
UserMock.findAll([options]).then(function(users) {
// users test
});
Could you add support for the Sequelize updateAttributes() function, please?
Is there any interest in making typings for this project available for TypeScript?
https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
Right now we pass in an empty object for transaction, but this is obviously less than ideal. We should have a mock transaction object that mocks that API so it can be used as a drop in replacement too.
all of the examples in the project readme seem to support only a single instance. i am trying to write a test against a set of instances. i don't see a way to fake a set of rows. i have looked through your src code (i have 0.7.0), and don't see any way to do this.
alternatively, i have been reading your readthedocs, and i see $queueResult --which looks like a setup where i could set up a test with any result i am trying to test against (i'd like to feed it an array of objects). this looks like what i want, but i see in #1 that this is a consideration for a future feature. i don't see any branches in your project... so i am really puzzled by two things -- 1) most importantly, how is anyone today using sequelize-mock to tests against sets of data, and 2) if the $queueResult is not real, why is it in the docs?
thanks!
Hello,
I noticed that if I do a
MockedModel.findOne({ where: { id: undefined } }).then(...)
I will still get a result instead of an undefined.
This prevents me from testing negative scenarios where the data should not exist.
Is there a way to add a handler for methods that get called on instances returned from another handler? For example, perhaps I return an array of model instances for findAll, and then one of those instances is later called with update()...can I add a handler for the update() call?
I have:
const User = sequelize.define('User', {....... })
User.prototype.validatePassword = function(password /*: string*/ ) {
return bcrypt.compareSync(password, this.password);
}
ButI have an error:
TypeError: Cannot set property 'validatePassword' of undefined
UserMock.findOne({
where: {
username: 'my-user',
},
}).then(function (user) {
// `user` is a Sequelize Model-like object
user.get('id'); // Auto-Incrementing ID available on all Models
user.get('email'); // '[email protected]'; Pulled from default values
user.get('username'); // 'my-user'; Pulled from the `where` in the query
user.myTestFunc(); // Will return 'Test User' as defined above
});
In this example, findOne()
always return something which basically a combination of where clause and default value. It means it will never going to actually look for an instance from some storage. This behaviour does not match what I expected a mock should be. Mock by my understanding is an object which behave like the original object, but easy to be control its behaviours. Specific for sequelize, the use case what my immediate understanding is to have all behaviours a sequelize has without hitting a real database. Which I dunno how to achieve with this repo. How do I attempt to have and have not result from findOne()
?
How can I be able to mock a SQL function without creating a model ?
Attempting to create a mock with a geometry field so that it can utilize geometry extensions in the tested module. The extension methods are not recognized as functions by the mock. Not sure if this is because I've declared my mocks incorrectly or because I am trying to access an extension method through a mocked object.
The extensions in question are only enabled through Docker containers. As a result, I had to set up a Docker container to host these Mocha tests.
my-test.js
const wkx = require("../common/wkxExt");
const SequelizeMock = require('sequelize-mock');
var DBConnectionMock = new SequelizeMock();
var ShapeMock = DBConnectionMock.define('shape', {
'name': 'testing',
'desc': 'a line from 0,1 to 10,1',
'geom': { type: SequelizeMock.GEOMETRY("GEOMETRYM", 4269) }
})
const proxyquire = require('proxyquire');
var MyModule = proxyquire('./my-module', {
'../common/models': ShapeMock
});
describe('Shape Tests', function () {
it("should run the task", function (done) {
var shapeGeo = wkx.Geometry.parse('0102000020AD100000020000000000000000000000000000000000F03F0000000000002440000000000000F03F', 'hex');
ShapeMock.$queueResult(ShapeMock.build({ geom: shapeGeo }));
MyModule.onRun().then(() => {
done();
})
});
});
my-module.js
const wkx = require("../common/wkxExt");
...
.then(theshape=> {
// .toGeos() is an extension declared in wkxExt for postgres geom fields
var shapeGeos = theshape.geom.toGeos();
})
TypeError: theshape.geom.toGeos is not a function, the value declared in the queueResult is visible.
The geom field is of type GEOMETRY and the associated extension methods are accessible.
delete this
When calling save()
it doesn't change the flag .options.isNewRecord
, making impossible to test if a model was correctly saved.
const user = TwitterAccountMock.build({});
expect(user.options.isNewRecord).to.be.true; //OK
user.save();
expect(user.options.isNewRecord).to.be.false; //Fails
this is my test.js using jest
jest.mock('../models/cartype', () => () => {
const SequelizeMock = require("sequelize-mock");
const dbMock = new SequelizeMock();
return dbMock.define('cartype', {
cartypename: 'check1'
})
});
this is my sequelize model which i am trying to mock
'use strict';
module.exports = (sequelize, DataTypes) => {
const cartype = sequelize.define('cartype', {
cartypename: {
type: DataTypes.STRING,
allowNull: false,
},
}, {});
cartype.associate = function(models) {
// associations can be defined here
cartype.hasMany(models.car, {
foreignKey: 'cartypeid',
as: 'cartypeid',
});
};
return cartype;
};
here is my decribe of jest
describe("Test Sequelize Mocking", () => {
it("Should get value from mock", async () => {
const cartype = await cartypeController.list();
expect(cartype.cartypename).toEqual('check1');
})
})
i am getting error as below while mocking with sequelize-mock
NODE_ENV=test jest
FAIL server/test/function.test.js
● Test suite failed to run
car.belongsTo called with something that's not a subclass of Sequelize.Model
32 | onDelete: 'CASCADE',
33 | }),
34 | car.belongsTo(models.cartype, {
| ^
35 | foreignKey: 'cartypeid',
36 | onDelete: 'CASCADE',
37 | }),
at Function. (node_modules/sequelize/lib/associations/mixin.js:93:13)
at Function.belongsTo (server/models/car.js:34:9)
at associate (server/models/index.js:30:19)
at Array.forEach ()
at Object.forEach (server/models/index.js:28:17)
at Object.require (server/controllers/cartypeController.js:1:17)
at Object.require (server/test/function.test.js:2:27)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 8.89s
Ran all test suites.
Note: This command was run via npm module 'win-node-env'
npm ERR! Test failed. See above for more details.
anyone able to help please do
Thanks in advance
this is my test.js using jest
jest.mock('../models/cartype', () => () => {
const SequelizeMock = require("sequelize-mock");
const dbMock = new SequelizeMock();
return dbMock.define('cartype', {
cartypename: 'check1'
})
});
this is my sequelize model which i am trying to mock
'use strict';
module.exports = (sequelize, DataTypes) => {
const cartype = sequelize.define('cartype', {
cartypename: {
type: DataTypes.STRING,
allowNull: false,
},
}, {});
cartype.associate = function(models) {
// associations can be defined here
cartype.hasMany(models.car, {
foreignKey: 'cartypeid',
as: 'cartypeid',
});
};
return cartype;
};
here is my decribe of jest
describe("Test Sequelize Mocking", () => {
it("Should get value from mock", async () => {
const cartype = await cartypeController.list();
expect(cartype.cartypename).toEqual('check1');
})
})
i am getting error as below while mocking with sequelize-mock
NODE_ENV=test jest
FAIL server/test/function.test.js
● Test suite failed to run
car.belongsTo called with something that's not a subclass of Sequelize.Model
32 | onDelete: 'CASCADE',
33 | }),
34 | car.belongsTo(models.cartype, {
| ^
35 | foreignKey: 'cartypeid',
36 | onDelete: 'CASCADE',
37 | }),
at Function. (node_modules/sequelize/lib/associations/mixin.js:93:13)
at Function.belongsTo (server/models/car.js:34:9)
at associate (server/models/index.js:30:19)
at Array.forEach ()
at Object.forEach (server/models/index.js:28:17)
at Object.require (server/controllers/cartypeController.js:1:17)
at Object.require (server/test/function.test.js:2:27)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 8.89s
Ran all test suites.
Note: This command was run via npm module 'win-node-env'
npm ERR! Test failed. See above for more details.
anyone able to help please do
Thanks in advance
Did see an example how to mock a raw query. I did see that you answered on #45 that it is possible. If I figure it out I will respond here with an example.
Sequelize 5.x removed findById and added findByPk can this be added to Sequelize mock?
I've overrided a .toJSON method on a certain model and it throws an error when used with this library.
Sequelize version: 4.4.2,
Here is the chunk of code in charge:
Page.prototype.toJSON = function toJSON() { ... };
Here is a link on Sequelize's docs that I've used
Am I doing something wrong?..
Thanks!
Associations are working well, but I notice another thing: when we write something like this:
userMock.findOne({where:{id:1},attributes:['name','username']})
we get a whole Sequelize model of user, so attributes doesn't work
This is a bug or so conceived?
hi,
i am trying to clear handlers in models but unable to do so.
when i checked the module files then found it's not bind in models
**this line should be added after line 190 in model.js**
this.$clearHandlers = this.$queryInterface.$clearHandlers.bind(this.$queryInterface);
Hi,
Mock-Sequelize doesn't seem to support the "include" property from Sequelize.
Here is an example of use :
const db = {};
// Creating a fake sector table
db.sector = dbMock.define(
'sector',
{
name: 'Test sector',
event_id: 1,
created_at: '2018-11-18 00:00:01',
updated_at: '2018-11-18 00:00:01',
deleted_at: null,
});
// Creating a fake event table
db.event = dbMock.define('event', {
name: 'Test event,
created_at: '2018-11-18 00:00:01',
updated_at: '2018-11-18 00:00:01',
deleted_at: null,
});
// Creating a relationship between sector and event
db.sector.belongsTo(db.event, { foreignKey: 'event_id' });
Above, I created two fake tables and now I want to get the event relative to a sector based on his id.
So I have three choices :
1- Get the event with the function sector.getEvent()
after getting my sector through a query.
2- Get the event through a query (like : event.findOne(... where: {id : sector.event_id}...)
)
3- Get the event through the property include
like this :
const sectorsQuery = {
where: {
id: params.id
},
include: [
{
model: db.event,
required: true,
}
]
};
const sector = await db.sector.findOne(sectorsQuery);
But the last one doesn't work with SequelizeMock and I don't know why...
Why does the include
property works well when I use Sequelize but not SequelizeMock ?
Do you have any functional examples of use ? for 1, N and N, M queries ?
Or this feature is not (yet) supported by SequelizeMock ?
Thank you.
I have a flow that looks like
return Party.create().then((party) => {
return PartyBudget.create({
type: input.budgetType || BUDGET_UNLIMITED
}).then(pb => {
return party.setBudget(pb)
})
})
in my tests, I am making sure that providing no input to the above produces a Party
with a PartyBudget
with an unlimited budget.
return graphql(schema, query, {}, state).then((result) => {
assert.equal(result.party.budget.type, BUDGET_UNLIMITED) // this doesn't work (type is null/undefined)
return Party.findById(result.party.id).then((party) => {
return party.getBudget().then((budget) => {
assert.equal(budget.type, BUDGET_UNLIMITED) // this doesn't work (type is null/undefined)
})
})
})
For reasons (mostly obfuscation), the default value isn't set at the model level.
It seems that sequelize-mock
creates a new instance instead of returning the associated object (in fact, setBudget
is a noop).
Am I SOL on this (i.e. beyond the scope of sequelize-mock
?)
In theory we should be able to design the mock API to support both v3 and v4. The number of breaking differences in the public API are small(-ish) from our perspective. The most complicated piece is definitely the Instance
being an actual instance of a Model
.
Problems to address:
Instance
is an instance of Model
. instance.Model
and model.Instance
were removedModel.validate
rejects on a validation issue, rather than return false
Hooks
use promises instead of callbacksThe Sequelize object is not mocked out very completely yet. It's got only a select few APIs actually mocked properly. Need to define all the functions that I'm able to mock in the core functionality.
API Calls Remaining
.getDialect
.getQueryInterface
.define
.model
.isDefined
.import
.query
.set
.escape
.createSchema
.showAllSchemas
.dropSchema
.dropAllSchemas
.sync
.truncate
.drop
.authenticate
.fn
.col
.cast
.literal
.and
.or
.json
.where
.transaction
Using the following code and I think there's an issue with the findOne() method because it saves over my table variable in my testing with Jest.
const SequelizeMock = require('sequelize-mock'); let dbMock = new SequelizeMock(); let UserMock = dbMock.define('test', { test: 'test', name: 'no' }
describe('Sequelize Model Testing',() => { test('testingggg', async () => { let user = await UserMock.findOne({ where: { name: 'amber' } }) expect(user.name).toBe('amber'); }) })
The expect user.name should be 'no' but its returning as 'amber'.
Hey there, love the simplicity and approach of this lib, thank you for writing it.
I just set it up and it works great within a minute or two, but I am confused about how I can mock an array of data (model.findAll) using this technique. Trying to keep my tests simple, but I do need to verify my report is querying a returning filtered arrays as expected.
Thanks again!
I'm using the count() method on a few of my models but it seems to be missing from the sequelize-mock API
See: http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-count
I'm trying to use this lib in my project but can't wrap my head around how exactly to integrate it. I'm using migrations so I have the auto-generated models/index.js
that is importing all Models.
Was trying to use $overrideImport
but don't know how ...
I really like the new queuing mechanism, but sometimes it falls a bit short in features. It would be nice if we can conditionally return results based on the result of a function. Example
mocks.TwitterAccount.$queueHandler(({where}) => {
if (where.userId === 1) return mocks.TwitterAccount.build({name:'User'});
else return null;
})
const user = await mocks.TwitterAccount.findOne({where:{ userId: 1 }});
const user2 = await mocks.TwitterAccount.findOne({where:{ userId: 2 }});
expect(user).to.exist;
expect(user2).to.be.null;
Not sure if the handler should be persistent (handle all future queries until $clearQueue()
is called) or a one-off handler. Maybe we could add a second parameter that indicates the number of queries it should handle?
// By default it handles one request
mocks.TwitterAccount.$queueHandler(myFunc);
// Handles 2 request
mocks.TwitterAccount.$queueHandler(myFunc, 2);
// Permanent handler
mocks.TwitterAccount.$queueHandler(myFunc, Infinity);
What do you think @ktsashes? I can start working on a PR if you are onboard with this change.
Had to manually add it
import Sequelize from 'sequelize'
import SequelizeMock from 'sequelize-mock'
const dbMock = new SequelizeMock()
dbMock.close = () => Promise.resolve() // sequelize-mock does not include a close mock
dbMock.QueryTypes = Sequelize.QueryTypes
Currently, instance methods work as advertised. When testing, we need to also test when the methods would fail: for example myMockInstance.update
could fail most possibly due to validation error(s).
How might we make instance methods throw an error?
Maybe call the underlying queryInterface
after performing the appropriate mocking magic?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.