Skip to content
Permalink
Browse files

feat: data mocking

  • Loading branch information
runspired committed Dec 16, 2019
1 parent 31fded5 commit 29404347955d2171d50222cd24c10f08f21e1d00
@@ -4,6 +4,11 @@
/dist/
/tmp/

/public/fixtures/
/app/models/
/app/serializers/
/app/adapters/

# dependencies
/bower_components/
/node_modules/
@@ -2,7 +2,11 @@
<h3>{{@item.text}}</h3>
<ol>
{{#each @item.facets as |facet|}}
<li>{{facet.description}}</li>
<li>
<strong>{{facet.fieldName}}:</strong>
<em>{{get facet facet.fieldName}}</em>
<p>{{facet.description}}</p>
</li>
{{/each}}
</ol>
</item>
@@ -1,10 +1,11 @@
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
import EmberRouter from "@ember/routing/router";
import config from "./config/environment";

export default class Router extends EmberRouter {
location = config.locationType;
rootURL = config.rootURL;
}

Router.map(function() {
this.route("lists", { path: "/" });
});
@@ -1,25 +1,17 @@
import Route from "@ember/routing/route";
import { inject } from '@ember/service';
import { all } from "rsvp";

export default class ListsRoute extends Route {
@inject store;

/*
async model() {
const { store } = this;
let promises = [];
// fetch 50 lists
// fetch all 200 lists
// each list will have 10 items
// each item will include 3 related items
// for a total of 500 item records + 50 list records + 1500 related items
for (let i = 1; i <= 50; i++) {
for (let i = 1; i <= 200; i++) {
promises.push(store.findRecord("list", `list:${i}`));
}
return await all(promises);
}
*/
model() {
return this.store.findAll('list');
}
}
@@ -0,0 +1,9 @@
module.exports = {
NUM_LISTS: 200,
ITEMS_PER_LIST: 20, // 4000 items total
FACETS_PER_ITEM: 5, // 20000 facets total
GENERATE_ADAPTER: true,
GENERATE_MODEL: true,
GENERATE_SERIALIZER: true,
COMPRESS_FILES: false
};
@@ -0,0 +1,13 @@
const writeFile = require('../utils/write-file');

module.exports = function generateAdapter(type, KlassName) {
let Adapter = `import JSONAPIAdapter from "@ember-data/adapter/json-api";
export default class ${KlassName}Adapter extends JSONAPIAdapter {
urlForFindRecord(id, type) {
return \`./fixtures/\${type}_\${id}.json\`;
}
}
`;
writeFile(`./app/adapters/${type}.js`, Adapter, false);
}
@@ -0,0 +1,17 @@
const faker = require('faker');

module.exports = function makeAuthor(listRef, listIndex) {
return {
type: 'author',
id: `author:${listIndex}`,
attributes: {
name: faker.name.findName(),
profileImageSrc: faker.image.imageUrl()
},
relationships: {
lists: {
data: [listRef]
}
}
}
}
@@ -0,0 +1,68 @@
const LoremIpsum = require("lorem-ipsum").LoremIpsum;

const Alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"];
const lorem = new LoremIpsum();
const invalidFieldNames = [
'id',
'currentState',
'_internalModel',
'for',
'in',
'of',
'class',
'function',
'let',
'var',
'const',
'import',
'export',
'default',
'Set',
'Map',
'WeakMap',
'interface',
'type',
'fieldName',
'description',
'item',
'do',
'while'
];


let FieldNames = {};
function getFieldName(facetType) {
if (FieldNames[facetType]) {
return FieldNames[facetType];
}
let fieldName = lorem.generateWords(1);
while(invalidFieldNames.indexOf(fieldName) !== -1) {
fieldName = lorem.generateWords(1);
}
FieldNames[facetType] = fieldName;
return fieldName;
}


module.exports = function generateFacet(itemRef, typeCount, idIndex) {
let alphaNum = Alphabet[idIndex - 1];
let facetType = `facet${typeCount.toString(16)}m`;
let fieldName = getFieldName(facetType);

let facet = {
type: facetType,
id: `${facetType}:${alphaNum}`,
attributes: {
description: lorem.generateSentences(1),
fieldName,
[fieldName]: lorem.generateWords(3)
},
relationships: {
item: {
data: itemRef
}
}
};

return facet;
}
@@ -0,0 +1,31 @@
const LoremIpsum = require("lorem-ipsum").LoremIpsum;

const lorem = new LoremIpsum({
wordsPerSentence: {
max: 12,
min: 8
}
});

module.exports = function generateItem(listRef, listIndex, itemInList) {
let data = {
type: "item",
id: `item:${listIndex}:${itemInList}`,
attributes: {
text: lorem.generateSentences(3)
},
relationships: {
facets: {
data: []
},
list: {
data: listRef
}
}
};

return {
data,
included: []
};
}
@@ -0,0 +1,35 @@
const generateAuthorFixture = require('./author-fixture');
const LoremIpsum = require("lorem-ipsum").LoremIpsum;

const lorem = new LoremIpsum({
wordsPerSentence: {
max: 12,
min: 8
}
});

module.exports = function generateList(i) {
let data = {
type: "list",
id: `list:${i}`,
attributes: {
title: lorem.generateSentences(1)
},
relationships: {
author: {},
items: {
data: []
}
}
};
let payload = {
data,
included: []
};

let author = generateAuthorFixture({ type: data.type, id: data.id }, i);
payload.included.push(author);
data.relationships.author.data = { type: author.type, id: author.id };

return payload;
}
@@ -0,0 +1,75 @@
const writeFile = require('../utils/write-file');

function getRelatedType(propertyName) {
switch (propertyName) {
case "item":
case "items":
return "item";
case "facets":
return "facet";
case "list":
case "lists":
return "list";
case 'author':
return 'author';
default:
return "facet";
}
}


module.exports = function generateModel(schema, KlassName) {
let attrs = Object.keys(schema.attributes).map(attr => {
return `@attr ${attr};`;
});
let rels = Object.keys(schema.relationships);
let imports = [];

if (attrs.length) {
imports.push("attr");
}
let has_belongsTo = false;
let has_hasMany = false;
let extendsFacet = schema.type.startsWith("facet") && schema.type !== "facet";
let rDefs = [];
rels.forEach(r => {
if (!Array.isArray(schema.relationships[r].data)) {
if (!extendsFacet || r !== "item") {
has_belongsTo = true;
rDefs.push(
`@belongsTo('${getRelatedType(r)}', { inverse: '${
schema.type
}s', async: true, polymorphic: ${r.startsWith("facet")} })\n ${r};`
);
}
} else {
has_hasMany = true;
rDefs.push(
`@hasMany('${getRelatedType(r)}', { inverse: '${
schema.type
}', async: true, polymorphic: ${r.startsWith("facet")} })\n ${r};`
);
}
});
if (has_belongsTo) {
imports.push("belongsTo");
}
if (has_hasMany) {
imports.push("hasMany");
}
let ExtendedKlass = extendsFacet ? "Facet" : "Model";

let lines = [
`import ${extendsFacet ? "" : "Model, "}{ ${imports.join(
", "
)} } from '@ember-data/model';`,
`${extendsFacet ? "import Facet from './facet';\n" : ""}`,
`export default class ${KlassName} extends ${ExtendedKlass} {`,
` ${attrs.join("\n ")}`,
` ${rDefs.join("\n ")}`,
"}"
];
let Model = lines.join("\n");

writeFile(`./app/models/${schema.type}.js`, Model, false);
}
@@ -0,0 +1,11 @@
const writeFile = require('../utils/write-file');

module.exports = function generateSerializer(type, KlassName) {
let Serializer = `import JSONAPISerializer from "@ember-data/serializer/json-api";
export default class ${KlassName}Serializer extends JSONAPISerializer {
keyForAttribute(key) { return key; }
}
`;
writeFile(`./app/serializers/${type}.js`, Serializer, false);
}
@@ -0,0 +1,31 @@
const config = require('./config');
const baseSchemas = require('./utils/base-schemas');
const generateClassesForSchema = require('./utils/classes-for-schema');
const makeItemsForList = require('./utils/make-items-for-list');
const generateListFixture = require('./generators/list-fixture');
const writeFile = require('./utils/write-file');

generateClassesForSchema(baseSchemas.AuthorSchema);
generateClassesForSchema(baseSchemas.ListSchema);
generateClassesForSchema(baseSchemas.ItemSchema);
generateClassesForSchema(baseSchemas.FacetSchema);

let payloads = [];
for (let i = 1; i <= config.NUM_LISTS; i++) {
let payload = generateListFixture(i);
makeItemsForList(payload, i);

writeFile(`./public/fixtures/list_${payload.data.id}.json`, payload, true);
payloads.push(payload);
}

let allPayload = {
data: [],
included: []
}
payloads.forEach(p => {
allPayload.data.push(p.data);
allPayload.included.push(...p.included);
});

writeFile(`./public/fixtures/list.json`, allPayload, true);

0 comments on commit 2940434

Please sign in to comment.
You can’t perform that action at this time.