move to mocha

This commit is contained in:
ido 2017-06-29 14:48:33 +03:00
parent 77aec486a5
commit c175351c39
18 changed files with 269 additions and 259 deletions

View File

@ -1,11 +1,11 @@
{ {
"extends": ["wix-editor", "wix-editor/node", "plugin:lodash/recommended"], "extends": ["wix-editor", "wix-editor/node", "plugin:lodash/canonical"],
"plugins": ["lodash", "wix-editor"], "plugins": ["lodash", "wix-editor"],
"rules": { "rules": {
"semi": [2, "never"], "semi": [2, "never"],
"func-style": [2, "declaration", {"allowArrowFunctions": true}], "func-style": [2, "declaration", {"allowArrowFunctions": true}],
"prefer-spread": 0, "prefer-spread": 1,
"prefer-template": 0, "prefer-template": 1,
"consistent-return": 0, "consistent-return": 0,
"no-restricted-syntax": [2, "WithStatement", "ContinueStatement", "ForStatement"], "no-restricted-syntax": [2, "WithStatement", "ContinueStatement", "ForStatement"],

View File

@ -9,7 +9,8 @@
"scripts": { "scripts": {
"build": "npm run lint && npm run test", "build": "npm run lint && npm run test",
"lint": "eslint .", "lint": "eslint .",
"test": "babel-node test/src/test.js", "test1": "babel-node test/src/test.js",
"test": "mocha test/src/**/*.unit.js",
"test-cov": "istanbul cover test/src/test.js -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/", "test-cov": "istanbul cover test/src/test.js -- --require test/support/env --reporter dot --check-leaks test/ test/acceptance/",
"patch": "npm version patch -m\"update version to %s\" && git push && git push --tags", "patch": "npm version patch -m\"update version to %s\" && git push && git push --tags",
"minor": "npm version minor -m\"update version to %s\" && git push && git push --tags", "minor": "npm version minor -m\"update version to %s\" && git push && git push --tags",
@ -35,40 +36,41 @@
"css": "2.2.1", "css": "2.2.1",
"escodegen": "1.8.1", "escodegen": "1.8.1",
"esprima": "3.1.3", "esprima": "3.1.3",
"glob": "7.1.1", "glob": "7.1.2",
"lodash": "4.17.4", "lodash": "4.17.4",
"normalize-html-whitespace": "0.2.0", "normalize-html-whitespace": "0.2.0",
"optionator": "0.8.2", "optionator": "0.8.2",
"text-table": "0.2.0" "text-table": "0.2.0"
}, },
"devDependencies": { "devDependencies": {
"babel-cli": "6.18.0", "babel-cli": "6.24.1",
"babel-core": "6.21.0", "babel-core": "6.25.0",
"babel-loader": "6.2.10", "babel-loader": "7.1.1",
"babel-preset-es2015": "6.18.0", "babel-preset-es2015": "6.24.1",
"brace": "0.9.1", "brace": "0.10.0",
"brfs": "1.4.3", "brfs": "1.4.3",
"coveralls": "2.11.15", "coveralls": "2.13.1",
"eslint": "3.12.2", "eslint": "4.1.1",
"eslint-config-wix-editor": "0.2.3", "eslint-config-wix-editor": "0.2.3",
"eslint-plugin-lodash": "2.2.5", "eslint-plugin-lodash": "2.4.3",
"eslint-plugin-react": "6.8.0", "eslint-plugin-react": "7.1.0",
"eslint-plugin-wix-editor": "1.1.1", "eslint-plugin-wix-editor": "1.1.1",
"grunt": "1.0.1", "grunt": "1.0.1",
"grunt-babel": "6.0.0", "grunt-babel": "6.0.0",
"grunt-browserify": "5.0.0", "grunt-browserify": "5.0.0",
"grunt-contrib-requirejs": "1.0.0", "grunt-contrib-requirejs": "1.0.0",
"grunt-contrib-uglify": "2.0.0", "grunt-contrib-uglify": "3.0.1",
"grunt-contrib-watch": "1.0.0", "grunt-contrib-watch": "1.0.0",
"grunt-eslint": "19.0.0", "grunt-eslint": "20.0.0",
"grunt-tape": "0.1.0", "grunt-tape": "0.1.0",
"istanbul": "0.4.5", "istanbul": "0.4.5",
"json-loader": "0.5.4", "json-loader": "0.5.4",
"mocha": "3.4.2",
"react": "15.3.2", "react": "15.3.2",
"react-dom": "15.3.2", "react-dom": "15.3.2",
"react-native": "0.39.2", "react-native": "0.39.2",
"tape": "4.6.3", "tape": "4.7.0",
"webpack": "1.14.0" "webpack": "3.0.0"
}, },
"keywords": [ "keywords": [
"templates", "templates",

5
test/src/.eslintrc Normal file
View File

@ -0,0 +1,5 @@
{
"env": {
"mocha": true
}
}

View File

@ -1,31 +0,0 @@
'use strict'
const fs = require('fs')
const fsUtil = require('../../src/fsUtil')
const path = require('path')
module.exports = {
runTests(test, dataPath) {
test('test isStale', t => {
const a = path.join(dataPath, 'a.tmp')
const b = path.join(dataPath, 'b.tmp')
fs.writeFileSync(a, 'actual')
fs.writeFileSync(b, 'actual')
const mtime1 = new Date(1995, 11, 17, 3, 24, 0)
fs.utimesSync(a, mtime1, mtime1)
const mtime2 = new Date(1995, 11, 17, 3, 24, 1)
fs.utimesSync(b, mtime2, mtime2)
let actual = fsUtil.isStale(a, b)
t.equal(actual, false)
actual = fsUtil.isStale(b, a)
t.equal(actual, true)
fs.unlinkSync(a)
fs.unlinkSync(b)
t.end()
})
}
}

30
test/src/fsUtil.unit.js Normal file
View File

@ -0,0 +1,30 @@
'use strict'
const fs = require('fs')
const fsUtil = require('../../src/fsUtil')
const path = require('path')
const assert = require('assert')
describe('utils', () => {
it('test isStale', () => {
const dataPath = path.resolve(__dirname, '..', 'data')
const a = path.join(dataPath, 'a.tmp')
const b = path.join(dataPath, 'b.tmp')
fs.writeFileSync(a, 'actual')
fs.writeFileSync(b, 'actual')
const mtime1 = new Date(1995, 11, 17, 3, 24, 0)
fs.utimesSync(a, mtime1, mtime1)
const mtime2 = new Date(1995, 11, 17, 3, 24, 1)
fs.utimesSync(b, mtime2, mtime2)
let actual = fsUtil.isStale(a, b)
assert.equal(actual, false)
actual = fsUtil.isStale(b, a)
assert.equal(actual, true)
fs.unlinkSync(a)
fs.unlinkSync(b)
})
})

View File

@ -1,14 +1,12 @@
'use strict' 'use strict'
const reactTemplates = require('../../src/reactTemplates') const reactTemplates = require('../../src/reactTemplates')
const testUtils = require('./testUtils') const testUtils = require('./utils/testUtils')
const readFileNormalized = testUtils.readFileNormalized const readFileNormalized = testUtils.readFileNormalized
const path = require('path') const path = require('path')
const fsUtil = require('../../src/fsUtil') const fsUtil = require('../../src/fsUtil')
const fs = require('fs') const fs = require('fs')
const assert = require('assert')
module.exports = {
runTests(test, dataPath) {
test('html tests', t => {
const files = [ const files = [
'scope.rt', 'scope.rt',
'scope-trailing-semicolon.rt', 'scope-trailing-semicolon.rt',
@ -34,6 +32,10 @@ module.exports = {
'include.rt' 'include.rt'
] ]
describe('utils', () => {
describe('#convertText', () => {
it('should convert text successfully', () => {
const dataPath = path.resolve(__dirname, '..', 'data')
files.forEach(testFile => { files.forEach(testFile => {
const filename = path.join(dataPath, testFile) const filename = path.join(dataPath, testFile)
const options = { const options = {
@ -47,16 +49,15 @@ module.exports = {
const expected = testUtils.normalizeHtml(readFileNormalized(filename + '.html')) const expected = testUtils.normalizeHtml(readFileNormalized(filename + '.html'))
const code = reactTemplates.convertTemplateToReact(html, options).replace(/\r/g, '') const code = reactTemplates.convertTemplateToReact(html, options).replace(/\r/g, '')
actual = testUtils.normalizeHtml(testUtils.codeToHtml(code)) actual = testUtils.normalizeHtml(testUtils.codeToHtml(code))
equal = t.equal(actual, expected, `${testFile}`) equal = assert.equal(actual, expected, `${testFile}`)
} catch (e) { } catch (e) {
console.log(testFile, e) console.log(testFile, e)
t.fail(e) assert.fail(e)
} }
if (!equal) { if (!equal) {
fs.writeFileSync(filename + '.actual.html', actual) fs.writeFileSync(filename + '.actual.html', actual)
} }
}) })
t.end()
}) })
} })
} })

View File

@ -1,63 +1,15 @@
'use strict' 'use strict'
const reactTemplates = require('../../src/reactTemplates') const reactTemplates = require('../../src/reactTemplates')
const testUtils = require('./testUtils') const testUtils = require('./utils/testUtils')
const _ = require('lodash') const _ = require('lodash')
const path = require('path') const path = require('path')
const RTCodeError = reactTemplates.RTCodeError const RTCodeError = reactTemplates.RTCodeError
const assert = require('assert')
const cli = require('../../src/cli')
const context = require('../../src/context')
const omitStack = err => _.omit(err, 'stack', 'toIssue') const omitStack = err => _.omit(err, 'stack', 'toIssue')
module.exports = {
runTests(test, basePath) {
const dataPath = path.resolve(basePath, 'invalid')
const invalidFiles = [
// {file: 'sortByDragListItemRowExamples.rt', issue: new RTCodeError('x', 0, 160, 1, 1)}
{file: 'if-with-scope/invalid-if-scope-1.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.bar(activeUsers.length)'", 0, 160, 1, 1)},
{file: 'if-with-scope/invalid-if-scope-2.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.bar[activeUsers || 0]'", 0, 158, 1, 1)},
{file: 'if-with-scope/invalid-if-scope-3.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.foo + activeUsers.length > this.bar'", 0, 172, 1, 1)},
{file: 'if-with-scope/invalid-if-scope-4.rt', issue: new RTCodeError("invalid scope mapping used in if part 'getCurrentActiveUsers().length'", 0, 170, 1, 1)},
{file: 'if-with-scope/invalid-if-scope-5.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.bar({activeUsers})'", 0, 155, 1, 1)},
{file: 'invalid-scope.rt', issue: new RTCodeError("invalid scope part 'a in a in a'", 0, 35, 1, 1)},
{file: 'invalid-html.rt', issue: new RTCodeError('Document should have a root element', -1, -1, -1, -1)},
{file: 'invalid-exp.rt', issue: new RTCodeError("Failed to parse text '\n {z\n'", 5, 13, 1, 6)},
{file: 'invalid-lambda.rt', issue: new RTCodeError("when using 'on' events, use lambda '(p1,p2)=>body' notation or 'this.handler'; otherwise use {} to return a callback function. error: [onClick='']", 0, 23, 1, 1)},
{file: 'invalid-autobind.rt', issue: new RTCodeError("'this.handler' syntax allowed only when the --autobind is on, use {} to return a callback function.", 0, 132, 1, 1)},
// {file: 'invalid-js.rt', issue: new RTCodeError('Unexpected token ILLEGAL', 0, 32, 1, 1)}, bug interduced due to scope parsing
{file: 'invalid-single-root.rt', issue: new RTCodeError('Document should have no more than a single root element', 12, 23, 2, 1)},
{file: 'invalid-repeat-1.rt', issue: new RTCodeError("rt-repeat invalid 'in' expression 'a in b in c'", 9, 44, 2, 4)},
{file: 'invalid-repeat-2.rt', issue: new RTCodeError("root element may not have a 'rt-repeat' attribute", 0, 39, 1, 1)},
{file: 'invalid-rt-require-1.rt', issue: new RTCodeError("'rt-require' needs 'dependency' and 'as' attributes", 0, 14, 1, 1)},
{file: 'invalid-rt-require-2.rt', issue: new RTCodeError("'rt-require' may have no children", 0, 32, 1, 1)},
// {file: 'invalid-rt-require-duplicate.rt', issue: new RTCodeError("Line 1: Strict mode function may not have duplicate parameter names", 64, -1, -1, -1), options: {modules: 'amd'}},
{file: 'invalid-rt-import-1.rt', issue: new RTCodeError("'*' imports must have an 'as' attribute", 0, 36, 1, 1)},
{file: 'invalid-rt-import-2.rt', issue: new RTCodeError("default imports must have an 'as' attribute", 0, 42, 1, 1)},
{file: 'invalid-rt-import-3.rt', issue: new RTCodeError("'rt-import' needs 'name' and 'from' attributes", 0, 13, 1, 1)},
{file: 'invalid-rt-import-4.rt', issue: new RTCodeError("'rt-import' must be a toplevel node", 9, 54, 2, 4)},
{file: 'invalid-rt-template-1.rt', issue: new RTCodeError("'rt-template' should have a single non-text element as direct child", 9, 88, 2, 4)},
{file: 'invalid-rt-template-2.rt', issue: new RTCodeError("'rt-template' should have a single non-text element as direct child", 9, 90, 2, 4)},
{file: 'invalid-brace.rt', issue: new RTCodeError('Unexpected end of input', 128, 163, 5, 11)},
{file: 'invalid-style-1.rt', issue: new RTCodeError('Unexpected token ILLEGAL', 10, 39, 2, 5)},
{file: 'invalid-style-2.rt', issue: new RTCodeError('style attribute keys cannot contain { } expressions', 35, 68, 2, 5)},
{file: 'invalid-virtual-1.rt', issue: new RTCodeError('Document should not have <rt-virtual> as root element', 0, 60, 1, 1)},
{file: 'invalid-virtual-2.rt', issue: new RTCodeError("<rt-virtual> may not contain attributes other than 'rt-scope', 'rt-if' and 'rt-repeat'", 9, 119, 2, 4)}
]
test('invalid tests', t => {
t.plan(invalidFiles.length)
invalidFiles.forEach(testFile => {
const filename = path.join(dataPath, testFile.file)
const html = testUtils.readFileNormalized(filename)
let error = null
try {
reactTemplates.convertTemplateToReact(html)
} catch (e) {
error = e
}
t.deepEqual(omitStack(error), omitStack(testFile.issue), 'Expect convertTemplateToReact to throw an error')
})
})
/** /**
* @param {ERR} err * @param {ERR} err
* @return {ERR} * @return {ERR}
@ -69,22 +21,6 @@ module.exports = {
return err return err
} }
test('invalid tests json', t => {
const cli = require('../../src/cli')
const context = require('../../src/context')
t.plan(invalidFiles.length)
invalidFiles.forEach(check)
function check(testFile) {
context.clear()
const filename = path.join(dataPath, testFile.file)
const options = {format: 'json', force: true}
cli.handleSingleFile(_.assign(options, testFile.options), filename)
t.deepEqual(normalizeError(context.getMessages()[0]), errorEqualMessage(testFile.issue, filename), `Expect cli to produce valid output messages ${testFile.file}`)
}
})
/** /**
* @typedef {{index: number, line: number, column: number, msg: string, level: string, file: string}} ERR * @typedef {{index: number, line: number, column: number, msg: string, level: string, file: string}} ERR
*/ */
@ -106,6 +42,76 @@ module.exports = {
file file
} }
} }
}
} describe('utils', () => {
describe('#convertText', () => {
const dataPath = path.resolve(__dirname, '..', 'data', 'invalid')
const invalidFiles = [
// {file: 'sortByDragListItemRowExamples.rt', issue: new RTCodeError('x', 0, 160, 1, 1)}
{file: 'if-with-scope/invalid-if-scope-1.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.bar(activeUsers.length)'", 0, 160, 1, 1)},
{file: 'if-with-scope/invalid-if-scope-2.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.bar[activeUsers || 0]'", 0, 158, 1, 1)},
{
file: 'if-with-scope/invalid-if-scope-3.rt',
issue: new RTCodeError("invalid scope mapping used in if part 'this.foo + activeUsers.length > this.bar'", 0, 172, 1, 1)
},
{file: 'if-with-scope/invalid-if-scope-4.rt', issue: new RTCodeError("invalid scope mapping used in if part 'getCurrentActiveUsers().length'", 0, 170, 1, 1)},
{file: 'if-with-scope/invalid-if-scope-5.rt', issue: new RTCodeError("invalid scope mapping used in if part 'this.bar({activeUsers})'", 0, 155, 1, 1)},
{file: 'invalid-scope.rt', issue: new RTCodeError("invalid scope part 'a in a in a'", 0, 35, 1, 1)},
{file: 'invalid-html.rt', issue: new RTCodeError('Document should have a root element', -1, -1, -1, -1)},
{file: 'invalid-exp.rt', issue: new RTCodeError("Failed to parse text '\n {z\n'", 5, 13, 1, 6)},
{
file: 'invalid-lambda.rt',
issue: new RTCodeError("when using 'on' events, use lambda '(p1,p2)=>body' notation or 'this.handler'; otherwise use {} to return a callback function. error: [onClick='']", 0, 23, 1, 1)
},
{
file: 'invalid-autobind.rt',
issue: new RTCodeError("'this.handler' syntax allowed only when the --autobind is on, use {} to return a callback function.", 0, 132, 1, 1)
},
// {file: 'invalid-js.rt', issue: new RTCodeError('Unexpected token ILLEGAL', 0, 32, 1, 1)}, bug interduced due to scope parsing
{file: 'invalid-single-root.rt', issue: new RTCodeError('Document should have no more than a single root element', 12, 23, 2, 1)},
{file: 'invalid-repeat-1.rt', issue: new RTCodeError("rt-repeat invalid 'in' expression 'a in b in c'", 9, 44, 2, 4)},
{file: 'invalid-repeat-2.rt', issue: new RTCodeError("root element may not have a 'rt-repeat' attribute", 0, 39, 1, 1)},
{file: 'invalid-rt-require-1.rt', issue: new RTCodeError("'rt-require' needs 'dependency' and 'as' attributes", 0, 14, 1, 1)},
{file: 'invalid-rt-require-2.rt', issue: new RTCodeError("'rt-require' may have no children", 0, 32, 1, 1)},
// {file: 'invalid-rt-require-duplicate.rt', issue: new RTCodeError("Line 1: Strict mode function may not have duplicate parameter names", 64, -1, -1, -1), options: {modules: 'amd'}},
{file: 'invalid-rt-import-1.rt', issue: new RTCodeError("'*' imports must have an 'as' attribute", 0, 36, 1, 1)},
{file: 'invalid-rt-import-2.rt', issue: new RTCodeError("default imports must have an 'as' attribute", 0, 42, 1, 1)},
{file: 'invalid-rt-import-3.rt', issue: new RTCodeError("'rt-import' needs 'name' and 'from' attributes", 0, 13, 1, 1)},
{file: 'invalid-rt-import-4.rt', issue: new RTCodeError("'rt-import' must be a toplevel node", 9, 54, 2, 4)},
{file: 'invalid-rt-template-1.rt', issue: new RTCodeError("'rt-template' should have a single non-text element as direct child", 9, 88, 2, 4)},
{file: 'invalid-rt-template-2.rt', issue: new RTCodeError("'rt-template' should have a single non-text element as direct child", 9, 90, 2, 4)},
{file: 'invalid-brace.rt', issue: new RTCodeError('Unexpected end of input', 128, 163, 5, 11)},
{file: 'invalid-style-1.rt', issue: new RTCodeError('Unexpected token ILLEGAL', 10, 39, 2, 5)},
{file: 'invalid-style-2.rt', issue: new RTCodeError('style attribute keys cannot contain { } expressions', 35, 68, 2, 5)},
{file: 'invalid-virtual-1.rt', issue: new RTCodeError('Document should not have <rt-virtual> as root element', 0, 60, 1, 1)},
{file: 'invalid-virtual-2.rt', issue: new RTCodeError("<rt-virtual> may not contain attributes other than 'rt-scope', 'rt-if' and 'rt-repeat'", 9, 119, 2, 4)}
]
it('should convert text successfully', () => {
invalidFiles.forEach(testFile => {
const filename = path.join(dataPath, testFile.file)
const html = testUtils.readFileNormalized(filename)
let error = null
try {
reactTemplates.convertTemplateToReact(html)
} catch (e) {
error = e
}
assert.deepEqual(omitStack(error), omitStack(testFile.issue), 'Expect convertTemplateToReact to throw an error')
})
invalidFiles.forEach(check)
function check(testFile) {
context.clear()
const filename = path.join(dataPath, testFile.file)
const options = {format: 'json', force: true}
cli.handleSingleFile(_.assign(options, testFile.options), filename)
assert.deepEqual(normalizeError(context.getMessages()[0]), errorEqualMessage(testFile.issue, filename), `Expect cli to produce valid output messages ${testFile.file}`)
}
})
})
})

View File

@ -1,26 +1,32 @@
'use strict' 'use strict'
const _ = require('lodash') const _ = require('lodash')
const reactTemplates = require('../../src/reactTemplates') const reactTemplates = require('../../src/reactTemplates')
const testUtils = require('./testUtils') const testUtils = require('./utils/testUtils')
const readFileNormalized = testUtils.readFileNormalized const readFileNormalized = testUtils.readFileNormalized
const compareAndWrite = testUtils.compareAndWrite const compareAndWrite = testUtils.compareAndWrite
const path = require('path') const path = require('path')
const context = require('../../src/context') const context = require('../../src/context')
const assert = require('assert')
const dataPath = path.resolve(__dirname, '..', 'data')
module.exports = { /**
runTests(test, dataPath) { * @param testData
function check(t, testData) { */
function check(testData) {
const filename = path.join(dataPath, testData.source) const filename = path.join(dataPath, testData.source)
const html = readFileNormalized(filename) const html = readFileNormalized(filename)
const expected = readFileNormalized(path.join(dataPath, testData.expected)) const expected = readFileNormalized(path.join(dataPath, testData.expected))
const actual = reactTemplates.convertTemplateToReact(html, testData.options).replace(/\r/g, '').trim() const actual = reactTemplates.convertTemplateToReact(html, testData.options).replace(/\r/g, '').trim()
compareAndWrite(t, actual, expected, filename) compareAndWrite(actual, expected, filename)
} }
function testFiles(t, files, options) { /**
t.plan(files.length) * @param files
* @param options
*/
function testFiles(files, options) {
files.forEach(testFile => { files.forEach(testFile => {
check(t, { check({
source: testFile, source: testFile,
expected: `${testFile}.js`, expected: `${testFile}.js`,
options options
@ -28,28 +34,30 @@ module.exports = {
}) })
} }
test('rt-if with rt-scope test', t => { describe('utils', () => {
describe('#convertText', () => {
it('rt-if with rt-scope test', () => {
const files = ['if-with-scope/valid-if-scope.rt'] const files = ['if-with-scope/valid-if-scope.rt']
const options = {modules: 'amd'} const options = {modules: 'amd'}
testFiles(t, files, options) testFiles(files, options)
}) })
test('conversion test', t => { it('conversion test', () => {
const files = ['div.rt', 'test.rt', 'repeat.rt', 'repeat-with-index.rt', 'inputs.rt', 'virtual.rt', 'stateless.rt', 'style-vendor-prefix.rt', 'non-breaking-space.rt'] const files = ['div.rt', 'test.rt', 'repeat.rt', 'repeat-with-index.rt', 'inputs.rt', 'virtual.rt', 'stateless.rt', 'style-vendor-prefix.rt', 'non-breaking-space.rt']
const options = {modules: 'amd'} const options = {modules: 'amd'}
testFiles(t, files, options) testFiles(files, options)
}) })
test('autobinding conversion test', t => { it('autobinding conversion test', () => {
const options = { const options = {
modules: 'amd', modules: 'amd',
autobind: true autobind: true
} }
const files = ['autobind.rt'] const files = ['autobind.rt']
testFiles(t, files, options) testFiles(files, options)
}) })
test('prop template conversion test', t => { it('prop template conversion test', () => {
const options = { const options = {
propTemplates: { propTemplates: {
List: { List: {
@ -65,10 +73,10 @@ module.exports = {
'twoTemplates.rt', 'twoTemplates.rt',
'siblingTemplates.rt' 'siblingTemplates.rt'
].map(file => path.join('propTemplates', file)) ].map(file => path.join('propTemplates', file))
testFiles(t, files, options) testFiles(files, options)
}) })
test('conversion test - native', t => { it('conversion test - native', () => {
const options = { const options = {
propTemplates: { propTemplates: {
MyComp: { MyComp: {
@ -87,11 +95,10 @@ module.exports = {
{source: 'native/listViewTemplate.rt', expected: 'native/listViewTemplate.rt.v029.js', options: optionsNew}, {source: 'native/listViewTemplate.rt', expected: 'native/listViewTemplate.rt.v029.js', options: optionsNew},
{source: 'native/listViewAndCustomTemplate.rt', expected: 'native/listViewAndCustomTemplate.rt.v029.js', options: optionsNew} {source: 'native/listViewAndCustomTemplate.rt', expected: 'native/listViewAndCustomTemplate.rt.v029.js', options: optionsNew}
] ]
t.plan(files.length) files.forEach(check)
files.forEach(file => check(t, file))
}) })
test('convert div with all module types', t => { it('convert div with all module types', () => {
const files = [ const files = [
{source: 'div.rt', expected: 'div.rt.commonjs.js', options: {modules: 'commonjs'}}, {source: 'div.rt', expected: 'div.rt.commonjs.js', options: {modules: 'commonjs'}},
{source: 'div.rt', expected: 'div.rt.amd.js', options: {modules: 'amd', name: 'div'}}, {source: 'div.rt', expected: 'div.rt.amd.js', options: {modules: 'amd', name: 'div'}},
@ -100,26 +107,24 @@ module.exports = {
{source: 'div.rt', expected: 'div.rt.typescript.ts', options: {modules: 'typescript'}}, {source: 'div.rt', expected: 'div.rt.typescript.ts', options: {modules: 'typescript'}},
{source: 'div.rt', expected: 'div.rt.15.js', options: {targetVersion: '15.0.0', modules: 'amd'}} {source: 'div.rt', expected: 'div.rt.15.js', options: {targetVersion: '15.0.0', modules: 'amd'}}
] ]
t.plan(files.length) files.forEach(check)
files.forEach(file => check(t, file))
}) })
test('normalize whitespace', t => { it('normalize whitespace', () => {
const files = ['whitespace.rt'] const files = ['whitespace.rt']
const options = {normalizeHtmlWhitespace: true, modules: 'amd'} const options = {normalizeHtmlWhitespace: true, modules: 'amd'}
testFiles(t, files, options) testFiles(files, options)
}) })
test('convert comment with AMD and ES6 modules', t => { it('convert comment with AMD and ES6 modules', () => {
const files = [ const files = [
{source: 'comment.rt', expected: 'comment.rt.amd.js', options: {modules: 'amd'}}, {source: 'comment.rt', expected: 'comment.rt.amd.js', options: {modules: 'amd'}},
{source: 'comment.rt', expected: 'comment.rt.es6.js', options: {modules: 'es6'}} {source: 'comment.rt', expected: 'comment.rt.es6.js', options: {modules: 'es6'}}
] ]
t.plan(files.length) files.forEach(check)
files.forEach(file => check(t, file))
}) })
test('rt-require with all module types', t => { it('rt-require with all module types', () => {
const files = [ const files = [
{source: 'require.rt', expected: 'require.rt.commonjs.js', options: {modules: 'commonjs'}}, {source: 'require.rt', expected: 'require.rt.commonjs.js', options: {modules: 'commonjs'}},
{source: 'require.rt', expected: 'require.rt.amd.js', options: {modules: 'amd', name: 'div'}}, {source: 'require.rt', expected: 'require.rt.amd.js', options: {modules: 'amd', name: 'div'}},
@ -127,11 +132,10 @@ module.exports = {
{source: 'require.rt', expected: 'require.rt.es6.js', options: {modules: 'es6'}}, {source: 'require.rt', expected: 'require.rt.es6.js', options: {modules: 'es6'}},
{source: 'require.rt', expected: 'require.rt.typescript.ts', options: {modules: 'typescript'}} {source: 'require.rt', expected: 'require.rt.typescript.ts', options: {modules: 'typescript'}}
] ]
t.plan(files.length) files.forEach(check)
files.forEach(file => check(t, file))
}) })
test('rt-import with all module types', t => { it('rt-import with all module types', () => {
const files = [ const files = [
{source: 'import.rt', expected: 'import.rt.commonjs.js', options: {modules: 'commonjs'}}, {source: 'import.rt', expected: 'import.rt.commonjs.js', options: {modules: 'commonjs'}},
{source: 'import.rt', expected: 'import.rt.amd.js', options: {modules: 'amd', name: 'div'}}, {source: 'import.rt', expected: 'import.rt.amd.js', options: {modules: 'amd', name: 'div'}},
@ -139,20 +143,18 @@ module.exports = {
{source: 'import.rt', expected: 'import.rt.es6.js', options: {modules: 'es6'}}, {source: 'import.rt', expected: 'import.rt.es6.js', options: {modules: 'es6'}},
{source: 'import.rt', expected: 'import.rt.typescript.ts', options: {modules: 'typescript'}} {source: 'import.rt', expected: 'import.rt.typescript.ts', options: {modules: 'typescript'}}
] ]
t.plan(files.length) files.forEach(check)
files.forEach(file => check(t, file))
}) })
test('convert jsrt and test source results', t => { it('convert jsrt and test source results', () => {
const files = ['simple.jsrt'] const files = ['simple.jsrt']
t.plan(files.length)
files.forEach(file => { files.forEach(file => {
const filename = path.join(dataPath, file) const filename = path.join(dataPath, file)
const js = readFileNormalized(filename) const js = readFileNormalized(filename)
const expected = readFileNormalized(path.join(dataPath, file.replace('.jsrt', '.js'))) const expected = readFileNormalized(path.join(dataPath, file.replace('.jsrt', '.js')))
const actual = reactTemplates.convertJSRTToJS(js, context).replace(/\r/g, '').trim() const actual = reactTemplates.convertJSRTToJS(js, context).replace(/\r/g, '').trim()
compareAndWrite(t, actual, expected, filename) compareAndWrite(actual, expected, filename)
})
})
}) })
}) })
}
}

View File

@ -1,14 +0,0 @@
'use strict'
const rtStyle = require('../../src/rtStyle')
module.exports = {
runTests(test) {
test('test rtStyle', t => {
const text = '.text { background-color: #00346E; padding: 3px; }'
const expected = '{\n "text": {\n "backgroundColor": "#00346E",\n "padding": 3\n }\n}'
const actual = rtStyle.convertBody(text)
t.equal(actual, expected)
t.end()
})
}
}

12
test/src/rtStyle.unit.js Normal file
View File

@ -0,0 +1,12 @@
'use strict'
const assert = require('assert')
const rtStyle = require('../../src/rtStyle')
describe('rtStyle', () => {
it('should convertBody style successfully', () => {
const text = '.text { background-color: #00346E; padding: 3px; }'
const expected = '{\n "text": {\n "backgroundColor": "#00346E",\n "padding": 3\n }\n}'
const actual = rtStyle.convertBody(text)
assert.equal(actual, expected)
})
})

View File

@ -2,33 +2,32 @@
const context = require('../../src/context') const context = require('../../src/context')
const _ = require('lodash') const _ = require('lodash')
const path = require('path') const path = require('path')
const assert = require('assert')
module.exports = { describe('rtStyle', () => {
runTests(test, dataPath) { it('should convertBody style successfully', () => {
test('test context', t => { it('should convertBody style successfully', () => {
context.clear() context.clear()
t.equal(context.hasErrors(), false) assert.equal(context.hasErrors(), false)
context.error('hi', '', 1, 1) context.error('hi', '', 1, 1)
t.equal(context.hasErrors(), true) assert.equal(context.hasErrors(), true)
context.clear() context.clear()
t.equal(context.hasErrors(), false) assert.equal(context.hasErrors(), false)
t.end()
}) })
test('test shell', t => { it('test shell', () => {
const shell = require('../../src/shell') const shell = require('../../src/shell')
const newContext = _.cloneDeep(context) const newContext = _.cloneDeep(context)
let outputJSON = '' let outputJSON = ''
newContext.options.format = 'json' newContext.options.format = 'json'
newContext.report = function (text) { outputJSON = text } newContext.report = function (text) { outputJSON = text }
let r = shell.printResults(newContext) let r = shell.printResults(newContext)
t.equal(r, 0) assert.equal(r, 0)
context.error('hi', '', 1, 1) context.error('hi', '', 1, 1)
r = shell.printResults(newContext) r = shell.printResults(newContext)
t.equal(r, 1) assert.equal(r, 1)
const output = JSON.parse(outputJSON) const output = JSON.parse(outputJSON)
t.deepEqual(output, [{ assert.deepEqual(output, [{
column: 1, column: 1,
endOffset: -1, endOffset: -1,
file: null, file: null,
@ -39,15 +38,13 @@ module.exports = {
startOffset: -1 startOffset: -1
}]) }])
context.clear() context.clear()
t.end()
}) })
test('test shell', t => { it('test shell', () => {
const filename = path.join(dataPath, 'div.rt') const filename = path.join(dataPath, 'div.rt')
const cli = require('../../src/cli') const cli = require('../../src/cli')
const r = cli.execute(`${filename} -r --dry-run`) const r = cli.execute(`${filename} -r --dry-run`)
t.equal(r, 0) assert.equal(r, 0)
t.end() })
})
}) })
}
}

View File

@ -1,10 +0,0 @@
'use strict'
const test = require('tape')
const path = require('path')
const dataPath = path.resolve(__dirname, '..', 'data')
const specs = ['rt.invalid', 'rt.valid', 'rt-html-valid', 'utils', 'shell', 'rtStyle', 'fsUtil']
specs
.map(file => require(`./${file}.spec`))
.forEach(spec => spec.runTests(test, dataPath))

View File

@ -1,20 +0,0 @@
'use strict'
const utils = require('../../src/utils')
module.exports = {
runTests(test) {
test('test convertText', t => {
const texts = [
{input: '{}', expected: '()'},
{input: "a {'b'}", expected: '"a "+(\'b\')'}
]
t.plan(texts.length)
texts.forEach(check)
function check(testData) {
const r = utils.convertText({}, {}, testData.input)
t.equal(r, testData.expected)
}
})
}
}

30
test/src/utils.unit.js Normal file
View File

@ -0,0 +1,30 @@
'use strict'
const assert = require('assert')
const utils = require('../../src/utils')
describe('utils', () => {
describe('#convertText', () => {
it('should convert text successfully', () => {
const texts = [
{input: '{}', expected: '()'},
{input: "a {'b'}", expected: '"a "+(\'b\')'}
]
texts.forEach(check)
function check(testData) {
const r = utils.convertText({}, {}, testData.input)
assert.equal(r, testData.expected)
}
})
it('should fail', () => {
const texts = [
{input: '() => {}', expected: '"() => "+()'}
]
texts.forEach(check)
function check(testData) {
const r = utils.convertText({}, {}, testData.input)
assert.equal(r, testData.expected)
}
})
})
})

View File

@ -2,10 +2,11 @@
const cheerio = require('cheerio') const cheerio = require('cheerio')
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const reactTemplates = require('../../src/reactTemplates') const reactTemplates = require('../../../src/reactTemplates')
const React = require('react') const React = require('react')
const ReactDOMServer = require('react-dom/server') const ReactDOMServer = require('react-dom/server')
const _ = require('lodash') const _ = require('lodash')
const assert = require('assert')
/** /**
* @param {string} html * @param {string} html
@ -25,8 +26,8 @@ function normalizeHtml(html) {
* @param {string} filename * @param {string} filename
* @return {boolean} whether actual is equal to expected * @return {boolean} whether actual is equal to expected
*/ */
function compareAndWrite(t, actual, expected, filename) { function compareAndWrite(actual, expected, filename) {
t.equal(actual, expected, filename) assert.equal(actual, expected, filename)
if (actual !== expected) { if (actual !== expected) {
fs.writeFileSync(`${filename}.actual.js`, actual) fs.writeFileSync(`${filename}.actual.js`, actual)
return false return false

View File

@ -5,11 +5,10 @@
module.exports = function (/*wallaby*/) { module.exports = function (/*wallaby*/) {
return { return {
files: [ files: [
'src/**/*.js' 'src/**/*.js',
// {pattern: 'lib/data/*.*', instrument: false}, 'test/src/utils/**/*.js',
// 'lib/formatters/*.js', {pattern: 'test/data/**/*', instrument: false},
// {pattern: 'test/testData/**/*.*', instrument: false}, {pattern: 'package.json', instrument: false}
// {pattern: 'test/src/utils/*.js', instrument: false}
], ],
tests: [ tests: [
'test/**/*.unit.js' 'test/**/*.unit.js'