Skip to content

Commit

Permalink
refactor: remove util functions
Browse files Browse the repository at this point in the history
`extend` is just `Object.assign` or object spread. `hasOwnProp` is easy to just inline. This also modernizes the style a bit using more modern syntax.
  • Loading branch information
eventualbuddha committed Sep 24, 2020
1 parent 99d2a4a commit d8398d4
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 1,308 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"extends": ["eslint:recommended", "prettier"],
"plugins": ["jest"],
"parserOptions": {
"ecmaVersion": 2015
"ecmaVersion": 2018
},
"overrides": [
{
Expand Down
14 changes: 7 additions & 7 deletions src/__tests__/rosie.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('Factory', () => {
describe('with a normal constructor', () => {
class Thing {
constructor(attrs) {
for (var attr in attrs) {
for (let attr in attrs) {
this[attr] = attrs[attr];
}
}
Expand Down Expand Up @@ -142,30 +142,30 @@ describe('Factory', () => {

it('should return array of objects with default attributes', () => {
const things = Factory.buildList('thing', 10);
for (var i = 0; i < 10; i++) {
for (let i = 0; i < 10; i++) {
expect(things[i]).toEqual({ name: 'Thing 1' });
}
});

it('should return array of objects with specified attributes', () => {
const things = Factory.buildList('thing', 10, { name: 'changed' });
for (var i = 0; i < 10; i++) {
for (let i = 0; i < 10; i++) {
expect(things[i]).toEqual({ name: 'changed' });
}
});

it('should return an array of objects with a sequence', () => {
Factory.define('thing').sequence('id');
const things = Factory.buildList('thing', 4);
for (var i = 0; i < 4; i++) {
for (let i = 0; i < 4; i++) {
expect(things[i]).toEqual({ id: i + 1 });
}
});

it('should return an array of objects with a sequence and with specified attributes', () => {
Factory.define('thing').sequence('id').attr('name', 'Thing 1');
const things = Factory.buildList('thing', 4, { name: 'changed' });
for (var i = 0; i < 4; i++) {
for (let i = 0; i < 4; i++) {
expect(things[i]).toEqual({ id: i + 1, name: 'changed' });
}
});
Expand Down Expand Up @@ -230,14 +230,14 @@ describe('Factory', () => {
describe('extend', () => {
class Thing {
constructor(attrs) {
for (var attr in attrs) {
for (let attr in attrs) {
this[attr] = attrs[attr];
}
}
}
class Thingy {
constructor(attrs) {
for (var attr in attrs) {
for (let attr in attrs) {
this[attr] = attrs[attr];
}
}
Expand Down
151 changes: 45 additions & 106 deletions src/rosie.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,13 @@ class Factory {
* @return {Factory}
*/
attr(attr, dependencies, value) {
var builder;
let builder;
if (arguments.length === 2) {
value = dependencies;
dependencies = null;
}

builder =
typeof value === 'function'
? value
: function () {
return value;
};
builder = typeof value === 'function' ? value : () => value;
this._attrs[attr] = { dependencies: dependencies || [], builder: builder };
return this;
}
Expand All @@ -87,8 +82,8 @@ class Factory {
* @return {Factory}
*/
attrs(attributes) {
for (var attr in attributes) {
if (Factory.util.hasOwnProp(attributes, attr)) {
for (let attr in attributes) {
if (Object.prototype.hasOwnProperty.call(attributes, attr)) {
this.attr(attr, attributes[attr]);
}
}
Expand Down Expand Up @@ -124,20 +119,15 @@ class Factory {
* @return {Factory}
*/
option(opt, dependencies, value) {
var builder;
let builder;
if (arguments.length === 2) {
value = dependencies;
dependencies = null;
}
if (arguments.length > 1) {
builder =
typeof value === 'function'
? value
: function () {
return value;
};
builder = typeof value === 'function' ? value : () => value;
}
this.opts[opt] = { dependencies: dependencies || [], builder: builder };
this.opts[opt] = { dependencies: dependencies || [], builder };
return this;
}

Expand All @@ -159,23 +149,15 @@ class Factory {
* @return {Factory}
*/
sequence(attr, dependencies, builder) {
var factory = this;

if (arguments.length === 2) {
builder = /** @type function(number): * */ dependencies;
dependencies = null;
}
builder =
builder ||
function (i) {
return i;
};
return this.attr(attr, dependencies, function () {
var args = [].slice.call(arguments);

factory.sequences[attr] = factory.sequences[attr] || 0;
args.unshift(++factory.sequences[attr]);
return builder.apply(null, args);
builder = builder || ((i) => i);
return this.attr(attr, dependencies, (...args) => {
this.sequences[attr] = this.sequences[attr] || 0;
args.unshift(++this.sequences[attr]);
return builder(...args);
});
}

Expand All @@ -202,9 +184,9 @@ class Factory {
* @return {object}
*/
attributes(attributes, options) {
attributes = Factory.util.extend({}, attributes);
attributes = { ...attributes };
options = this.options(options);
for (var attr in this._attrs) {
for (let attr in this._attrs) {
this._attrValue(attr, attributes, options, [attr]);
}
return attributes;
Expand All @@ -224,13 +206,13 @@ class Factory {
_attrValue(attr, attributes, options, stack) {
if (
!this._alwaysCallBuilder(attr) &&
Factory.util.hasOwnProp(attributes, attr)
Object.prototype.hasOwnProperty.call(attributes, attr)
) {
return attributes[attr];
}

var value = this._buildWithDependencies(this._attrs[attr], function (dep) {
if (Factory.util.hasOwnProp(options, dep)) {
const value = this._buildWithDependencies(this._attrs[attr], (dep) => {
if (Object.prototype.hasOwnProperty.call(options, dep)) {
return options[dep];
} else if (dep === attr) {
return attributes[dep];
Expand All @@ -255,7 +237,7 @@ class Factory {
* @return {boolean}
*/
_alwaysCallBuilder(attr) {
var attrMeta = this._attrs[attr];
const attrMeta = this._attrs[attr];
return attrMeta.dependencies.indexOf(attr) >= 0;
}

Expand All @@ -266,9 +248,9 @@ class Factory {
* @param {?object} options
* @return {object}
*/
options(options) {
options = Factory.util.extend({}, options || {});
for (var opt in this.opts) {
options(options = {}) {
options = { ...options };
for (let opt in this.opts) {
options[opt] = this._optionValue(opt, options);
}
return options;
Expand All @@ -284,20 +266,20 @@ class Factory {
* @return {*}
*/
_optionValue(opt, options) {
if (Factory.util.hasOwnProp(options, opt)) {
if (Object.prototype.hasOwnProperty.call(options, opt)) {
return options[opt];
}

var optMeta = this.opts[opt];
const optMeta = this.opts[opt];
if (!optMeta.builder) {
throw new Error(
'option `' + opt + '` has no default value and none was provided'
);
}

return this._buildWithDependencies(optMeta, function (dep) {
return this._optionValue(dep, options);
});
return this._buildWithDependencies(optMeta, (dep) =>
this._optionValue(dep, options)
);
}

/**
Expand All @@ -310,11 +292,8 @@ class Factory {
* @return {*}
*/
_buildWithDependencies(meta, getDep) {
var deps = meta.dependencies;
var self = this;
var args = deps.map(function () {
return getDep.apply(self, arguments);
});
const deps = meta.dependencies;
const args = deps.map((...args) => getDep.apply(this, args));
return meta.builder.apply(this, args);
}

Expand All @@ -327,26 +306,26 @@ class Factory {
* @return {*}
*/
build(attributes, options) {
var result = this.attributes(attributes, options);
var retval = null;
const result = this.attributes(attributes, options);
let retval = null;

if (this.construct) {
var Constructor = this.construct;
const Constructor = this.construct;
retval = new Constructor(result);
} else {
retval = result;
}

for (var i = 0; i < this.callbacks.length; i++) {
var callbackResult = this.callbacks[i](retval, this.options(options));
for (let i = 0; i < this.callbacks.length; i++) {
const callbackResult = this.callbacks[i](retval, this.options(options));
retval = callbackResult || retval;
}
return retval;
}

buildList(size, attributes, options) {
var objs = [];
for (var i = 0; i < size; i++) {
const objs = [];
for (let i = 0; i < size; i++) {
objs.push(this.build(attributes, options));
}
return objs;
Expand All @@ -361,59 +340,19 @@ class Factory {
* @return {Factory}
*/
extend(name) {
var factory = typeof name === 'string' ? Factory.factories[name] : name;
const factory = typeof name === 'string' ? Factory.factories[name] : name;
// Copy the parent's constructor
if (this.construct === undefined) {
this.construct = factory.construct;
}
Factory.util.extend(this._attrs, factory._attrs);
Factory.util.extend(this.opts, factory.opts);
Object.assign(this._attrs, factory._attrs);
Object.assign(this.opts, factory.opts);
// Copy the parent's callbacks
this.callbacks = factory.callbacks.slice();
return this;
}
}

/**
* @private
*/
Factory.util = (function () {
var hasOwnProp = Object.prototype.hasOwnProperty;

return {
/**
* Determines whether `object` has its own property named `prop`.
*
* @private
* @param {object} object
* @param {string} prop
* @return {boolean}
*/
hasOwnProp: function (object, prop) {
return hasOwnProp.call(object, prop);
},

/**
* Extends `dest` with all of own properties of `source`.
*
* @private
* @param {object} dest
* @param {object=} source
* @return {object}
*/
extend: function (dest, source) {
if (source) {
for (var key in source) {
if (hasOwnProp.call(source, key)) {
dest[key] = source[key];
}
}
}
return dest;
},
};
})();

Factory.factories = {};

/**
Expand All @@ -425,7 +364,7 @@ Factory.factories = {};
* @return {Factory}
*/
Factory.define = function (name, constructor) {
var factory = new Factory(constructor);
const factory = new Factory(constructor);
this.factories[name] = factory;
return factory;
};
Expand All @@ -440,7 +379,7 @@ Factory.define = function (name, constructor) {
*/
Factory.build = function (name, attributes, options) {
if (!this.factories[name]) {
throw new Error('The "' + name + '" factory is not defined.');
throw new Error(`The "${name}" factory is not defined.`);
}
return this.factories[name].build(attributes, options);
};
Expand All @@ -455,8 +394,8 @@ Factory.build = function (name, attributes, options) {
* @return {Array.<*>}
*/
Factory.buildList = function (name, size, attributes, options) {
var objs = [];
for (var i = 0; i < size; i++) {
const objs = [];
for (let i = 0; i < size; i++) {
objs.push(Factory.build(name, attributes, options));
}
return objs;
Expand All @@ -480,9 +419,9 @@ if (typeof exports === 'object' && typeof module !== 'undefined') {
/* eslint-env commonjs:false */
} else if (typeof define === 'function' && define.amd) {
/* eslint-env amd */
define([], function () {
return { Factory: Factory };
});
define([], () => ({
Factory: Factory,
}));
/* eslint-env amd:false */
} else if (this) {
this.Factory = Factory;
Expand Down
Loading

0 comments on commit d8398d4

Please sign in to comment.