Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 47 additions & 24 deletions __tests__/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'path'
import cli from '../src/cli/main'
import * as constants from '../src/constants'
import * as utils from '../src/cli/utils'
import runInTempDirectory from '../jest/runInTempDirectory'

describe('cli', () => {
const inputCssPath = path.resolve(__dirname, 'fixtures/tailwind-input.css')
Expand All @@ -13,37 +14,30 @@ describe('cli', () => {
beforeEach(() => {
console.log = jest.fn()
process.stdout.write = jest.fn()
utils.writeFile = jest.fn()
})

describe('init', () => {
it('creates a Tailwind config file', () => {
return cli(['init']).then(() => {
expect(utils.writeFile.mock.calls[0][0]).toEqual(constants.defaultConfigFile)
return runInTempDirectory(() => {
return cli(['init']).then(() => {
expect(utils.readFile(constants.defaultConfigFile)).toEqual(simpleConfigFixture)
})
})
})

it('creates a Tailwind config file in a custom location', () => {
return cli(['init', 'custom.js']).then(() => {
expect(utils.writeFile.mock.calls[0][0]).toEqual('custom.js')
})
})

it('creates a Tailwind config file without comments', () => {
return cli(['init', '--no-comments']).then(() => {
expect(utils.writeFile.mock.calls[0][1]).not.toContain('/**')
})
})

it('creates a simple Tailwind config file', () => {
return cli(['init']).then(() => {
expect(utils.writeFile.mock.calls[0][1]).toEqual(simpleConfigFixture)
it('creates a full Tailwind config file', () => {
return runInTempDirectory(() => {
return cli(['init', '--full']).then(() => {
expect(utils.readFile(constants.defaultConfigFile)).toEqual(defaultConfigFixture)
})
})
})

it('creates a full Tailwind config file', () => {
return cli(['init', '--full']).then(() => {
expect(utils.writeFile.mock.calls[0][1]).toEqual(defaultConfigFixture)
it('creates a Tailwind config file in a custom location', () => {
return runInTempDirectory(() => {
return cli(['init', 'custom.js']).then(() => {
expect(utils.exists('custom.js')).toEqual(true)
})
})
})
})
Expand All @@ -62,9 +56,10 @@ describe('cli', () => {
})

it('creates compiled CSS file', () => {
return cli(['build', inputCssPath, '--output', 'output.css']).then(() => {
expect(utils.writeFile.mock.calls[0][0]).toEqual('output.css')
expect(utils.writeFile.mock.calls[0][1]).toContain('.example')
return runInTempDirectory(() => {
return cli(['build', inputCssPath, '--output', 'output.css']).then(() => {
expect(utils.readFile('output.css')).toContain('.example')
})
})
})

Expand All @@ -80,4 +75,32 @@ describe('cli', () => {
})
})
})

describe('update', () => {
it('updates the configuration file', () => {
return runInTempDirectory(() => {
utils.copyFile(constants.oldDefaultConfigStubFile, constants.oldDefaultConfigFile)

return cli(['update']).then(() => {
expect(utils.exists(constants.defaultConfigFile)).toEqual(true)
})
})
})

it('updates the configuration file from custom location', () => {
return runInTempDirectory(() => {
return cli(['update', constants.oldDefaultConfigStubFile]).then(() => {
expect(utils.exists(constants.defaultConfigFile)).toEqual(true)
})
})
})

it('updates the configuration file from custom location to custom location', () => {
return runInTempDirectory(() => {
return cli(['update', constants.oldDefaultConfigStubFile, 'custom.js']).then(() => {
expect(utils.exists('custom.js')).toEqual(true)
})
})
})
})
})
69 changes: 69 additions & 0 deletions __tests__/cli.update.transform.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import transform from '../src/cli/commands/update/transform'
import defaultConfig from '../stubs/defaultConfig.stub.js'

describe('cli update transform', () => {
let oldConfig
let containerPlugin

beforeEach(() => {
containerPlugin = {
plugin: 'container',
options: {},
}

oldConfig = {
options: {},
modules: {},
plugins: [containerPlugin],
}
})

it('returns complete configuration', () => {
expect(transform(oldConfig)).toEqual(defaultConfig)
})

it('populates theme', () => {
oldConfig.colors = 'test'
expect(transform(oldConfig).theme.colors).toEqual('test')
})

it('transforms theme values that have changed', () => {
oldConfig.shadows = 'test'
expect(transform(oldConfig).theme.boxShadow).toEqual('test')
})

it('populates variants', () => {
oldConfig.modules.appearance = 'test'
expect(transform(oldConfig).variants.appearance).toEqual('test')
})

it('transforms variants that have changed', () => {
oldConfig.modules.svgFill = 'test'
expect(transform(oldConfig).variants.fill).toEqual('test')
})

it('disables variants using corePlugins', () => {
oldConfig.modules.float = false
expect(transform(oldConfig).corePlugins.float).toEqual(false)
})

it('populates options', () => {
oldConfig.options.important = 'test'
expect(transform(oldConfig).important).toEqual('test')
})

it('populates plugins', () => {
oldConfig.plugins = [jest.fn()]
expect(transform(oldConfig).plugins).toEqual(oldConfig.plugins)
})

it('transforms container plugin', () => {
containerPlugin.options = { padding: 'test' }
expect(transform(oldConfig).theme.container).toEqual(containerPlugin.options)
})

it('disables container plugin', () => {
oldConfig.plugins = []
expect(transform(oldConfig).corePlugins.container).toEqual(false)
})
})
9 changes: 9 additions & 0 deletions __tests__/cli.update.validate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { getMissingRequiredProperties } from '../src/cli/commands/update/validator'

describe('cli update validator', () => {
describe('getMissingRequiredProperties', () => {
it('gets a list of missing required properties', () => {
expect(getMissingRequiredProperties({})).toEqual(expect.arrayContaining(['options.prefix']))
})
})
})
14 changes: 14 additions & 0 deletions __tests__/cli.utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,18 @@ describe('cli utils', () => {
expect(result).toEqual({ test: ['c', 'd', 'h'] })
})
})

describe('getSimplePath', () => {
it('strips leading ./', () => {
const result = utils.getSimplePath('./test')

expect(result).toEqual('test')
})

it('returns unchanged path if it does not begin with ./', () => {
const result = utils.getSimplePath('../test')

expect(result).toEqual('../test')
})
})
})
14 changes: 1 addition & 13 deletions __tests__/customConfig.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import fs from 'fs'
import path from 'path'
import rimraf from 'rimraf'
import postcss from 'postcss'
import tailwind from '../src/index'
import { defaultConfigFile } from '../src/constants'

function inTempDirectory(callback) {
return new Promise(resolve => {
rimraf.sync('./__tmp')
fs.mkdirSync(path.resolve('./__tmp'))
process.chdir(path.resolve('./__tmp'))
callback().then(() => {
process.chdir(path.resolve('../'))
rimraf('./__tmp', resolve)
})
})
}
import inTempDirectory from '../jest/runInTempDirectory'

test('it uses the values from the custom config file', () => {
return postcss([tailwind(path.resolve(`${__dirname}/fixtures/custom-config.js`))])
Expand Down
21 changes: 21 additions & 0 deletions jest/runInTempDirectory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import fs from 'fs'
import path from 'path'

import rimraf from 'rimraf'

const tmpPath = path.resolve(__dirname, '../__tmp')

export default function(callback) {
return new Promise(resolve => {
const currentPath = process.cwd()

rimraf.sync(tmpPath)
fs.mkdirSync(tmpPath)
process.chdir(tmpPath)

callback().then(() => {
process.chdir(currentPath)
rimraf(tmpPath, resolve)
})
})
}
46 changes: 46 additions & 0 deletions src/cli/colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import chalk from 'chalk'

/**
* Applies colors to emphasize
*
* @param {...string} msgs
*/
export function bold(...msgs) {
return chalk.bold(...msgs)
}

/**
* Applies colors to inform
*
* @param {...string} msgs
*/
export function info(...msgs) {
return chalk.bold.cyan(...msgs)
}

/**
* Applies colors to signify error
*
* @param {...string} msgs
*/
export function error(...msgs) {
return chalk.bold.red(...msgs)
}

/**
* Applies colors to represent a command
*
* @param {...string} msgs
*/
export function command(...msgs) {
return chalk.bold.magenta(...msgs)
}

/**
* Applies colors to represent a file
*
* @param {...string} msgs
*/
export function file(...msgs) {
return chalk.bold.magenta(...msgs)
}
19 changes: 12 additions & 7 deletions src/cli/commands/build.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import autoprefixer from 'autoprefixer'
import bytes from 'bytes'
import chalk from 'chalk'
import prettyHrtime from 'pretty-hrtime'

import tailwind from '../..'

import commands from '.'
import compile from '../compile'
import * as colors from '../colors'
import * as emoji from '../emoji'
import * as utils from '../utils'

Expand Down Expand Up @@ -75,19 +75,22 @@ function buildToStdout(compileOptions) {
* @return {Promise}
*/
function buildToFile(compileOptions, startTime) {
const inputFileSimplePath = utils.getSimplePath(compileOptions.inputFile)
const outputFileSimplePath = utils.getSimplePath(compileOptions.outputFile)

utils.header()
utils.log()
utils.log(emoji.go, 'Building...', chalk.bold.cyan(compileOptions.inputFile))
utils.log(emoji.go, 'Building...', colors.file(inputFileSimplePath))

return compile(compileOptions).then(result => {
utils.writeFile(compileOptions.outputFile, result.css)

const prettyTime = prettyHrtime(process.hrtime(startTime))

utils.log()
utils.log(emoji.yes, 'Finished in', chalk.bold.magenta(prettyTime))
utils.log(emoji.pack, 'Size:', chalk.bold.magenta(bytes(result.css.length)))
utils.log(emoji.disk, 'Saved to', chalk.bold.cyan(compileOptions.outputFile))
utils.log(emoji.yes, 'Finished in', colors.info(prettyTime))
utils.log(emoji.pack, 'Size:', colors.info(bytes(result.css.length)))
utils.log(emoji.disk, 'Saved to', colors.file(outputFileSimplePath))
utils.footer()
})
}
Expand All @@ -106,13 +109,15 @@ export function run(cliParams, cliOptions) {
const configFile = cliOptions.config && cliOptions.config[0]
const outputFile = cliOptions.output && cliOptions.output[0]
const autoprefix = !cliOptions.noAutoprefixer
const inputFileSimplePath = utils.getSimplePath(inputFile)
const configFileSimplePath = utils.getSimplePath(configFile)

!inputFile && stopWithHelp('CSS file is required.')
!utils.exists(inputFile) && stop(chalk.bold.magenta(inputFile), 'does not exist.')
!utils.exists(inputFile) && stop(colors.file(inputFileSimplePath), 'does not exist.')

configFile &&
!utils.exists(configFile) &&
stop(chalk.bold.magenta(configFile), 'does not exist.')
stop(colors.file(configFileSimplePath), 'does not exist.')

const compileOptions = {
inputFile,
Expand Down
Loading