diff --git a/tests/test-runner.js b/tests/test-runner.js
index 0b1cdd4..857f385 100644
--- a/tests/test-runner.js
+++ b/tests/test-runner.js
@@ -1,448 +1,101 @@
-var passCount = 0;
-var failCount = 0;
-var testCount = 0;
+var assert = chai.assert;
-$(function()
-{
- // First, wireup!
- $('.results').on('click', 'td.rvl', function()
- {
- var tr = $(this).closest('tr');
- if (tr.hasClass('collapsed'))
- {
- $('.revealer', tr).hide();
- $('.hidden', tr).show();
- $(this).html("-");
- }
- else
- {
- $('.revealer', tr).show();
- $('.hidden', tr).hide();
- $(this).html("+");
- }
- tr.toggleClass('collapsed expanded');
- });
- $('.expand-all').click(function()
- {
- var $testGroup = $(this).closest('.test-group');
- $('.collapsed .rvl', $testGroup).click();
- });
-
- $('.collapse-all').click(function()
- {
- var $testGroup = $(this).closest('.test-group');
- $('.expanded .rvl', $testGroup).click();
- });
-
- function asyncDone()
- {
- // Finally, show the overall status.
- if (failCount == 0)
- $('#status').addClass('status-pass').html("All " + passCount + " test" + (passCount == 1 ? "" : "s") + " passed");
- else
- $('#status').addClass('status-fail').html("" + failCount + " test" + (failCount == 1 ? "" : "s") + " failed; " + passCount + " passed");
+// Generates all tests from CORE_PARSER_TESTS in test-cases.js
+describe('Core Parser Tests', function() {
+ function generateTest(test) {
+ (test.disabled ? it.skip : it)(test.description, function() {
+ var actual = new Papa.Parser(test.config).parse(test.input);
+ assert.deepEqual(JSON.stringify(actual.errors), JSON.stringify(test.expected.errors));
+ assert.deepEqual(actual.data, test.expected.data);
+ });
}
- // Next, run tests and render results!
- runCoreParserTests();
- runParseTests(asyncDone);
- runUnparseTests();
- runCustomTests(asyncDone);
-
+ for (var i = 0; i < CORE_PARSER_TESTS.length; i++) {
+ generateTest(CORE_PARSER_TESTS[i]);
+ }
});
-// Executes all tests in CORE_PARSER_TESTS from test-cases.js
-// and renders results in the table.
-function runCoreParserTests()
-{
- for (var i = 0; i < CORE_PARSER_TESTS.length; i++)
- {
- var test = CORE_PARSER_TESTS[i];
- var passed = runTest(test);
- if (passed)
- passCount++;
- else
- failCount++;
- }
-
- function runTest(test)
- {
- var actual = new Papa.Parser(test.config).parse(test.input);
- var results = compare(actual.data, actual.errors, test.expected);
- displayResults('#tests-for-core-parser', test, actual, results);
- return results.data.passed && results.errors.passed
+// Generates all tests from PARSE_TESTS in test-cases.js
+describe('Parse Tests', function() {
+ function generateTest(test) {
+ (test.disabled ? it.skip : it)(test.description, function() {
+ var actual = Papa.parse(test.input, test.config);
+ assert.deepEqual(JSON.stringify(actual.errors), JSON.stringify(test.expected.errors));
+ assert.deepEqual(actual.data, test.expected.data);
+ });
}
-}
-
-// Executes all tests in PARSE_TESTS from test-cases.js
-// and renders results in the table.
-function runParseTests(asyncDone)
-{
- for (var i = 0; i < PARSE_TESTS.length; i++)
- {
- var test = PARSE_TESTS[i];
- var passed = runTest(test);
- if (passed)
- passCount++;
- else
- failCount++;
+ for (var i = 0; i < PARSE_TESTS.length; i++) {
+ generateTest(PARSE_TESTS[i]);
}
+});
- var asyncRemaining = 0;
-
- PARSE_ASYNC_TESTS.forEach(function(test)
- {
- if (test.disabled)
- return;
- asyncRemaining++;
- var config = test.config;
- config.complete = function(actual)
- {
- var results = compare(actual.data, actual.errors, test.expected);
-
- displayResults("#tests-for-parse", test, actual, results);
-
- if (results.data.passed && results.errors.passed) {
- passCount++;
- } else {
- failCount++;
- }
- if (--asyncRemaining === 0) {
- asyncDone();
- }
- };
-
- config.error = function(err)
- {
- failCount++;
- displayResults("#tests-for-parse", test, {data:[],errors:err}, test.expected);
- if (--asyncRemaining === 0) {
- asyncDone();
- }
- };
-
- Papa.parse(test.input, config);
- });
-
-
- function runTest(test)
- {
- var actual = Papa.parse(test.input, test.config);
- var results = compare(actual.data, actual.errors, test.expected);
- displayResults('#tests-for-parse', test, actual, results);
- return results.data.passed && results.errors.passed
- }
-}
-
-
-
-
-
-function displayResults(tableId, test, actual, results)
-{
- var testId = testCount++;
-
- var testDescription = (test.description || "");
- if (testDescription.length > 0)
- testDescription += '
';
- if (test.notes)
- testDescription += '' + test.notes + '';
-
- var tr = '
'
- + '+ | '
- + '' + testDescription + ' | '
- + passOrFailTd(results.data)
- + passOrFailTd(results.errors)
- + 'condensed ' + JSON.stringify(test.config, null, 2) + ' | '
- + 'condensed ' + revealChars(test.input) + ' | '
- + 'condensed data: ' + JSON.stringify(test.expected.data, null, 4) + '\r\nerrors: ' + JSON.stringify(test.expected.errors, null, 4) + ' | '
- + 'condensed data: ' + JSON.stringify(actual.data, null, 4) + '\r\nerrors: ' + JSON.stringify(actual.errors, null, 4) + ' | '
- + '
';
-
- $(tableId+' .results').append(tr);
-
- if (!results.data.passed || !results.errors.passed)
- $('#test-'+testId+' td.rvl').click();
-
-}
-
-
-function compare(actualData, actualErrors, expected)
-{
- var data = compareData(actualData, expected.data);
- var errors = compareErrors(actualErrors, expected.errors);
-
- return {
- data: data,
- errors: errors
- };
-
-
- function compareData(actual, expected)
- {
- var passed = true;
-
- if (actual.length != expected.length)
- passed = false;
- else
- {
- // The order is important, so we go through manually before using stringify to check everything else
- for (var row = 0; row < expected.length; row++)
- {
- if (actual[row].length != expected[row].length)
- {
- passed = false;
- break;
- }
- for (var col = 0; col < expected[row].length; col++)
- {
- var expectedVal = expected[row][col];
- var actualVal = actual[row][col];
+// Generates all tests from PARSE_ASYNC_TESTS in test-cases.js
+describe('Parse Async Tests', function() {
+ function generateTest(test) {
+ (test.disabled ? it.skip : it)(test.description, function(done) {
+ var config = test.config;
- if (actualVal !== expectedVal)
- {
- passed = false;
- break;
- }
- }
- }
- }
+ config.complete = function(actual) {
+ assert.deepEqual(JSON.stringify(actual.errors), JSON.stringify(test.expected.errors));
+ assert.deepEqual(actual.data, test.expected.data);
+ done();
+ };
- if (passed) // final check will catch any other differences
- passed = JSON.stringify(actual) == JSON.stringify(expected);
+ config.error = function(err) {
+ throw err;
+ };
- // We pass back an object right now, even though it only contains
- // one value, because we might add details to the test results later
- // (same with compareErrors below)
- return {
- passed: passed
- };
+ Papa.parse(test.input, config);
+ });
}
-
- function compareErrors(actual, expected)
- {
- var passed = JSON.stringify(actual) == JSON.stringify(expected);
-
- return {
- passed: passed
- };
+ for (var i = 0; i < PARSE_ASYNC_TESTS.length; i++) {
+ generateTest(PARSE_ASYNC_TESTS[i]);
}
-}
-
-
-
-
+});
-// Executes all tests in UNPARSE_TESTS from test-cases.js
-// and renders results in the table.
-function runUnparseTests()
-{
- for (var i = 0; i < UNPARSE_TESTS.length; i++)
- {
- var test = UNPARSE_TESTS[i];
- var passed = runTest(test);
- if (passed)
- passCount++;
- else
- failCount++;
- }
- function runTest(test)
- {
- var actual;
+// Generates all tests from UNPARSE_TESTS in test-cases.js
+describe('Unparse Tests', function() {
+ function generateTest(test) {
+ (test.disabled ? it.skip : it)(test.description, function() {
+ var actual;
- try
- {
- actual = Papa.unparse(test.input, test.config);
- }
- catch (e)
- {
- if (e instanceof Error) {
- throw e;
+ try {
+ actual = Papa.unparse(test.input, test.config);
+ } catch (e) {
+ if (e instanceof Error) {
+ throw e;
+ }
+ actual = e;
}
- actual = e;
- }
-
- var testId = testCount++;
- var results = compare(actual, test.expected);
-
- var testDescription = (test.description || "");
- if (testDescription.length > 0)
- testDescription += '
';
- if (test.notes)
- testDescription += '' + test.notes + '';
-
- var tr = ''
- + '+ | '
- + '' + testDescription + ' | '
- + passOrFailTd(results)
- + 'condensed ' + JSON.stringify(test.config, null, 2) + ' | '
- + 'condensed ' + JSON.stringify(test.input, null, 4) + ' | '
- + 'condensed ' + revealChars(test.expected) + ' | '
- + 'condensed ' + revealChars(actual) + ' | '
- + '
';
-
- $('#tests-for-unparse .results').append(tr);
-
- if (!results.passed)
- $('#test-' + testId + ' td.rvl').click();
-
- return results.passed;
- }
-
- function compare(actual, expected)
- {
- return {
- passed: actual === expected
- };
- }
-}
-
-
-
-
-// Executes all tests in CUSTOM_TESTS from test-cases.js
-// and renders results in the table.
-function runCustomTests(asyncDone)
-{
- var asyncRemaining = 0;
- for (var i = 0; i < CUSTOM_TESTS.length; i++)
- {
- runTest(CUSTOM_TESTS[i]);
+ assert.strictEqual(actual, test.expected);
+ });
}
- function runTest(test)
- {
- if (test.disabled)
- return;
- asyncRemaining++;
- try
- {
- displayAsyncTest(test);
- }
- catch (e)
- {
- displayResults(test, e);
- }
+ for (var i = 0; i < UNPARSE_TESTS.length; i++) {
+ generateTest(UNPARSE_TESTS[i]);
}
+});
- function displayAsyncTest(test)
- {
- var testId = testCount++;
- test.testId = testId;
-
- var testDescription = (test.description || "");
- if (testDescription.length > 0)
- testDescription += '
';
- if (test.notes)
- testDescription += '' + test.notes + '';
-
- var tr = ''
- + '+ | '
- + '' + testDescription + ' | '
- + 'pending | '
- + 'condensed ' + test.expected + ' | '
- + 'condensed | '
- + '
';
-
- $('#custom-tests .results').append(tr);
- test.run(function(actual)
- {
- displayAsyncResults(test, actual);
+// Generates all tests from CUSTOM_TESTS in test-cases.js
+describe('Custom Tests', function() {
+ function generateTest(test) {
+ (test.disabled ? it.skip : it)(test.description, function(done) {
+ test.run(function (actual) {
+ assert.deepEqual(JSON.stringify(actual), JSON.stringify(test.expected));
+ done();
+ });
});
-
- setTimeout(function()
- {
- if (test.complete) return;
- displayAsyncResults(test, '(incomplete)');
- }, 2000);
}
- function displayAsyncResults(test, actual)
- {
- var testId = test.testId;
- if (test.complete)
- {
- asyncRemaining++;
- actual = '(multiple results from test)';
- }
- test.complete = true;
- var results = compare(actual, test.expected);
-
- var tr = $('#test-'+testId);
- tr.find('.actual').text(actual);
-
- var status = $(passOrFailTd(results));
- var oldStatus = tr.find('.status');
- oldStatus.attr('class', status.attr('class'));
- oldStatus.text(status.text());
-
- if (!results.passed)
- $('#test-' + testId + ' td.rvl').click();
-
- if (results.passed)
- passCount++;
- else
- failCount++;
-
- if (--asyncRemaining === 0)
- asyncDone();
- }
-
-
- function compare(actual, expected)
- {
- return {
- passed: JSON.stringify(actual) === JSON.stringify(expected)
- };
+ for (var i = 0; i < CUSTOM_TESTS.length; i++) {
+ generateTest(CUSTOM_TESTS[i]);
}
-}
-
-
-
-
-
-
-
-
-// Makes a TD tag with OK or FAIL depending on test result
-function passOrFailTd(result)
-{
- if (result.passed)
- return 'OK | ';
- else
- return 'FAIL | ';
-}
-
-
-// Reveals some hidden, whitespace, or invisible characters
-function revealChars(txt)
-{
- if (typeof txt != 'string')
- return '(file)';
-
- // Make spaces and tabs more obvious when glancing
- txt = txt.replace(/( |\t)/ig, '$1');
- txt = txt.replace(/(\r\n|\n\r|\r|\n)/ig, '$1$1');
-
- // Make UNIT_SEP and RECORD_SEP characters visible
- txt = txt.replace(/(\u001e|\u001f)/ig, '$1$1');
-
- // Now make the whitespace and invisible characters
- // within the spans actually appear on the page
- txt = txt.replace(/">\r\n<\/span>/ig, '">\\r\\n');
- txt = txt.replace(/">\n\r<\/span>/ig, '">\\n\\r');
- txt = txt.replace(/">\r<\/span>/ig, '">\\r');
- txt = txt.replace(/">\n<\/span>/ig, '">\\n');
- txt = txt.replace(/">\u001e<\/span>/ig, '">\\u001e');
- txt = txt.replace(/">\u001f<\/span>/ig, '">\\u001f');
-
- return txt;
-}
+});
diff --git a/tests/tests.css b/tests/tests.css
deleted file mode 100644
index 1c59cab..0000000
--- a/tests/tests.css
+++ /dev/null
@@ -1,173 +0,0 @@
-/* Eric Meyer's Reset CSS v2.0 */
-html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
-
-body {
- background: #F0F0F0;
- font: 14px 'Helvetica Neue', sans-serif;
- color: #333;
- padding: 30px 15px;
-}
-
-a {
- color: rgb(0, 142, 236);
-}
-
-a:hover {
- color: rgb(82, 186, 255);
-}
-
-b {
- font-weight: bold;
-}
-
-i {
- font-style: italic;
-}
-
-h1 {
- text-align: center;
- font-weight: bold;
- font-size: 62px;
- margin-bottom: 30px;
-}
-
-h2 {
- text-align: center;
- font-weight: bold;
- font-size: 26px;
- margin-bottom: 20px;
-}
-
-.status-pass,
-.status-fail {
- padding: 10px;
- margin-bottom: 30px;
- color: #FFF;
- text-align: center;
- text-transform: uppercase;
- font-size: 18px;
- letter-spacing: 1px;
- font-weight: 100;
-}
-
-.status-pass {
- background: rgb(3, 168, 3);
-}
-
-.status-fail {
- background: #BB0000;
-}
-
-.test-group {
- margin-bottom: 50px;
-}
-
-table {
- width: 100%;
- border-collapse: collapse;
- margin-top: 5px;
-}
-
-table th,
-table td {
- padding: 5px;
- border: 1px solid #BBB;
-}
-
-table th {
- color: #000;
- background: #DDD;
- font-weight: bold;
- padding: 10px 5px;
- text-transform: uppercase;
-}
-
-table td {
- background: #FFF;
- color: #555;
- font-size: 14px;
-}
-
-td.status {
- text-transform: uppercase;
- font-weight: 300;
- vertical-align: middle;
- text-align: center;
- width: 80px;
-}
-
-td.ok {
- background: rgb(204, 250, 144);
-}
-
-td.fail {
- background: rgb(255, 192, 192);
-}
-
-td.pending {
- background: rgb(255, 255, 150);
-}
-
-td.rvl {
- background: #444;
- color: #999;
- vertical-align: middle;
- text-align: center;
- cursor: pointer;
- width: 20px;
-}
-
-td.rvl:hover {
- color: #FFF;
-}
-
-tr.collapsed td.revealable {
- background: #ECECEC;
- vertical-align: middle;
- text-align: center;
- font-family: 'Helvetica Neue', sans-serif;
- text-transform: lowercase;
- color: #AAA;
-}
-
-tr.expanded .revealer {
- font-family: 'Helvetica Neue', sans-serif;
- text-transform: lowercase;
- font-size: 10px;
- background: #FFF;
- position: absolute;
- display: block;
- padding: 3px;
- top: -5px;
- right: -5px;
-}
-
-td .container {
- position: relative;
-}
-
-.notes {
- color: #888;
- font-size: 12px;
-}
-
-.pre {
- font-family: Menlo, Monaco, monospace;
- white-space: pre-wrap;
-}
-
-td.pre {
- font-size: 12px;
-}
-
-.hidden {
- display: none;
-}
-
-.special-char {
- color: #78B7E7;
-}
-
-.whitespace-char {
- background: #D5FCFA;
-}
diff --git a/tests/tests.html b/tests/tests.html
index 60d2342..049ef26 100644
--- a/tests/tests.html
+++ b/tests/tests.html
@@ -1,113 +1,25 @@
-
Papa Parse Tests
-
+
+
+
+
+
+
- Papa Parse Tests
-
-
-
-
-
-
Core Parser Tests
-
-
Expand all
- ·
-
Collapse all
-
-
-
-
- Test Case |
- Data |
- Errors |
- Config |
- Input |
- Expected |
- Actual |
-
-
-
-
-
-
-
-
Papa.parse() Wrapper Tests
-
-
Expand all
- ·
-
Collapse all
-
-
-
-
- Test Case |
- Data |
- Errors |
- Config |
- Input |
- Expected |
- Actual |
-
-
-
-
-
-
-
-
-
-
-
Papa.unparse() Tests
-
-
Expand all
- ·
-
Collapse all
-
-
-
-
- Test Case |
- Data |
- Config |
- Input |
- Expected |
- Actual |
-
-
-
-
-
-
-
-
-
-
-
-
+
+