Skip to content

Instantly share code, notes, and snippets.

@Turbo87
Last active April 7, 2016 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Turbo87/fc8bc57def947d2eae8526964c2c9f02 to your computer and use it in GitHub Desktop.
Save Turbo87/fc8bc57def947d2eae8526964c2c9f02 to your computer and use it in GitHub Desktop.
export default function transformer(file, api) {
const j = api.jscodeshift;
const {expression, statement, statements} = j.template;
function argsArray(p) {
return j.variableDeclaration('var', [
j.variableDeclarator(
j.identifier('args'),
p.node.argument.arguments[0]
)
]);
}
function converted(p) {
return j.returnStatement(
j.callExpression(
j.memberExpression(
emberNew(p),
j.identifier('then')
), [
j.arrowFunctionExpression(
[],
j.callExpression(
j.identifier('emberGenerateDestroy'), [
j.identifier('args'),
j.arrowFunctionExpression(
[j.identifier('_file')],
j.blockStatement(assertions(p))
)
]
)
)
]
)
);
}
function emberNew(p) {
var props = p.node.argument.arguments[1].properties;
var expression = j.callExpression(
j.identifier('emberNew'), emberNewArguments(props)
);
expression = modifyPackages(expression, props);
expression = setupPodConfig(expression, props);
return expression;
}
function emberNewArguments(props) {
var targetProp = props.filter(n => n.key.name === 'target')[0];
if (!targetProp)
return [];
var target = targetProp.value.value;
if (target === 'inRepoAddon')
target = 'in-repo-addon';
return [j.objectExpression([
j.property('init', j.identifier('target'), j.literal(target))
])];
}
function modifyPackages(n, props) {
var packagesProp = props.filter(n => n.key.name === 'packages')[0];
if (!packagesProp)
return n;
return j.callExpression(
j.memberExpression(n, j.identifier('then')),
[j.arrowFunctionExpression([],
j.callExpression(
j.identifier('modifyPackages'), [packagesProp.value]
)
)]
);
}
function setupPodConfig(n, props) {
var usePodsProp = props.filter(n => n.key.name === 'usePods')[0];
var podModulePrefixProp = props.filter(n => n.key.name === 'podModulePrefix')[0];
if (!usePodsProp && !podModulePrefixProp)
return n;
var properties = [];
if (usePodsProp) {
properties.push(usePodsProp);
}
if (podModulePrefixProp) {
properties.push(podModulePrefixProp);
}
return j.callExpression(
j.memberExpression(n, j.identifier('then')),
[j.arrowFunctionExpression([],
j.callExpression(
j.identifier('setupPodConfig'),
[j.objectExpression(properties)]
)
)]
);
}
function assertions(p) {
var props = p.node.argument.arguments[1].properties;
var filesProp = props.filter(n => n.key.name === 'files')[0];
if (!filesProp)
return [];
var files = filesProp.value.elements;
return files.map(assertionsForFile);
}
function assertionsForFile(f) {
var file = f.properties.filter(n => n.key.name === 'file')[0].value;
var existsProp = f.properties.filter(n => n.key.name === 'exists')[0];
var isEmptyProp = f.properties.filter(n => n.key.name === 'isEmpty')[0];
var containsProp = f.properties.filter(n => n.key.name === 'contains')[0];
var doesNotContainProp = f.properties.filter(n => n.key.name === 'doesNotContain')[0];
var expression = j.callExpression(
j.identifier('expect'),
[j.callExpression(j.identifier('_file'), [file])]
);
if (existsProp) {
let value = existsProp.value.raw;
if (value === 'false') {
expression = toNotExist(expression)
} else if (value === 'true') {
expression = toExist(expression)
}
}
if (isEmptyProp) {
let value = isEmptyProp.value.raw;
if (value === 'false') {
expression = toNotBeEmpty(expression)
} else if (value === 'true') {
expression = toBeEmpty(expression)
}
}
if (containsProp) {
if (containsProp.value.type !== 'ArrayExpression') {
expression = toContain(expression, containsProp.value);
} else {
let values = containsProp.value.elements;
values.forEach(value => {
expression = toContain(expression, value);
})
}
}
if (doesNotContainProp) {
if (doesNotContainProp.value.type !== 'ArrayExpression') {
expression = toNotContain(expression, doesNotContainProp.value);
} else {
let values = doesNotContainProp.value.elements;
values.forEach(value => {
expression = toNotContain(expression, value);
})
}
}
return j.expressionStatement(expression);
}
function to(n) {
return j.memberExpression(n, j.identifier('to'));
}
function be(n) {
return j.memberExpression(n, j.identifier('be'));
}
function not(n) {
return j.memberExpression(n, j.identifier('not'));
}
function toNot(n) {
return not(to(n));
}
function exist(n) {
return j.memberExpression(n, j.identifier('exist'));
}
function toExist(n) {
return exist(to(n));
}
function toNotExist(n) {
return exist(toNot(n));
}
function empty(n) {
return j.memberExpression(n, j.identifier('empty'));
}
function toBeEmpty(n) {
return empty(be(to(n)));
}
function toNotBeEmpty(n) {
return empty(be(toNot(n)));
}
function contain(n, v) {
return j.callExpression(
j.memberExpression(n, j.identifier('contain')),
[v]
);
}
function toContain(n, v) {
return contain(to(n), v);
}
function toNotContain(n, v) {
return contain(toNot(n), v);
}
return j(file.source)
.find(j.ReturnStatement, { argument: { callee: { name: 'generateAndDestroy' }}})
.insertBefore(argsArray)
.replaceWith(converted)
.toSource({quote: 'single'});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment