Skip to content

Commit

Permalink
Merge ffdba1c into 1ddd017
Browse files Browse the repository at this point in the history
  • Loading branch information
cpcwood authored Nov 19, 2020
2 parents 1ddd017 + ffdba1c commit 52e3a36
Show file tree
Hide file tree
Showing 9 changed files with 1,090 additions and 22 deletions.
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Contributing

Feel free to ask questions using [issues](https://github.com/cpcwood/jest-erb-transformer/issues) or fork and [create a pull request](https://github.com/cpcwood/jest-erb-transformer/compare) if you have any improvements.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Jest ERB Transformer

[![npm-version](https://img.shields.io/npm/v/jest-erb-transformer.svg?color=blueviolet&style=flat-square)](https://www.npmjs.com/package/jest-erb-transformer) [![build-status](https://img.shields.io/travis/com/cpcwood/jest-erb-transformer.svg?style=flat-square)](https://travis-ci.com/github/cpcwood/jest-erb-transformer) [![code-coverage](https://img.shields.io/coveralls/github/cpcwood/jest-erb-transformer.svg?style=flat-square)](https://coveralls.io/github/cpcwood/jest-erb-transformer) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg?style=flat-square)](https://standardjs.com)
[![npm-version](https://img.shields.io/npm/v/jest-erb-transformer.svg?color=blueviolet&style=flat-square)](https://www.npmjs.com/package/jest-erb-transformer) [![build-status](https://img.shields.io/travis/com/cpcwood/jest-erb-transformer/master.svg?style=flat-square)](https://travis-ci.com/github/cpcwood/jest-erb-transformer) [![code-coverage](https://img.shields.io/coveralls/github/cpcwood/jest-erb-transformer.svg?style=flat-square)](https://coveralls.io/github/cpcwood/jest-erb-transformer) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg?style=flat-square)](https://standardjs.com)

## Overview

Expand Down Expand Up @@ -56,7 +56,7 @@ To add custom configuration, such as using the Ruby on Rails runner for ERB comp
| ```"application"``` | ```"ruby"``` | Transformer is run using ```ruby``` by default, set value to ```"rails"``` to use ```bin/rails runner```. The ```"rails"``` option can be useful if the .erb files include Ruby on Rails specific environment variables such as ```Rails.application.credentails```. |
| ```"engine"``` | ```"erb"``` | Transformer uses the ruby 'ERB' engine by default, to use the [Erubi](https://github.com/jeremyevans/erubi) engine set the value to ```"erubi"```. |
| ```"timeout"``` | ```"5000"``` | Set the timeout duration in milliseconds for the compilation of individual files. |

| ```"babelConfig"``` | ```false``` | Process the output of the ERB transformer using [babel-jest](https://www.npmjs.com/package/babel-jest). <br> Options: <ul><li>```false``` - Disables the use of Babel.</li><li>```true``` - Babel processing using project or file-relative [Babel configuration file](https://babeljs.io/docs/en/config-files).</li><li>```./path/to/.babelrc.json``` - Relative path to Babel configuration file to be used for processing.</li><li>```{ "comments": false }``` - Object containing [Babel options](https://babeljs.io/docs/en/options) to be used for processing.</li></ul> |
## Contributing

Feel free to ask questions using [issues](https://github.com/cpcwood/jest-erb-transformer/issues) or contribute if you have any improvements.
Expand Down
4 changes: 4 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
comments: true,
presets: ["@babel/preset-env"]
}
39 changes: 32 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const childProcess = require('child_process')
const path = require('path')
const babelJest = require('babel-jest')

function loadConfig (filePath, jestConfig) {
// Default Config
Expand All @@ -12,29 +13,44 @@ function loadConfig (filePath, jestConfig) {
delimiter: '__JEST_ERB_TRANSFORMER__'
},
timeout: 5000,
stdio: ['pipe', 'pipe', process.stderr]
stdio: ['pipe', 'pipe', process.stderr],
babelConfig: false
}

// User options
const userOptions = {
application: {
regex: new RegExp(`^(rails|${config.application})$`),
tester: new RegExp(`^(rails|${config.application})$`),
applyToConfig: () => {
config.application = 'bin/rails'
config.args.runner = 'runner'
}
},
engine: {
regex: new RegExp(`^(erubi|${config.args.engine})$`),
tester: new RegExp(`^(erubi|${config.args.engine})$`),
applyToConfig: () => {
config.args.engine = 'erubi'
}
},
timeout: {
regex: /^(\d+(?:\.\d*)?)$/,
applyToConfig: (userTimeout) => {
tester: { test: value => /^(\d+(?:\.\d*)?)$/.test(value.toString()) },
applyToConfig: userTimeout => {
config.timeout = parseInt(userTimeout)
}
},
babelConfig: {
tester: { test: value => ['boolean', 'string', 'object'].includes(typeof value) },
applyToConfig: userBabelConfig => {
if (userBabelConfig === true) {
config.babelConfig = {}
} else if (typeof userBabelConfig === 'string') {
config.babelConfig = {
configFile: userBabelConfig
}
} else if (typeof userBabelConfig === 'object') {
config.babelConfig = userBabelConfig
}
}
}
}

Expand All @@ -50,7 +66,7 @@ function loadConfig (filePath, jestConfig) {
if (selectedOption === undefined) {
console.warn(`WARNING - User Configuration: "${key}" is not a valid configuration key and will be ignored!`)
} else {
const isValidValue = selectedOption.regex.test(value.toString())
const isValidValue = selectedOption.tester.test(value)
if (isValidValue) {
selectedOption.applyToConfig(value)
} else {
Expand Down Expand Up @@ -89,9 +105,18 @@ function erbTransformer (fileContent, filePath, config) {
return compiledFile
}

function processFile (fileContent, filePath, config) {
let processedContent = String(erbTransformer(fileContent, filePath, config))
if (config.babelConfig) {
const babelTransformer = babelJest.createTransformer(config.babelConfig)
processedContent = babelTransformer.process(processedContent, filePath, {}).code
}
return processedContent
}

module.exports = {
process (fileContent, filePath, jestConfig) {
const config = loadConfig(filePath, jestConfig)
return String(erbTransformer(fileContent, filePath, config))
return processFile(fileContent, filePath, config)
}
}
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "jest-erb-transformer",
"version": "1.0.3",
"version": "1.1.0",
"description": "Jest transformer for Embedded Ruby (`.erb`) files in Ruby projects",
"main": "index.js",
"scripts": {
"test": "jest --no-cache --coverage",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"eslint": "eslint index.js"
"lint": "eslint index.js test.js --fix"
},
"repository": {
"type": "git",
Expand All @@ -26,7 +26,12 @@
"url": "https://github.com/cpcwood/jest-erb-transformer/issues"
},
"homepage": "https://github.com/cpcwood/jest-erb-transformer#readme",
"dependencies": {
"@babel/core": "^7.12.3",
"babel-jest": "^26.6.3"
},
"devDependencies": {
"@babel/preset-env": "^7.12.1",
"coveralls": "^3.1.0",
"eslint": "^7.2.0",
"eslint-config-standard": "^14.1.1",
Expand Down
42 changes: 40 additions & 2 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint no-undef: 0 */
const fs = require('fs')
const { process } = require('./index')
const path = require('path')
Expand All @@ -22,11 +23,13 @@ function transformErb (filePath, testConfiguration = {}) {
}

// Hooks
// ========================
afterEach(() => {
jest.restoreAllMocks()
})

// Features
// ========================
test('compiles a simple file', () => {
expect(transformErb('./tests/helloWorld.js.erb')).toEqual("var helloWorld = 'Hello World'")
})
Expand Down Expand Up @@ -56,7 +59,34 @@ test('user config - timeout', () => {
}).toThrow("Compilation of './tests/configSleep500.js.erb' timed out after 450ms!")
})

test('user config - babelConfig true', () => {
const testConfig = { babelConfig: true }
const result = transformErb('./tests/es6.js.erb', testConfig)
expect(result).toContain('exports.ACCOUNT_PATH = ACCOUNT_PATH;')
expect(result).toContain('a comment')
})

test('user config - babelConfig path', () => {
const testConfig = { babelConfig: './tests/testBabelConfig.js' }
const result = transformErb('./tests/es6.js.erb', testConfig)
expect(result).toContain('exports.ACCOUNT_PATH = ACCOUNT_PATH;')
expect(result).not.toContain('a comment')
})

test('user config - babelConfig inline', () => {
const testConfig = {
babelConfig: {
comments: false,
minified: true
}
}
const result = transformErb('./tests/es6.js.erb', testConfig)
expect(result).toContain('exports.ACCOUNT_PATH=ACCOUNT_PATH;')
expect(result).not.toContain('a comment')
})

// Warnings
// ========================
test('user config - warning - invalid configuration key entered', () => {
const testConfig = { 'not-a-key': 'value' }
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation()
Expand All @@ -74,24 +104,32 @@ test('user config - warning - invalid rails option entered', () => {
test('user config - warning - invalid engine type entered', () => {
const testConfig = { engine: 'not-an-engine' }
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation()
transformErb('./tests/erbEngine.js.erb', testConfig)
transformErb('./tests/helloWorld.js.erb', testConfig)
expect(consoleSpy).toHaveBeenLastCalledWith('WARNING - User Configuration: "engine": "not-an-engine" is not a valid "engine" value, using default value instead!')
})

test('user config - warning - invalid timeout type entered', () => {
const testConfig = { timeout: 'not-an-number' }
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation()
transformErb('./tests/erbEngine.js.erb', testConfig)
transformErb('./tests/helloWorld.js.erb', testConfig)
expect(consoleSpy).toHaveBeenLastCalledWith('WARNING - User Configuration: "timeout": "not-an-number" is not a valid "timeout" value, using default value instead!')
})

test('user config - warning - invalid babelConfig type entered', () => {
const testConfig = { babelConfig: 1 }
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation()
transformErb('./tests/helloWorld.js.erb', testConfig)
expect(consoleSpy).toHaveBeenLastCalledWith('WARNING - User Configuration: "babelConfig": "1" is not a valid "babelConfig" value, using default value instead!')
})

test('user config - warning - could not be loaded', () => {
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation()
transformErb('./tests/configNotLoaded.na.erb')
expect(consoleSpy).toHaveBeenLastCalledWith('WARNING - User Configuration could not be loaded, please check configuration is correct and report to the maintainers!')
})

// Errors
// ========================
test('error - general failure of childProcess.spawnSync', () => {
jest.spyOn(childProcess, 'spawnSync').mockImplementation(() => { return { status: 1, signal: 'test', error: 'test' } })
expect(() => {
Expand Down
10 changes: 10 additions & 0 deletions tests/es6.js.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<%
def account_path
return '/account'
end
%>

// a comment

export const ACCOUNT_PATH = '<%= account_path %>';

4 changes: 4 additions & 0 deletions tests/testBabelConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
comments: false,
presets: ["@babel/preset-env"]
}
Loading

0 comments on commit 52e3a36

Please sign in to comment.