Skip to content

Commit

Permalink
transform-plugins.js work right
Browse files Browse the repository at this point in the history
  • Loading branch information
futurist committed Dec 22, 2016
1 parent 753aa15 commit 4dd2079
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"plugins": ["./index"],
"plugins": ["./transform-plugins"],
"ignore": ["node_modules"]
}
48 changes: 38 additions & 10 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
const {expect} = require('chai')
const {transform} = require('babel-core')

describe('transform-plugins', () => {
var lib = function (code) {
return transform(code, {
plugins: ['./transform-plugins']
}).code
}

it('should transform plugins literal, should not transform non-literal', () => {
let node = `!{plugins: [{'default-unit-234': 'px'}, {selector: abc}]}`
expect(lib(node)).to.equal(`import cssobj_plugin_default_unit_234 from 'cssobj-plugin-default-unit-234';
!{ plugins: [cssobj_plugin_default_unit_234('px'), { selector: abc }] };`)

node = `!{plugins: [{'default-unit-234': 'px'}, {'localize': {space:'_my_'}}]}`
expect(lib(node)).to.equal(`import cssobj_plugin_localize from 'cssobj-plugin-localize';
import cssobj_plugin_default_unit_234 from 'cssobj-plugin-default-unit-234';
!{ plugins: [cssobj_plugin_default_unit_234('px'), cssobj_plugin_localize({ space: '_my_' })] };`)
})

it('should work with empty or non-plugins', () => {
let node = `!{plugins: null}`
expect(lib(node)).to.equal(`!{ plugins: null };`)
node = `!{plugins: []}`
expect(lib(node)).to.equal(`!{ plugins: [] };`)
node = `!{plugins: {abc: 'def'}}`
expect(lib(node)).to.equal(`!{ plugins: { abc: 'def' } };`)
})
})

describe('babel-plugin-transform-cssobj-jsx', () => {
var lib = function (code) {
return transform(code, {
Expand All @@ -9,32 +37,32 @@ describe('babel-plugin-transform-cssobj-jsx', () => {
}

it('should mapClass for string literal', () => {
const node = `var d= result.mapClass(<div className='a b c'><p class='abc' shouldNotMap='cde'>test</p></div>)`
let node = `var d= result.mapClass(<div className='a b c'><p class='abc' shouldNotMap='cde'>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={result.mapClass('a b c')}><p class={result.mapClass('abc')} shouldNotMap="cde">test</p></div>;`)
})

it('should mapClass for expression container', () => {
const node = `var d= result.mapClass(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
let node = `var d= result.mapClass(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={result.mapClass('a b c')}><p class={result.mapClass(getClass())}>test</p></div>;`)
})

it('should mapClass using complex cssobj result', () => {
const node = `var d= state.result().mapClass(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
let node = `var d= state.result().mapClass(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={state.result().mapClass('a b c')}><p class={state.result().mapClass(getClass())}>test</p></div>;`)
})

it('should not work with computed object', () => {
const node = `var d= result['mapClass'](<div className='a b c'><p class='abc'>test</p></div>)`
let node = `var d= result['mapClass'](<div className='a b c'><p class='abc'>test</p></div>)`
expect(lib(node)).to.equal(`var d = result['mapClass'](<div className="a b c"><p class="abc">test</p></div>);`)
})

it('should not work with non-member func call', () => {
const node = `var d= mapClass(<div className='a b c'><p class='abc'>test</p></div>)`
let node = `var d= mapClass(<div className='a b c'><p class='abc'>test</p></div>)`
expect(lib(node)).to.equal(`var d = mapClass(<div className="a b c"><p class="abc">test</p></div>);`)
})

it('should not work with non-jsx args', () => {
const node = `var d= result.mapClass('abc')`
let node = `var d= result.mapClass('abc')`
expect(lib(node)).to.equal(`var d = result.mapClass('abc');`)
})

Expand All @@ -48,22 +76,22 @@ describe('babel-plugin-transform-cssobj-jsx with mapName option', () => {
}).code
}
it('should mapClass for string literal', () => {
const node = `var d= result.makeLocal(<div className='a b c'><p class='abc'>test</p></div>)`
let node = `var d= result.makeLocal(<div className='a b c'><p class='abc'>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={result.mapClass('a b c')}><p class={result.mapClass('abc')}>test</p></div>;`)
})

it('should mapClass for expression container', () => {
const node = `var d= result.makeLocal(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
let node = `var d= result.makeLocal(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={result.mapClass('a b c')}><p class={result.mapClass(getClass())}>test</p></div>;`)
})

it('should mapClass using complex cssobj result', () => {
const node = `var d= state.result().makeLocal(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
let node = `var d= state.result().makeLocal(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={state.result().mapClass('a b c')}><p class={state.result().mapClass(getClass())}>test</p></div>;`)
})

it('should accept makeLocal only, without result', () => {
const node = `var d= makeLocal(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
let node = `var d= makeLocal(<div className={'a b c'}><p class={getClass()}>test</p></div>)`
expect(lib(node)).to.equal(`var d = <div className={makeLocal('a b c')}><p class={makeLocal(getClass())}>test</p></div>;`)
})
})
48 changes: 48 additions & 0 deletions transform-plugins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module.exports = function (babel) {
var t = babel.types

return {
visitor: {
Program (path) {
var firstExp = path.node.body[0]
if(!t.isExpressionStatement(firstExp)
|| !t.isUnaryExpression(firstExp.expression, {operator: '!'})
|| !t.isObjectExpression(firstExp.expression.argument)) return
// get target expression
var node = firstExp.expression.argument
// get plugins prop
var pluginsNode = node.properties.filter(function(v) {
return t.isIdentifier(v.key, {name: 'plugins'})
&& t.isArrayExpression(v.value)
}).shift()
if(!pluginsNode) return
// only transform literal keys with plugin names
var elements = pluginsNode.value.elements
for (var v, i = 0; i < elements.length; i++) {
v = elements[i]
if (t.isObjectExpression(v)
&& v.properties.length == 1
&& t.isLiteral(v.properties[0].key)
// plugin name cannot be below keywords
&& ['selector', 'value', 'post'].indexOf(v.properties[0].key.value) < 0) {
var prop = v.properties[0].key.value
var pluginIden = 'cssobj_plugin_' + prop.replace(/-/g, '_')
var value = v.properties[0].value
elements[i] = t.callExpression(
t.identifier(pluginIden),
value ? [value] : []
)
path.unshiftContainer(
'body',
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(pluginIden))],
t.stringLiteral('cssobj-plugin-'+prop)
)
)
}
}

}
}
}
}

0 comments on commit 4dd2079

Please sign in to comment.