mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Remove existing CLI
This commit is contained in:
parent
b9dd8b0a6d
commit
cb48248552
@ -1,46 +0,0 @@
|
||||
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)
|
||||
}
|
||||
@ -1,127 +0,0 @@
|
||||
import autoprefixer from 'autoprefixer'
|
||||
import bytes from 'bytes'
|
||||
import prettyHrtime from 'pretty-hrtime'
|
||||
|
||||
import tailwind from '../..'
|
||||
|
||||
import compile from '../compile'
|
||||
import * as colors from '../colors'
|
||||
import * as emoji from '../emoji'
|
||||
import * as utils from '../utils'
|
||||
|
||||
export const usage = 'build <file> [options]'
|
||||
export const description = 'Compiles Tailwind CSS file.'
|
||||
|
||||
export const options = [
|
||||
{
|
||||
usage: '-o, --output <file>',
|
||||
description: 'Output file.',
|
||||
},
|
||||
{
|
||||
usage: '-c, --config <file>',
|
||||
description: 'Tailwind config file.',
|
||||
},
|
||||
{
|
||||
usage: '--no-autoprefixer',
|
||||
description: "Don't add vendor prefixes using autoprefixer.",
|
||||
},
|
||||
]
|
||||
|
||||
export const optionMap = {
|
||||
output: ['output', 'o'],
|
||||
config: ['config', 'c'],
|
||||
noAutoprefixer: ['no-autoprefixer'],
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the error message and stops the process.
|
||||
*
|
||||
* @param {...string} [msgs]
|
||||
*/
|
||||
function stop(...msgs) {
|
||||
utils.header()
|
||||
utils.error(...msgs)
|
||||
utils.die()
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles CSS file and writes it to stdout.
|
||||
*
|
||||
* @param {CompileOptions} compileOptions
|
||||
* @return {Promise}
|
||||
*/
|
||||
function buildToStdout(compileOptions) {
|
||||
return compile(compileOptions).then((result) => process.stdout.write(result.css))
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles CSS file and writes it to a file.
|
||||
*
|
||||
* @param {CompileOptions} compileOptions
|
||||
* @param {int[]} startTime
|
||||
* @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,
|
||||
...(inputFileSimplePath
|
||||
? ['Building:', colors.file(inputFileSimplePath)]
|
||||
: ['Building from default CSS...', colors.info('(No input file provided)')])
|
||||
)
|
||||
|
||||
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', 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()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command.
|
||||
*
|
||||
* @param {string[]} cliParams
|
||||
* @param {object} cliOptions
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function run(cliParams, cliOptions) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const startTime = process.hrtime()
|
||||
const inputFile = cliParams[0]
|
||||
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)
|
||||
|
||||
if (inputFile) {
|
||||
!utils.exists(inputFile) && stop(colors.file(inputFileSimplePath), 'does not exist.')
|
||||
}
|
||||
|
||||
configFile &&
|
||||
!utils.exists(configFile) &&
|
||||
stop(colors.file(configFileSimplePath), 'does not exist.')
|
||||
|
||||
const compileOptions = {
|
||||
inputFile,
|
||||
outputFile,
|
||||
plugins: [tailwind(configFile)].concat(autoprefix ? [autoprefixer] : []),
|
||||
}
|
||||
|
||||
const buildPromise = outputFile
|
||||
? buildToFile(compileOptions, startTime)
|
||||
: buildToStdout(compileOptions)
|
||||
|
||||
buildPromise.then(resolve).catch(reject)
|
||||
})
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
import { forEach, map, padEnd } from 'lodash'
|
||||
|
||||
import commands from '.'
|
||||
import * as constants from '../../constants'
|
||||
import * as colors from '../colors'
|
||||
import * as utils from '../utils'
|
||||
|
||||
export const usage = 'help [command]'
|
||||
export const description = 'More information about the command.'
|
||||
|
||||
const PADDING_SIZE = 3
|
||||
|
||||
/**
|
||||
* Prints general help.
|
||||
*/
|
||||
export function forApp() {
|
||||
const pad = Math.max(...map(commands, 'usage.length')) + PADDING_SIZE
|
||||
|
||||
utils.log()
|
||||
utils.log('Usage:')
|
||||
utils.log(' ', colors.bold(constants.cli + ' <command> [options]'))
|
||||
utils.log()
|
||||
utils.log('Commands:')
|
||||
forEach(commands, (command) => {
|
||||
utils.log(' ', colors.bold(padEnd(command.usage, pad)), command.description)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints help for a command.
|
||||
*
|
||||
* @param {object} command
|
||||
*/
|
||||
export function forCommand(command) {
|
||||
utils.log()
|
||||
utils.log('Usage:')
|
||||
utils.log(' ', colors.bold(constants.cli, command.usage))
|
||||
utils.log()
|
||||
utils.log('Description:')
|
||||
utils.log(' ', colors.bold(command.description))
|
||||
|
||||
if (command.options) {
|
||||
const pad = Math.max(...map(command.options, 'usage.length')) + PADDING_SIZE
|
||||
|
||||
utils.log()
|
||||
utils.log('Options:')
|
||||
forEach(command.options, (option) => {
|
||||
utils.log(' ', colors.bold(padEnd(option.usage, pad)), option.description)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints invalid command error and general help. Kills the process.
|
||||
*
|
||||
* @param {string} commandName
|
||||
*/
|
||||
export function invalidCommand(commandName) {
|
||||
utils.error('Invalid command:', colors.command(commandName))
|
||||
forApp()
|
||||
utils.die()
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command.
|
||||
*
|
||||
* @param {string[]} cliParams
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function run(cliParams) {
|
||||
return new Promise((resolve) => {
|
||||
utils.header()
|
||||
|
||||
const commandName = cliParams[0]
|
||||
const command = commands[commandName]
|
||||
|
||||
!commandName && forApp()
|
||||
commandName && command && forCommand(command)
|
||||
commandName && !command && invalidCommand(commandName)
|
||||
|
||||
utils.footer()
|
||||
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
import * as help from './help'
|
||||
import * as init from './init'
|
||||
import * as build from './build'
|
||||
|
||||
export default { help, init, build }
|
||||
@ -1,70 +0,0 @@
|
||||
import * as constants from '../../constants'
|
||||
import * as colors from '../colors'
|
||||
import * as emoji from '../emoji'
|
||||
import * as utils from '../utils'
|
||||
|
||||
export const usage = 'init [file]'
|
||||
export const description =
|
||||
'Creates Tailwind config file. Default: ' +
|
||||
colors.file(utils.getSimplePath(constants.defaultConfigFile))
|
||||
|
||||
export const options = [
|
||||
{
|
||||
usage: '--full',
|
||||
description: 'Generate complete configuration file.',
|
||||
},
|
||||
{
|
||||
usage: '-p',
|
||||
description: 'Generate PostCSS config file.',
|
||||
},
|
||||
]
|
||||
|
||||
export const optionMap = {
|
||||
full: ['full'],
|
||||
postcss: ['p'],
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the command.
|
||||
*
|
||||
* @param {string[]} cliParams
|
||||
* @param {object} cliOptions
|
||||
* @return {Promise}
|
||||
*/
|
||||
export function run(cliParams, cliOptions) {
|
||||
return new Promise((resolve) => {
|
||||
utils.header()
|
||||
|
||||
const isModule = utils.isModule()
|
||||
const full = cliOptions.full
|
||||
const file = cliParams[0] || (isModule ? constants.cjsConfigFile : constants.defaultConfigFile)
|
||||
const simplePath = utils.getSimplePath(file)
|
||||
|
||||
utils.exists(file) && utils.die(colors.file(simplePath), 'already exists.')
|
||||
|
||||
const stubFile = full ? constants.defaultConfigStubFile : constants.simpleConfigStubFile
|
||||
const stubFileContents = utils
|
||||
.readFile(stubFile, 'utf-8')
|
||||
.replace('../colors', 'tailwindcss/colors')
|
||||
|
||||
utils.writeFile(file, stubFileContents)
|
||||
|
||||
utils.log()
|
||||
utils.log(emoji.yes, 'Created Tailwind config file:', colors.file(simplePath))
|
||||
|
||||
if (cliOptions.postcss) {
|
||||
const postCssConfigFile = isModule
|
||||
? constants.cjsPostCssConfigFile
|
||||
: constants.defaultPostCssConfigFile
|
||||
const path = utils.getSimplePath(postCssConfigFile)
|
||||
utils.exists(constants.defaultPostCssConfigFile) &&
|
||||
utils.die(colors.file(path), 'already exists.')
|
||||
utils.copyFile(constants.defaultPostCssConfigStubFile, postCssConfigFile)
|
||||
utils.log(emoji.yes, 'Created PostCSS config file:', colors.file(path))
|
||||
}
|
||||
|
||||
utils.footer()
|
||||
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
import path from 'path'
|
||||
import postcss from 'postcss'
|
||||
|
||||
import * as utils from './utils'
|
||||
|
||||
/**
|
||||
* Compiler options
|
||||
*
|
||||
* @typedef {Object} CompileOptions
|
||||
* @property {string} inputFile
|
||||
* @property {string} outputFile
|
||||
* @property {array} plugins
|
||||
*/
|
||||
|
||||
const defaultOptions = {
|
||||
inputFile: null,
|
||||
outputFile: null,
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles CSS file.
|
||||
*
|
||||
* @param {CompileOptions} options
|
||||
* @return {Promise}
|
||||
*/
|
||||
export default function compile(options = {}) {
|
||||
const config = { ...defaultOptions, ...options }
|
||||
|
||||
const css = config.inputFile
|
||||
? utils.readFile(config.inputFile)
|
||||
: `
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
postcss(config.plugins)
|
||||
.process(css, {
|
||||
from: config.inputFile || path.resolve(__dirname, '../../tailwind.css'),
|
||||
to: config.outputFile,
|
||||
})
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
})
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
import { get } from 'node-emoji'
|
||||
|
||||
export const yes = get('white_check_mark')
|
||||
export const no = get('no_entry_sign')
|
||||
export const go = get('rocket')
|
||||
export const pack = get('package')
|
||||
export const disk = get('floppy_disk')
|
||||
export const warning = get('warning')
|
||||
@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import main from './main'
|
||||
import * as utils from './utils'
|
||||
|
||||
main(process.argv.slice(2)).catch((error) => utils.die(error.stack))
|
||||
@ -1,22 +0,0 @@
|
||||
import commands from './commands'
|
||||
import * as utils from './utils'
|
||||
|
||||
/**
|
||||
* CLI application entrypoint.
|
||||
*
|
||||
* @param {string[]} cliArgs
|
||||
* @return {Promise}
|
||||
*/
|
||||
export default function run(cliArgs) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const params = utils.parseCliParams(cliArgs)
|
||||
const command = commands[params[0]]
|
||||
const options = command ? utils.parseCliOptions(cliArgs, command.optionMap) : {}
|
||||
|
||||
const commandPromise = command
|
||||
? command.run(params.slice(1), options)
|
||||
: commands.help.run(params)
|
||||
|
||||
commandPromise.then(resolve).catch(reject)
|
||||
})
|
||||
}
|
||||
158
src/cli/utils.js
158
src/cli/utils.js
@ -1,158 +0,0 @@
|
||||
import { copyFileSync, ensureFileSync, existsSync, outputFileSync, readFileSync } from 'fs-extra'
|
||||
import { findKey, mapValues, startsWith, trimStart } from 'lodash'
|
||||
import path from 'path'
|
||||
|
||||
import * as colors from './colors'
|
||||
import * as emoji from './emoji'
|
||||
import packageJson from '../../package.json'
|
||||
|
||||
/**
|
||||
* Gets CLI parameters.
|
||||
*
|
||||
* @param {string[]} cliArgs
|
||||
* @return {string[]}
|
||||
*/
|
||||
export function parseCliParams(cliArgs) {
|
||||
const firstOptionIndex = cliArgs.findIndex((cliArg) => cliArg.startsWith('-'))
|
||||
|
||||
return firstOptionIndex > -1 ? cliArgs.slice(0, firstOptionIndex) : cliArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets mapped CLI options.
|
||||
*
|
||||
* @param {string[]} cliArgs
|
||||
* @param {object} [optionMap]
|
||||
* @return {object}
|
||||
*/
|
||||
export function parseCliOptions(cliArgs, optionMap = {}) {
|
||||
let options = {}
|
||||
let currentOption = []
|
||||
|
||||
cliArgs.forEach((cliArg) => {
|
||||
const option = cliArg.startsWith('-') && trimStart(cliArg, '-').toLowerCase()
|
||||
const resolvedOption = findKey(optionMap, (aliases) => aliases.includes(option))
|
||||
|
||||
if (resolvedOption) {
|
||||
currentOption = options[resolvedOption] || (options[resolvedOption] = [])
|
||||
} else if (option) {
|
||||
currentOption = []
|
||||
} else {
|
||||
currentOption.push(cliArg)
|
||||
}
|
||||
})
|
||||
|
||||
return { ...mapValues(optionMap, () => undefined), ...options }
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints messages to console.
|
||||
*
|
||||
* @param {...string} [msgs]
|
||||
*/
|
||||
export function log(...msgs) {
|
||||
console.log(' ', ...msgs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints application header to console.
|
||||
*/
|
||||
export function header() {
|
||||
log()
|
||||
log(colors.bold(packageJson.name), colors.info(packageJson.version))
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints application footer to console.
|
||||
*/
|
||||
export function footer() {
|
||||
log()
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints error messages to console.
|
||||
*
|
||||
* @param {...string} [msgs]
|
||||
*/
|
||||
export function error(...msgs) {
|
||||
log()
|
||||
console.error(' ', emoji.no, colors.error(msgs.join(' ')))
|
||||
}
|
||||
|
||||
/**
|
||||
* Kills the process. Optionally prints error messages to console.
|
||||
*
|
||||
* @param {...string} [msgs]
|
||||
*/
|
||||
export function die(...msgs) {
|
||||
msgs.length && error(...msgs)
|
||||
footer()
|
||||
process.exit(1) // eslint-disable-line
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if path exists.
|
||||
*
|
||||
* @param {string} path
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function exists(path) {
|
||||
return existsSync(path)
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies file source to destination.
|
||||
*
|
||||
* @param {string} source
|
||||
* @param {string} destination
|
||||
*/
|
||||
export function copyFile(source, destination) {
|
||||
copyFileSync(source, destination)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets file content.
|
||||
*
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
*/
|
||||
export function readFile(path) {
|
||||
return readFileSync(path, 'utf-8')
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current package.json uses type "module"
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
export function isModule() {
|
||||
const pkgPath = path.resolve('./package.json')
|
||||
if (exists(pkgPath)) {
|
||||
const pkg = JSON.parse(readFile(pkgPath))
|
||||
return pkg.type && pkg.type === 'module'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes content to file.
|
||||
*
|
||||
* @param {string} path
|
||||
* @param {string} content
|
||||
* @return {string}
|
||||
*/
|
||||
export function writeFile(path, content) {
|
||||
ensureFileSync(path)
|
||||
|
||||
return outputFileSync(path, content)
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips leading ./ from path
|
||||
*
|
||||
* @param {string} path
|
||||
* @return {string}
|
||||
*/
|
||||
export function getSimplePath(path) {
|
||||
return startsWith(path, './') ? path.slice(2) : path
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
import path from 'path'
|
||||
|
||||
import autoprefixer from 'autoprefixer'
|
||||
|
||||
import tailwind from '../src'
|
||||
import compile from '../src/cli/compile'
|
||||
|
||||
describe('cli compile', () => {
|
||||
const inputFile = path.resolve(__dirname, 'fixtures/tailwind-input.css')
|
||||
const outputFile = 'output.css'
|
||||
const plugins = [tailwind(), autoprefixer]
|
||||
|
||||
it('compiles CSS file', () => {
|
||||
return compile({ inputFile, outputFile, plugins }).then((result) => {
|
||||
expect(result.css).toContain('.example')
|
||||
expect(result.css).toContain('-webkit-background-clip')
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,122 +0,0 @@
|
||||
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')
|
||||
const customConfigPath = path.resolve(__dirname, 'fixtures/custom-config.js')
|
||||
const esmPackageJsonPath = path.resolve(__dirname, 'fixtures/esm-package.json')
|
||||
const defaultConfigFixture = utils.readFile(constants.defaultConfigStubFile)
|
||||
const simpleConfigFixture = utils.readFile(constants.simpleConfigStubFile)
|
||||
const defaultPostCssConfigFixture = utils.readFile(constants.defaultPostCssConfigStubFile)
|
||||
|
||||
beforeEach(() => {
|
||||
console.log = jest.fn()
|
||||
process.stdout.write = jest.fn()
|
||||
})
|
||||
|
||||
describe('init', () => {
|
||||
it('creates a Tailwind config file', () => {
|
||||
return runInTempDirectory(() => {
|
||||
return cli(['init']).then(() => {
|
||||
expect(utils.readFile(constants.defaultConfigFile)).toEqual(simpleConfigFixture)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a Tailwind config file and a postcss.config.js file', () => {
|
||||
return runInTempDirectory(() => {
|
||||
return cli(['init', '-p']).then(() => {
|
||||
expect(utils.readFile(constants.defaultConfigFile)).toEqual(simpleConfigFixture)
|
||||
expect(utils.readFile(constants.defaultPostCssConfigFile)).toEqual(
|
||||
defaultPostCssConfigFixture
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a full Tailwind config file', () => {
|
||||
return runInTempDirectory(() => {
|
||||
return cli(['init', '--full']).then(() => {
|
||||
expect(utils.readFile(constants.defaultConfigFile)).toEqual(
|
||||
defaultConfigFixture.replace('../colors', 'tailwindcss/colors')
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a .cjs Tailwind config file inside of an ESM project', () => {
|
||||
return runInTempDirectory(() => {
|
||||
utils.writeFile('package.json', utils.readFile(esmPackageJsonPath))
|
||||
return cli(['init']).then(() => {
|
||||
expect(utils.readFile(constants.cjsConfigFile)).toEqual(simpleConfigFixture)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('creates a .cjs Tailwind config file and a postcss.config.cjs file inside of an ESM project', () => {
|
||||
return runInTempDirectory(() => {
|
||||
utils.writeFile('package.json', utils.readFile(esmPackageJsonPath))
|
||||
return cli(['init', '-p']).then(() => {
|
||||
expect(utils.readFile(constants.cjsConfigFile)).toEqual(simpleConfigFixture)
|
||||
expect(utils.readFile(constants.cjsPostCssConfigFile)).toEqual(
|
||||
defaultPostCssConfigFixture
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('build', () => {
|
||||
it('compiles CSS file using an input css file', () => {
|
||||
return cli(['build', inputCssPath]).then(() => {
|
||||
expect(process.stdout.write.mock.calls[0][0]).toContain('.example')
|
||||
})
|
||||
})
|
||||
|
||||
it('compiles CSS file without an input css file', () => {
|
||||
return cli(['build']).then(() => {
|
||||
expect(process.stdout.write.mock.calls[0][0]).toContain('normalize.css') // base
|
||||
expect(process.stdout.write.mock.calls[0][0]).toContain('.container') // components
|
||||
expect(process.stdout.write.mock.calls[0][0]).toContain('.mx-auto') // utilities
|
||||
})
|
||||
})
|
||||
|
||||
it('compiles CSS file using custom configuration', () => {
|
||||
return cli(['build', inputCssPath, '--config', customConfigPath]).then(() => {
|
||||
expect(process.stdout.write.mock.calls[0][0]).toContain('400px')
|
||||
})
|
||||
})
|
||||
|
||||
it('creates compiled CSS file', () => {
|
||||
return runInTempDirectory(() => {
|
||||
return cli(['build', inputCssPath, '--output', 'output.css']).then(() => {
|
||||
expect(utils.readFile('output.css')).toContain('.example')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('compiles CSS file with autoprefixer', () => {
|
||||
return cli(['build', inputCssPath]).then(() => {
|
||||
expect(process.stdout.write.mock.calls[0][0]).toContain('-webkit-background-clip')
|
||||
})
|
||||
})
|
||||
|
||||
it('compiles CSS file without autoprefixer', () => {
|
||||
return cli(['build', inputCssPath, '--no-autoprefixer']).then(() => {
|
||||
expect(process.stdout.write.mock.calls[0][0]).not.toContain('-webkit-background-clip')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,73 +0,0 @@
|
||||
import * as utils from '../src/cli/utils'
|
||||
|
||||
describe('cli utils', () => {
|
||||
describe('parseCliParams', () => {
|
||||
it('parses CLI parameters', () => {
|
||||
const result = utils.parseCliParams(['a', 'b', '-c', 'd'])
|
||||
|
||||
expect(result).toEqual(['a', 'b'])
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseCliOptions', () => {
|
||||
it('parses CLI options', () => {
|
||||
const result = utils.parseCliOptions(['a', '-b', 'c'], { test: ['b'] })
|
||||
|
||||
expect(result).toEqual({ test: ['c'] })
|
||||
})
|
||||
|
||||
it('parses multiple types of options', () => {
|
||||
const result = utils.parseCliOptions(['a', '-b', 'c', '--test', 'd', '-test', 'e'], {
|
||||
test: ['test', 'b'],
|
||||
})
|
||||
|
||||
expect(result).toEqual({ test: ['c', 'd', 'e'] })
|
||||
})
|
||||
|
||||
it('ignores unknown options', () => {
|
||||
const result = utils.parseCliOptions(['a', '-b', 'c'], {})
|
||||
|
||||
expect(result).toEqual({})
|
||||
})
|
||||
|
||||
it('maps options', () => {
|
||||
const result = utils.parseCliOptions(['a', '-b', 'c', '-d', 'e'], { test: ['b', 'd'] })
|
||||
|
||||
expect(result).toEqual({ test: ['c', 'e'] })
|
||||
})
|
||||
|
||||
it('parses undefined options', () => {
|
||||
const result = utils.parseCliOptions(['a'], { test: ['b'] })
|
||||
|
||||
expect(result).toEqual({ test: undefined })
|
||||
})
|
||||
|
||||
it('parses flags', () => {
|
||||
const result = utils.parseCliOptions(['a', '-b'], { test: ['b'] })
|
||||
|
||||
expect(result).toEqual({ test: [] })
|
||||
})
|
||||
|
||||
it('accepts multiple values per option', () => {
|
||||
const result = utils.parseCliOptions(['a', '-b', 'c', 'd', '-e', 'f', '-g', 'h'], {
|
||||
test: ['b', 'g'],
|
||||
})
|
||||
|
||||
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')
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user