Skip to content

Commit 8c38231

Browse files
merceyzKent C. Dodds
authored and
Kent C. Dodds
committed
feat: control which linefeed character to use (#45)
* docs: run doctoc * docs: endOfLine * feat: allow controlling endOfLine * test: endOfLine * refactor: use lf and crlf * test: invalid value and no linefeed * refactor: set default earlier, don't default input
1 parent 1d22086 commit 8c38231

File tree

3 files changed

+197
-15
lines changed

3 files changed

+197
-15
lines changed

Diff for: README.md

+50-13
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,45 @@ work with `mocha` and `jasmine`.
3333
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
3434
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
3535

36-
- [Installation](#installation)
37-
- [Usage](#usage)
38-
- [import](#import)
39-
- [Invoke](#invoke)
40-
- [options](#options)
41-
- [Test Objects](#test-objects)
42-
- [Examples](#examples)
43-
- [Full Example + Docs](#full-example--docs)
44-
- [Simple Example](#simple-example)
45-
- [Inspiration](#inspiration)
46-
- [Other Solutions](#other-solutions)
47-
- [Contributors](#contributors)
48-
- [LICENSE](#license)
36+
- [babel-plugin-tester](#babel-plugin-tester)
37+
- [The problem](#the-problem)
38+
- [This solution](#this-solution)
39+
- [Installation](#installation)
40+
- [Usage](#usage)
41+
- [import](#import)
42+
- [Invoke](#invoke)
43+
- [options](#options)
44+
- [plugin](#plugin)
45+
- [pluginName](#pluginname)
46+
- [pluginOptions](#pluginoptions)
47+
- [babel.config.js](#babelconfigjs)
48+
- [title](#title)
49+
- [filename](#filename)
50+
- [endOfLine](#endofline)
51+
- [fixtures](#fixtures)
52+
- [tests](#tests)
53+
- [babel](#babel)
54+
- [...rest](#rest)
55+
- [Test Objects](#test-objects)
56+
- [code](#code)
57+
- [title](#title-1)
58+
- [output](#output)
59+
- [fixture](#fixture)
60+
- [outputFixture](#outputfixture)
61+
- [only](#only)
62+
- [skip](#skip)
63+
- [snapshot](#snapshot)
64+
- [error](#error)
65+
- [setup](#setup)
66+
- [teardown](#teardown)
67+
- [formatResult](#formatresult)
68+
- [Examples](#examples)
69+
- [Full Example + Docs](#full-example--docs)
70+
- [Simple Example](#simple-example)
71+
- [Inspiration](#inspiration)
72+
- [Other Solutions](#other-solutions)
73+
- [Contributors](#contributors)
74+
- [LICENSE](#license)
4975

5076
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
5177

@@ -154,6 +180,17 @@ this value is `fixtures`. Test Object properties affected by this value are:
154180
absolute paths, then they will be `path.join`ed with `path.dirname` of the
155181
`filename`.
156182

183+
#### endOfLine
184+
185+
This is used to control which line endings the output from babel should have
186+
187+
| Options | Description |
188+
| ---------- | ---------------------------------- |
189+
| `lf` | Unix - default |
190+
| `crlf` | Windows |
191+
| `auto` | Use the system default |
192+
| `preserve` | Use the line ending from the input |
193+
157194
#### fixtures
158195

159196
This is a path to a directory with this format:

Diff for: src/__tests__/index.js

+100
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fs from 'fs'
22
import path from 'path'
33
import assert from 'assert'
4+
import {EOL} from 'os'
45
// eslint-disable-next-line import/default
56
import pluginTester from '../'
67
import identifierReversePlugin from './helpers/identifier-reverse-plugin'
@@ -708,6 +709,105 @@ test('appends to root plugins array', async () => {
708709
expect(programVisitor).toHaveBeenCalledTimes(9)
709710
})
710711

712+
test('endOfLine - default', async () => {
713+
await runPluginTester(
714+
getOptions({
715+
tests: [
716+
{
717+
code: 'var foo = "";\nvar bar = "";',
718+
output: 'var foo = "";\nvar bar = "";',
719+
},
720+
],
721+
}),
722+
)
723+
})
724+
725+
test('endOfLine - Unix', async () => {
726+
await runPluginTester(
727+
getOptions({
728+
endOfLine: 'lf',
729+
tests: [
730+
{
731+
code: 'var foo = "";\nvar bar = "";',
732+
output: 'var foo = "";\nvar bar = "";',
733+
},
734+
],
735+
}),
736+
)
737+
})
738+
739+
test('endOfLine - Windows', async () => {
740+
await runPluginTester(
741+
getOptions({
742+
endOfLine: 'crlf',
743+
tests: [
744+
{
745+
code: 'var foo = "";\nvar bar = "";',
746+
output: 'var foo = "";\r\nvar bar = "";',
747+
},
748+
],
749+
}),
750+
)
751+
})
752+
753+
test('endOfLine - auto', async () => {
754+
await runPluginTester(
755+
getOptions({
756+
endOfLine: 'auto',
757+
tests: [
758+
{
759+
code: 'var foo = "";\nvar bar = "";',
760+
output: `var foo = "";${EOL}var bar = "";`,
761+
},
762+
],
763+
}),
764+
)
765+
})
766+
767+
test('endOfLine - preserve', async () => {
768+
await runPluginTester(
769+
getOptions({
770+
endOfLine: 'preserve',
771+
tests: [
772+
{
773+
code: 'var foo = "";\r\nvar bar = "";',
774+
output: `var foo = "";\r\nvar bar = "";`,
775+
},
776+
],
777+
}),
778+
)
779+
})
780+
781+
test('endOfLine - preserve - no linefeed', async () => {
782+
await runPluginTester(
783+
getOptions({
784+
endOfLine: 'preserve',
785+
tests: [
786+
{
787+
code: 'var foo = "";',
788+
output: 'var foo = "";',
789+
},
790+
],
791+
}),
792+
)
793+
})
794+
795+
test('endOfLine - invalid option', async () => {
796+
const errorThrown = await runPluginTester(
797+
getOptions({
798+
endOfLine: 'invalid',
799+
tests: [
800+
{
801+
code: 'var foo = "";',
802+
output: 'var foo = "";',
803+
},
804+
],
805+
}),
806+
).catch(e => e)
807+
808+
expect(errorThrown.message).toBe("Invalid 'endOfLine' value")
809+
})
810+
711811
function getOptions(overrides) {
712812
return {
713813
pluginName: 'captains-log',

Diff for: src/index.js

+47-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import assert from 'assert'
44
import path from 'path'
55
import fs from 'fs'
6+
import {EOL} from 'os'
67
import pathExists from 'path-exists'
78
import mergeWith from 'lodash.mergewith'
89
import invariant from 'invariant'
@@ -39,6 +40,7 @@ function pluginTester({
3940
fixtures,
4041
fixtureOutputName = 'output',
4142
filename,
43+
endOfLine = 'lf',
4244
...rest
4345
} = {}) {
4446
let testNumber = 1
@@ -52,6 +54,7 @@ function pluginTester({
5254
fixtureOutputName,
5355
filename,
5456
babel,
57+
endOfLine,
5558
...rest,
5659
})
5760
}
@@ -144,7 +147,13 @@ function pluginTester({
144147
let errored = false
145148

146149
try {
147-
result = formatResult(babel.transform(code, babelOptions).code)
150+
result = formatResult(
151+
fixLineEndings(
152+
babel.transform(code, babelOptions).code,
153+
endOfLine,
154+
code,
155+
),
156+
)
148157
} catch (err) {
149158
if (error) {
150159
errored = true
@@ -214,6 +223,34 @@ function pluginTester({
214223
}
215224
}
216225

226+
function fixLineEndings(code, endOfLine, input) {
227+
return code.replace(/\r?\n/g, getReplacement())
228+
229+
function getReplacement() {
230+
switch (endOfLine) {
231+
case 'lf': {
232+
return '\n'
233+
}
234+
case 'crlf': {
235+
return '\r\n'
236+
}
237+
case 'auto': {
238+
return EOL
239+
}
240+
case 'preserve': {
241+
const match = input.match(/\r?\n/)
242+
if (match === null) {
243+
return EOL
244+
}
245+
return match[0]
246+
}
247+
default: {
248+
throw new Error("Invalid 'endOfLine' value")
249+
}
250+
}
251+
}
252+
}
253+
217254
const createFixtureTests = (fixturesDir, options) => {
218255
if (!fs.statSync(fixturesDir).isDirectory()) return
219256

@@ -259,6 +296,7 @@ const createFixtureTests = (fixturesDir, options) => {
259296
pluginOptions,
260297
fixtureOutputName,
261298
babel,
299+
endOfLine,
262300
formatResult = r => r,
263301
...rest
264302
} = options
@@ -288,8 +326,15 @@ const createFixtureTests = (fixturesDir, options) => {
288326
rest,
289327
mergeCustomizer,
290328
)
329+
330+
const input = fs.readFileSync(codePath).toString()
291331
const actual = formatResult(
292-
babel.transformFileSync(codePath, babelOptions).code,
332+
fixLineEndings(
333+
babel.transformSync(input, {...babelOptions, filename: codePath})
334+
.code,
335+
endOfLine,
336+
input,
337+
),
293338
)
294339

295340
const outputPath = path.join(fixtureDir, `${fixtureOutputName}${ext}`)

0 commit comments

Comments
 (0)