Skip to content

Commit

Permalink
feat(css): Allow independent css builds
Browse files Browse the repository at this point in the history
- move a lot of logic from bin/mastarm into a util file to allow testing
- add test case for build script
- add tests for util functions
  • Loading branch information
evansiroky committed Sep 30, 2016
1 parent 4edf0b2 commit 6314bb9
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 50 deletions.
58 changes: 9 additions & 49 deletions bin/mastarm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const commander = require('commander')
const path = require('path')

const loadConfig = require('../lib/load-config')
const pkg = require('../lib/pkg')
const util = require('../lib/util')

commander
.version(require('../package.json').version)
Expand All @@ -20,11 +20,13 @@ commander
.option('-p, --proxy <address>', 'Proxy calls through to target address.')
.option('-s, --serve', 'Serve with budo. Auto-matically rebuilds on changes.')
.option('-w, --watch', 'Rebuild on changes with watchify.')
.option('--no-css', 'Do not build using default css options')
.option('--css-files <files>', 'Specify custom css files to build')
.action(function (entries, options) {
checkDependencies()
const config = loadConfig(process.cwd(), commander.config, commander.env)
const get = (item) => val([options, commander, config.settings], item)
const files = parseEntries(entries, get)
const get = util.makeGetFn([options, commander, config.settings])
const files = util.parseEntries(entries.concat(util.getCssFiles(options)), get)
if (get('serve')) {
const budo = require('../lib/budo')
files.map(budo({
Expand All @@ -47,7 +49,7 @@ commander
.command('commit')
.description('Force intelligent commit messages.')
.action(function () {
popMastarmFromArgv()
util.popMastarmFromArgv()
const path = require('path')
const bootstrap = require('commitizen/dist/cli/git-cz').bootstrap
bootstrap({
Expand All @@ -67,8 +69,8 @@ commander
checkDependencies()
const pushToS3 = require('../lib/push-to-s3')
const config = loadConfig(process.cwd(), commander.config, commander.env)
const get = (item) => val([options, commander, config.settings], item)
const files = parseEntries(entries, get)
const get = util.makeGetFn([options, commander, config.settings])
const files = util.parseEntries(entries, get)
files.map(pushToS3({
cloudfront: get('cloudfront'),
config,
Expand Down Expand Up @@ -164,48 +166,6 @@ commander.parse(process.argv)

function checkDependencies () {
if (!commander.skipCheckDependencies) {
const checkDependenciesSync = require('check-dependencies').sync
const results = checkDependenciesSync({
install: true,
packageDir: process.cwd()
})
if (results.status !== 0) {
console.error(results.error)
process.exit(results.status)
} else if (!results.depsWereOk) {
console.log('Updated out of date dependencies found in package.json. Please try running the command again.')
process.exit(results.status)
}
util.updateDependencies()
}
}

function parseEntries (entries, get) {
const files = entries.map((entry) => {
entry = entry.split(':')
if (entry.length === 1) {
entry.push(`assets/${entry[0]}`)
}
return entry
})

if (files.length === 0) {
files.push([
get('entry') || pkg.main || 'index.js',
get('outfile') || 'assets/index.js'
])
}

return files
}

/**
* A lot of subcommands utilize exact argument lengths. Pop mastarm to handle it.
*/
function popMastarmFromArgv () {
process.argv = process.argv.slice(0, 1).concat(process.argv.slice(2))
}

function val (targets, i) {
const ts = targets.filter((t) => t[i] !== undefined)
if (ts.length > 0) return ts[0][i]
}
61 changes: 61 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const pkg = require('../lib/pkg')

exports.getCssFiles = (options) => {
let files = []
if (options.css) {
if (options.cssFiles) {
files = files.concat(options.cssFiles.split(' '))
} else {
files.push('lib/styles.css:assets/index.css')
}
}
return files
}

exports.makeGetFn = (targets) => {
return (item) => {
const ts = targets.filter((t) => t[item] !== undefined)
if (ts.length > 0) return ts[0][item]
}
}

exports.parseEntries = function (entries, get) {
const files = entries.map((entry) => {
entry = entry.split(':')
if (entry.length === 1) {
entry.push(`assets/${entry[0]}`)
}
return entry
})

if (files.length === 0) {
files.push([
get('entry') || pkg.main || 'index.js',
get('outfile') || 'assets/index.js'
])
}

return files
}

/**
* A lot of subcommands utilize exact argument lengths. Pop mastarm to handle it.
*/
exports.popMastarmFromArgv = function () {
process.argv = process.argv.slice(0, 1).concat(process.argv.slice(2))
}

exports.updateDependencies = function () {
const checkDependenciesSync = require('check-dependencies').sync
const results = checkDependenciesSync({
install: true,
packageDir: process.cwd()
})
if (results.status !== 0) {
console.error(results.error)
process.exit(results.status)
} else if (!results.depsWereOk) {
console.log('Updated out of date dependencies found in package.json. Please try running the command again.')
process.exit(results.status)
}
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"yamljs": "^0.2.8"
},
"devDependencies": {
"async-each": "^1.0.1",
"rimraf": "^2.5.4",
"semantic-release": "^4.3.5"
}
}
37 changes: 36 additions & 1 deletion tests/bin/mastarm.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
/* globals describe, it, expect */
/* globals afterEach, beforeEach, describe, it, expect */

const exec = require('child_process').exec
const fs = require('fs')
const path = require('path')

const each = require('async-each')
const rimraf = require('rimraf')

const mastarm = path.resolve('./bin/mastarm')

describe('mastarm cli', () => {
Expand All @@ -15,6 +19,37 @@ describe('mastarm cli', () => {
})
})

describe('build', function () {
const clean = (done) => {
rimraf('tests/mocks/built.*', done)
}

beforeEach(clean)
afterEach(clean)

it('should build a project', (done) => {
exec(`node ${mastarm} build tests/mocks/mockComponent.js:tests/mocks/built.js --css-files tests/mocks/mock.css:tests/mocks/built.css`,
(err, stdout, stderr) => {
expect(err).toBeNull()
expect(stdout).toBe('')
expect(stderr).toBe('')
each(['tests/mocks/built.js', 'tests/mocks/built.css'],
(file, cb) => {
fs.stat(file, (err, data) => {
if (err) { return cb(err) }
cb()
})
},
(err) => {
expect(err).not.toBeTruthy()
done()
}
)
}
)
})
})

it('should run lint on a project', (done) => {
exec(`node ${mastarm} lint`, (err, stdout, stderr) => {
expect(err).toBeNull()
Expand Down
36 changes: 36 additions & 0 deletions tests/lib/__snapshots__/util.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
exports[`util.js getCssFiles should return correct results 1`] = `Array []`;

exports[`util.js getCssFiles should return correct results 2`] = `
Array [
"lib/styles.css:assets/index.css"
]
`;

exports[`util.js getCssFiles should return correct results 3`] = `
Array [
"a:b",
"c"
]
`;

exports[`util.js parseEntries should return default file paths 1`] = `
Array [
Array [
"bin/mastarm",
"assets/index.js"
]
]
`;

exports[`util.js parseEntries should return inputted file paths 1`] = `
Array [
Array [
"a",
"b"
],
Array [
"c",
"assets/c"
]
]
`;
42 changes: 42 additions & 0 deletions tests/lib/util.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* globals describe, expect, it, jest */

const mockSyncFn = jest.fn(() => { return { status: 0, depsWereOk: true } })
jest.mock('check-dependencies', () => { return { sync: mockSyncFn } })

const util = require('../../lib/util')

describe('util.js', () => {
describe('getCssFiles', () => {
it('should return correct results', () => {
expect(util.getCssFiles({ css: false })).toMatchSnapshot()
expect(util.getCssFiles({ css: true })).toMatchSnapshot()
expect(util.getCssFiles({ css: true, cssFiles: 'a:b c' })).toMatchSnapshot()
})
})

it('makeGetFn should find the right value', () => {
expect(util.makeGetFn([{ a: 1 }, { a: 2 }])('a')).toEqual(1)
})

describe('parseEntries', () => {
it('should return default file paths', () => {
expect(util.parseEntries([], () => null)).toMatchSnapshot()
})

it('should return inputted file paths', () => {
expect(util.parseEntries(['a:b', 'c'])).toMatchSnapshot()
})
})

it('popMastarmFromArgv should remove the mastarm command', () => {
const argv1 = process.argv[1]
expect(argv1).toContain('mastarm')
util.popMastarmFromArgv()
expect(process.argv[1]).not.toBe(argv1)
})

it('updateDependencies should run check-dependencies package', () => {
util.updateDependencies()
expect(mockSyncFn).toBeCalled()
})
})
3 changes: 3 additions & 0 deletions tests/mocks/mock.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.criticalClass {
font-weight: bold !important;
}

0 comments on commit 6314bb9

Please sign in to comment.