From 2e339829677c74a05aa8532cbfc1961e90aade65 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 12:36:51 -0800 Subject: [PATCH 01/37] Testing Travis ci --- .travis.yml | 4 +++ test/assert.js | 46 +++++++++++++++++++++++++++++++++ test/runner.js | 63 +++++++++++++++++++++++++++++++++++++++++++++ test/test_page.html | 11 ++++++++ test/tests.js | 27 +++++++++++++++++++ 5 files changed, 151 insertions(+) create mode 100644 .travis.yml create mode 100644 test/assert.js create mode 100644 test/runner.js create mode 100644 test/test_page.html create mode 100644 test/tests.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..eb6fa88 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +before_install: + - sudo npm install phantomjs + +script: phantomjs runner.js diff --git a/test/assert.js b/test/assert.js new file mode 100644 index 0000000..a0cdee4 --- /dev/null +++ b/test/assert.js @@ -0,0 +1,46 @@ +/* + * Copyright 2015 Eric Radman + */ + +function assert(a, b) { + var fn = arguments.callee.caller.name; + if (!fn) + fn = String(arguments.callee.caller); + if (!deepEq(a, b)) throw new Error("in " + fn + "\n" + a + " != " + b); +} + +/* + * Copyright 2013 Serge A. Zaitsev + * See LICENSE file for details + */ + +function deepEq(a, b) { + if (typeof a !== typeof b) { + return false; + } + if (a instanceof Function) { + return a.toString() === b.toString(); + } + if (a === b || a.valueOf() === b.valueOf()) { + return true; + } + if (!(a instanceof Object)) { + return false; + } + var ka = Object.keys(a); + if (ka.length != Object.keys(b).length) { + return false; + } + for (var i in b) { + if (!b.hasOwnProperty(i)) { + continue; + } + if (ka.indexOf(i) === -1) { + return false; + } + if (!deepEq(a[i], b[i])) { + return false; + } + } + return true; +} diff --git a/test/runner.js b/test/runner.js new file mode 100644 index 0000000..7538ea2 --- /dev/null +++ b/test/runner.js @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 Eric Radman + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* phantomjs page setup */ + +var page = require('webpage').create(); + +page.onError = function(msg, trace) { + /* inject a line number into the error message raised by assert() */ + if (trace.length > 1) + console.error(msg.replace(/: in /, + " in line " + (parseInt(trace[1].line)-1) + " of ")); + else + console.error("line " + (parseInt(trace[0].line)-1) + ": " + msg); + phantom.exit(1); +}; + +page.onConsoleMessage = function(msg) { + console.log(msg); +}; + +/* read html_fixture, sources[], tests[] */ +phantom.injectJs('./tests.js') + +/* test runner */ + +page.open(html_fixture, function(status) { + if( status !== "success" ){ + console.log("Error loading page"); + phantom.exit(1); + } + var _content = page.content; + /* iterate over the tests, resetting page content each time */ + tests.forEach(function(test_function) { + page.content = _content; + /* activate javascript on the refreshed page */ + sources.forEach(function(file) { + if (!page.injectJs(file)) + throw new Error("Unable to load '" + file + "'"); + }); + /* execute test in the page context */ + page.evaluate(test_function); + }); + /* pause to allow tests with timers to complete */ + setTimeout(function() { + console.log(tests.length + " tests PASSED"); + phantom.exit(0); + }, 200); + console.log(Array(tests.length+1).join('.')); +}); diff --git a/test/test_page.html b/test/test_page.html new file mode 100644 index 0000000..7fa8454 --- /dev/null +++ b/test/test_page.html @@ -0,0 +1,11 @@ + + +Test Fixture + + +
+ + diff --git a/test/tests.js b/test/tests.js new file mode 100644 index 0000000..0f808c1 --- /dev/null +++ b/test/tests.js @@ -0,0 +1,27 @@ +var html_fixture = "test_page.html"; +var sources = ["./assert.js"]; +var tests = []; + +tests.push(function count_chart_elements () { + document.getElementsByClassName('chart')[0].id = "bogus"; + assert(document.getElementsByClassName('chart').length, 1); +}) + +tests.push(function get_chart_div () { + assert(document.getElementsByClassName('chart')[0].id, + "chart_60eb0dc5-6b41-4ca1-94d0-1760c1f3d87b"); +}) + +tests.push(function compare_lists () { + assert([1, 3, 5, 3, 7], [1, 3, 5, 7]); +}) + +tests.push(function compare_maps () { + assert({'one': 1, 'two': 2}, {'two': 2, 'one': 1}); +}) + +tests.push(function delayed_assert () { + setTimeout(function() { + assert(1 / 0, Infinity); + }, 100) +}) From ec5e05c405a60279390117ff6390a85f0320e8b1 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 12:42:16 -0800 Subject: [PATCH 02/37] Update .travis.yml to (try to) get travis work --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eb6fa88..1f59dfc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,8 @@ -before_install: +language: node_js +node_js: + - "6.1" + +install: - sudo npm install phantomjs script: phantomjs runner.js From eeac626fd351714235a9b2e2dff39d2aeb2bc1be Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 12:45:23 -0800 Subject: [PATCH 03/37] Another try to get travis work --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1f59dfc..3c35c71 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: node_js node_js: - "6.1" -install: +before_script: - sudo npm install phantomjs script: phantomjs runner.js From b3ee4366add6359109e60bd08e3d4667b3214dca Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 12:47:25 -0800 Subject: [PATCH 04/37] Maybe removing sudo will work --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3c35c71..a2bf26f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,6 @@ node_js: - "6.1" before_script: - - sudo npm install phantomjs + - npm install phantomjs script: phantomjs runner.js From 3d59fc673ae41428c05da660ed0567b8fb0ad4a7 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 12:49:18 -0800 Subject: [PATCH 05/37] Modifying the path of the phantomjs runner --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a2bf26f..097744a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,4 @@ node_js: before_script: - npm install phantomjs -script: phantomjs runner.js +script: phantomjs test/runner.js From 15f939b83d190c8663aa7d3db00c73a2a48006f7 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 13:04:38 -0800 Subject: [PATCH 06/37] Pushing a commit that is supposed to be failing --- .travis.yml | 2 +- test/runner.js | 63 -------------------------------------------------- test/tests.js | 4 ++-- 3 files changed, 3 insertions(+), 66 deletions(-) delete mode 100644 test/runner.js diff --git a/.travis.yml b/.travis.yml index 097744a..aba127f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,4 @@ node_js: before_script: - npm install phantomjs -script: phantomjs test/runner.js +script: phantomjs test_runner.js diff --git a/test/runner.js b/test/runner.js deleted file mode 100644 index 7538ea2..0000000 --- a/test/runner.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2015 Eric Radman - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* phantomjs page setup */ - -var page = require('webpage').create(); - -page.onError = function(msg, trace) { - /* inject a line number into the error message raised by assert() */ - if (trace.length > 1) - console.error(msg.replace(/: in /, - " in line " + (parseInt(trace[1].line)-1) + " of ")); - else - console.error("line " + (parseInt(trace[0].line)-1) + ": " + msg); - phantom.exit(1); -}; - -page.onConsoleMessage = function(msg) { - console.log(msg); -}; - -/* read html_fixture, sources[], tests[] */ -phantom.injectJs('./tests.js') - -/* test runner */ - -page.open(html_fixture, function(status) { - if( status !== "success" ){ - console.log("Error loading page"); - phantom.exit(1); - } - var _content = page.content; - /* iterate over the tests, resetting page content each time */ - tests.forEach(function(test_function) { - page.content = _content; - /* activate javascript on the refreshed page */ - sources.forEach(function(file) { - if (!page.injectJs(file)) - throw new Error("Unable to load '" + file + "'"); - }); - /* execute test in the page context */ - page.evaluate(test_function); - }); - /* pause to allow tests with timers to complete */ - setTimeout(function() { - console.log(tests.length + " tests PASSED"); - phantom.exit(0); - }, 200); - console.log(Array(tests.length+1).join('.')); -}); diff --git a/test/tests.js b/test/tests.js index 0f808c1..43065f3 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1,5 +1,5 @@ -var html_fixture = "test_page.html"; -var sources = ["./assert.js"]; +var html_fixture = "./test/test_page.html"; +var sources = ["./test/assert.js"]; var tests = []; tests.push(function count_chart_elements () { From ea7838413eb9cc308e3bb67c1633e30f312b9f0c Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 13:08:34 -0800 Subject: [PATCH 07/37] Trying to figure out why travis didn't find test_runner --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index aba127f..bb1a87d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,6 @@ node_js: before_script: - npm install phantomjs -script: phantomjs test_runner.js +script: + - ls -lR + - phantomjs test_runner.js From 80ca438663c8ac78b1761570289d53287f81c429 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 13:10:36 -0800 Subject: [PATCH 08/37] Adding the file that is missing .... --- test_runner.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 test_runner.js diff --git a/test_runner.js b/test_runner.js new file mode 100644 index 0000000..022abb6 --- /dev/null +++ b/test_runner.js @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 Eric Radman + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* phantomjs page setup */ + +var page = require('webpage').create(); + +page.onError = function(msg, trace) { + /* inject a line number into the error message raised by assert() */ + if (trace.length > 1) + console.error(msg.replace(/: in /, + " in line " + (parseInt(trace[1].line)-1) + " of ")); + else + console.error("line " + (parseInt(trace[0].line)-1) + ": " + msg); + phantom.exit(1); +}; + +page.onConsoleMessage = function(msg) { + console.log(msg); +}; + +/* read html_fixture, sources[], tests[] */ +phantom.injectJs('./test/tests.js') + +/* test runner */ + +page.open(html_fixture, function(status) { + if( status !== "success" ){ + console.log("Error loading page"); + phantom.exit(1); + } + var _content = page.content; + /* iterate over the tests, resetting page content each time */ + tests.forEach(function(test_function) { + page.content = _content; + /* activate javascript on the refreshed page */ + sources.forEach(function(file) { + if (!page.injectJs(file)) + throw new Error("Unable to load '" + file + "'"); + }); + /* execute test in the page context */ + page.evaluate(test_function); + }); + /* pause to allow tests with timers to complete */ + setTimeout(function() { + console.log(tests.length + " tests PASSED"); + phantom.exit(0); + }, 200); + console.log(Array(tests.length+1).join('.')); +}); From c69e34a31dc08d9c94733a955817a18658104a3b Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 13:12:52 -0800 Subject: [PATCH 09/37] This commit is supposed to pass all the tests --- .travis.yml | 1 - test/tests.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb1a87d..c658b1a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,5 +6,4 @@ before_script: - npm install phantomjs script: - - ls -lR - phantomjs test_runner.js diff --git a/test/tests.js b/test/tests.js index 43065f3..f3ceb6a 100644 --- a/test/tests.js +++ b/test/tests.js @@ -13,7 +13,7 @@ tests.push(function get_chart_div () { }) tests.push(function compare_lists () { - assert([1, 3, 5, 3, 7], [1, 3, 5, 7]); + assert([1, 3, 5, 7], [1, 3, 5, 7]); }) tests.push(function compare_maps () { From cb7fd2fcd0a0a99655bebcbbacecc1cfc5b63a50 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Thu, 2 Feb 2017 14:46:22 -0800 Subject: [PATCH 10/37] Start working on migrating tests --- test/LICENSE | 39 ++++++++++++++++++++++++++++++++++ test/assert-old.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++ test/assert.js | 12 ++++++----- test/tests-old.js | 32 ++++++++++++++++++++++++++++ test/tests.js | 19 ++++++++++------- test_runner.js | 18 +++++++++------- 6 files changed, 151 insertions(+), 21 deletions(-) create mode 100644 test/LICENSE create mode 100644 test/assert-old.js create mode 100644 test/tests-old.js diff --git a/test/LICENSE b/test/LICENSE new file mode 100644 index 0000000..805a1ae --- /dev/null +++ b/test/LICENSE @@ -0,0 +1,39 @@ +Source code for `phantom-assert` is licensed under an ISC-style license, to the +following copyright holders: + +Copyright 2015 Eric Radman + +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +The function `deepEq` is borrowed from `klud.js` and is licensed under a +MIT-style license to the following copyright holders: + +Copyright 2013 Serge A. Zaitsev + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/test/assert-old.js b/test/assert-old.js new file mode 100644 index 0000000..234303f --- /dev/null +++ b/test/assert-old.js @@ -0,0 +1,52 @@ +"use strict"; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +/* + * Copyright 2015 Eric Radman + * Modified by Runjie Guan + */ + +function assert(got, expected, error) { + if (!deepEq(got, expected)) { + throw new Error((error || "") + " \nExpected: " + expected + "\nGot: " + got); + } +} + +/* + * Copyright 2013 Serge A. Zaitsev + * See LICENSE file for details + */ + +function deepEq(a, b) { + if ((typeof a === "undefined" ? "undefined" : _typeof(a)) !== (typeof b === "undefined" ? "undefined" : _typeof(b))) { + return false; + } + if (a instanceof Function) { + return a.toString() === b.toString(); + } + if (a === b || a.valueOf() === b.valueOf()) { + return true; + } + if (!(a instanceof Object)) { + return false; + } + var ka = Object.keys(a); + if (ka.length != Object.keys(b).length) { + return false; + } + for (var i in b) { + if (!b.hasOwnProperty(i)) { + continue; + } + if (ka.indexOf(i) === -1) { + return false; + } + if (!deepEq(a[i], b[i])) { + return false; + } + } + return true; +} + +//# sourceMappingURL=assert-old.js.map \ No newline at end of file diff --git a/test/assert.js b/test/assert.js index a0cdee4..b53c78c 100644 --- a/test/assert.js +++ b/test/assert.js @@ -1,12 +1,14 @@ /* * Copyright 2015 Eric Radman + * Modified by Runjie Guan */ -function assert(a, b) { - var fn = arguments.callee.caller.name; - if (!fn) - fn = String(arguments.callee.caller); - if (!deepEq(a, b)) throw new Error("in " + fn + "\n" + a + " != " + b); +function assert(got, expected, error) { + if (!deepEq(got, expected)) { + throw new Error(`${error || ""} +Expected: ${expected} +Got: ${got}`); + } } /* diff --git a/test/tests-old.js b/test/tests-old.js new file mode 100644 index 0000000..eeb719c --- /dev/null +++ b/test/tests-old.js @@ -0,0 +1,32 @@ +"use strict"; + +var html_fixture = "./test/test_page.html"; +var sources = ["./test/assert-old.js"]; +var tests = [function () { + assert(2, 3, "tets"); +}]; + +tests.push(function count_chart_elements() { + document.getElementsByClassName('chart')[0].id = "bogus"; + assert(document.getElementsByClassName('chart').length, 1); +}); + +tests.push(function get_chart_div() { + assert(document.getElementsByClassName('chart')[0].id, "chart_60eb0dc5-6b41-4ca1-94d0-1760c1f3d87b"); +}); + +tests.push(function compare_lists() { + assert([1, 3, 5, 3, 7], [1, 3, 5, 7]); +}); + +tests.push(function compare_maps() { + assert({ 'one': 1, 'two': 2 }, { 'two': 2, 'one': 1 }); +}); + +tests.push(function delayed_assert() { + setTimeout(function () { + assert(1 / 0, Infinity); + }, 100); +}); + +//# sourceMappingURL=tests-old.js.map \ No newline at end of file diff --git a/test/tests.js b/test/tests.js index f3ceb6a..746e56b 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1,26 +1,29 @@ var html_fixture = "./test/test_page.html"; -var sources = ["./test/assert.js"]; -var tests = []; +var sources = ["./test/assert-old.js"]; +var tests = [function() { + assert(2, 3, "tets"); +}]; -tests.push(function count_chart_elements () { + +tests.push(function count_chart_elements() { document.getElementsByClassName('chart')[0].id = "bogus"; assert(document.getElementsByClassName('chart').length, 1); }) -tests.push(function get_chart_div () { +tests.push(function get_chart_div() { assert(document.getElementsByClassName('chart')[0].id, "chart_60eb0dc5-6b41-4ca1-94d0-1760c1f3d87b"); }) -tests.push(function compare_lists () { - assert([1, 3, 5, 7], [1, 3, 5, 7]); +tests.push(function compare_lists() { + assert([1, 3, 5, 3, 7], [1, 3, 5, 7]); }) -tests.push(function compare_maps () { +tests.push(function compare_maps() { assert({'one': 1, 'two': 2}, {'two': 2, 'one': 1}); }) -tests.push(function delayed_assert () { +tests.push(function delayed_assert() { setTimeout(function() { assert(1 / 0, Infinity); }, 100) diff --git a/test_runner.js b/test_runner.js index 022abb6..5d7b005 100644 --- a/test_runner.js +++ b/test_runner.js @@ -20,11 +20,12 @@ var page = require('webpage').create(); page.onError = function(msg, trace) { /* inject a line number into the error message raised by assert() */ - if (trace.length > 1) + if (trace.length > 1) { console.error(msg.replace(/: in /, - " in line " + (parseInt(trace[1].line)-1) + " of ")); - else - console.error("line " + (parseInt(trace[0].line)-1) + ": " + msg); + " in line " + (parseInt(trace[1].line) - 1) + " of ")); + } else { + console.error("line " + (parseInt(trace[0].line) - 1) + ": " + msg); + } phantom.exit(1); }; @@ -33,12 +34,12 @@ page.onConsoleMessage = function(msg) { }; /* read html_fixture, sources[], tests[] */ -phantom.injectJs('./test/tests.js') +phantom.injectJs('./test/tests-old.js'); /* test runner */ page.open(html_fixture, function(status) { - if( status !== "success" ){ + if (status !== "success") { console.log("Error loading page"); phantom.exit(1); } @@ -48,8 +49,9 @@ page.open(html_fixture, function(status) { page.content = _content; /* activate javascript on the refreshed page */ sources.forEach(function(file) { - if (!page.injectJs(file)) + if (!page.injectJs(file)) { throw new Error("Unable to load '" + file + "'"); + } }); /* execute test in the page context */ page.evaluate(test_function); @@ -59,5 +61,5 @@ page.open(html_fixture, function(status) { console.log(tests.length + " tests PASSED"); phantom.exit(0); }, 200); - console.log(Array(tests.length+1).join('.')); + console.log(Array(tests.length + 1).join('.')); }); From 6f553ffaa13b397e74e5000193e3bf42c8cb053c Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Tue, 7 Feb 2017 10:43:07 -0800 Subject: [PATCH 11/37] This commit should fail all the tests --- .travis.yml | 2 +- test_runner.js => runner_test.js | 30 ++++++++++------- test/test_page.html | 57 +++++++++++++++++++++++++++++--- test/tests-old.js | 27 ++------------- test/tests.js | 28 ++-------------- 5 files changed, 77 insertions(+), 67 deletions(-) rename test_runner.js => runner_test.js (93%) diff --git a/.travis.yml b/.travis.yml index c658b1a..5073443 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,4 +6,4 @@ before_script: - npm install phantomjs script: - - phantomjs test_runner.js + - phantomjs runner_test.js diff --git a/test_runner.js b/runner_test.js similarity index 93% rename from test_runner.js rename to runner_test.js index 5d7b005..de2e48d 100644 --- a/test_runner.js +++ b/runner_test.js @@ -18,19 +18,8 @@ var page = require('webpage').create(); -page.onError = function(msg, trace) { - /* inject a line number into the error message raised by assert() */ - if (trace.length > 1) { - console.error(msg.replace(/: in /, - " in line " + (parseInt(trace[1].line) - 1) + " of ")); - } else { - console.error("line " + (parseInt(trace[0].line) - 1) + ": " + msg); - } - phantom.exit(1); -}; - page.onConsoleMessage = function(msg) { - console.log(msg); + console.log(123 + msg); }; /* read html_fixture, sources[], tests[] */ @@ -63,3 +52,20 @@ page.open(html_fixture, function(status) { }, 200); console.log(Array(tests.length + 1).join('.')); }); + +page.onError = function(msg, trace) { + console.log("here's an error"); + /* inject a line number into the error message raised by assert() */ + if (trace.length > 1) { + console.error(msg.replace(/: in /, + " in line " + (parseInt(trace[1].line) - 1) + " of ")); + } else { + console.error("line " + (parseInt(trace[0].line) - 1) + ": " + msg); + } + phantom.exit(1); +}; + +phantom.onError = function(msg) { + console.log("Here's another error"); + phantom.exit(1); +}; \ No newline at end of file diff --git a/test/test_page.html b/test/test_page.html index 7fa8454..a2f73c2 100644 --- a/test/test_page.html +++ b/test/test_page.html @@ -1,11 +1,58 @@ + -Test Fixture + + + YPet Demo + + -
+Fork me on GitHub +

By Max Nanis
at The Su Lab

+

The testing script is written by Runjie Guan

+ +
+ +
+
+
+
+
+

Click n' Drag on stuff!

+

YPet is a Javascript library to rapidly annotate paragraphs of text on websites with the goal of making the annotation process as fast and simple as possible.

+
+
+
+
+
+ +
+
+

BACKGROUND & AIMS The chromosome region 18q21 has been shown to be frequently deleted in colorectal cancers , and such frequent allelic loss is a hallmark of the presence of a tumor-suppressor gene . The DPC4 gene , which is located at 18q21 , has been identified as a tumor-suppressor gene from examination of pancreatic cancers . The aim of the present study was to determine if it might also be altered in colorectal cancers . METHODS Mutation analyses of the DPC4 gene were performed on complementary DNA samples from 31 primary colorectal cancer specimens using a combination of polymerase chain reaction , single-strand conformation polymorphism , and DNA sequencing . RESULTS Four missense mutations producing amino acid substitutions and a somatic 12-base pair deletion in the coding region of the DPC4 gene were detected in the 31 cancers ( 16 % ; 5 of 31 ) . CONCLUSIONS The DPC4 gene may play a role as a tumor-suppressor gene in a fraction of colorectal cancers ; however , while allelic loss at 18q21 is very often seen in colorectal cancers , only a minority show DPC4 mutations , suggesting that there might be another tumor-suppressor gene in this chromosome region . .

+
+
+ +
+
+
    +
    + +
    +
      +
      +
      + +
      + + + + + + + + + + diff --git a/test/tests-old.js b/test/tests-old.js index eeb719c..395760b 100644 --- a/test/tests-old.js +++ b/test/tests-old.js @@ -3,30 +3,9 @@ var html_fixture = "./test/test_page.html"; var sources = ["./test/assert-old.js"]; var tests = [function () { - assert(2, 3, "tets"); + console.log(21); + throw new Error("EEE"); + // assert(2, 3, "tets"); }]; -tests.push(function count_chart_elements() { - document.getElementsByClassName('chart')[0].id = "bogus"; - assert(document.getElementsByClassName('chart').length, 1); -}); - -tests.push(function get_chart_div() { - assert(document.getElementsByClassName('chart')[0].id, "chart_60eb0dc5-6b41-4ca1-94d0-1760c1f3d87b"); -}); - -tests.push(function compare_lists() { - assert([1, 3, 5, 3, 7], [1, 3, 5, 7]); -}); - -tests.push(function compare_maps() { - assert({ 'one': 1, 'two': 2 }, { 'two': 2, 'one': 1 }); -}); - -tests.push(function delayed_assert() { - setTimeout(function () { - assert(1 / 0, Infinity); - }, 100); -}); - //# sourceMappingURL=tests-old.js.map \ No newline at end of file diff --git a/test/tests.js b/test/tests.js index 746e56b..626935a 100644 --- a/test/tests.js +++ b/test/tests.js @@ -1,30 +1,8 @@ var html_fixture = "./test/test_page.html"; var sources = ["./test/assert-old.js"]; var tests = [function() { - assert(2, 3, "tets"); + console.log(21); + throw new Error("EEE"); + // assert(2, 3, "tets"); }]; - -tests.push(function count_chart_elements() { - document.getElementsByClassName('chart')[0].id = "bogus"; - assert(document.getElementsByClassName('chart').length, 1); -}) - -tests.push(function get_chart_div() { - assert(document.getElementsByClassName('chart')[0].id, - "chart_60eb0dc5-6b41-4ca1-94d0-1760c1f3d87b"); -}) - -tests.push(function compare_lists() { - assert([1, 3, 5, 3, 7], [1, 3, 5, 7]); -}) - -tests.push(function compare_maps() { - assert({'one': 1, 'two': 2}, {'two': 2, 'one': 1}); -}) - -tests.push(function delayed_assert() { - setTimeout(function() { - assert(1 / 0, Infinity); - }, 100) -}) From 46c499125030745e7e15ddffe6d624717138c59a Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Tue, 7 Feb 2017 10:57:34 -0800 Subject: [PATCH 12/37] Trying to figure out why Travis prints that error --- runner_test.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/runner_test.js b/runner_test.js index de2e48d..f1ad603 100644 --- a/runner_test.js +++ b/runner_test.js @@ -55,6 +55,8 @@ page.open(html_fixture, function(status) { page.onError = function(msg, trace) { console.log("here's an error"); + console.log(msg); + console.log(JSON.stringify(trace)); /* inject a line number into the error message raised by assert() */ if (trace.length > 1) { console.error(msg.replace(/: in /, @@ -64,8 +66,3 @@ page.onError = function(msg, trace) { } phantom.exit(1); }; - -phantom.onError = function(msg) { - console.log("Here's another error"); - phantom.exit(1); -}; \ No newline at end of file From 449062d4bc41d78a17ef7cbc8a62a53f288e1384 Mon Sep 17 00:00:00 2001 From: Runjie Guan Date: Tue, 7 Feb 2017 11:03:10 -0800 Subject: [PATCH 13/37] Add missing library files --- src/lib/backbone-min.js | 2 ++ src/lib/bootstrap.min.js | 6 ++++++ src/lib/jquery-1.11.1.min.js | 4 ++++ src/lib/underscore-min.js | 6 ++++++ 4 files changed, 18 insertions(+) create mode 100644 src/lib/backbone-min.js create mode 100644 src/lib/bootstrap.min.js create mode 100644 src/lib/jquery-1.11.1.min.js create mode 100644 src/lib/underscore-min.js diff --git a/src/lib/backbone-min.js b/src/lib/backbone-min.js new file mode 100644 index 0000000..435a72c --- /dev/null +++ b/src/lib/backbone-min.js @@ -0,0 +1,2 @@ +(function(t){var e=typeof self=="object"&&self.self===self&&self||typeof global=="object"&&global.global===global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,n){e.Backbone=t(e,n,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore"),r;try{r=require("jquery")}catch(n){}t(e,exports,i,r)}else{e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}})(function(t,e,i,r){var n=t.Backbone;var s=Array.prototype.slice;e.VERSION="1.3.3";e.$=r;e.noConflict=function(){t.Backbone=n;return this};e.emulateHTTP=false;e.emulateJSON=false;var a=function(t,e,r){switch(t){case 1:return function(){return i[e](this[r])};case 2:return function(t){return i[e](this[r],t)};case 3:return function(t,n){return i[e](this[r],o(t,this),n)};case 4:return function(t,n,s){return i[e](this[r],o(t,this),n,s)};default:return function(){var t=s.call(arguments);t.unshift(this[r]);return i[e].apply(i,t)}}};var h=function(t,e,r){i.each(e,function(e,n){if(i[n])t.prototype[n]=a(e,n,r)})};var o=function(t,e){if(i.isFunction(t))return t;if(i.isObject(t)&&!e._isModel(t))return l(t);if(i.isString(t))return function(e){return e.get(t)};return t};var l=function(t){var e=i.matches(t);return function(t){return e(t.attributes)}};var u=e.Events={};var c=/\s+/;var f=function(t,e,r,n,s){var a=0,h;if(r&&typeof r==="object"){if(n!==void 0&&"context"in s&&s.context===void 0)s.context=n;for(h=i.keys(r);athis.length)n=this.length;if(n<0)n+=this.length+1;var s=[];var a=[];var h=[];var o=[];var l={};var u=e.add;var c=e.merge;var f=e.remove;var d=false;var v=this.comparator&&n==null&&e.sort!==false;var g=i.isString(this.comparator)?this.comparator:null;var p,m;for(m=0;m7);this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(O,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){this.iframe=document.createElement("iframe");this.iframe.src="javascript:0";this.iframe.style.display="none";this.iframe.tabIndex=-1;var r=document.body;var n=r.insertBefore(this.iframe,r.firstChild).contentWindow;n.document.open();n.document.close();n.location.hash="#"+this.fragment}var s=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){s("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){s("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);N.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe.contentWindow)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){if(!this.matchRoot())return false;t=this.fragment=this.getFragment(t);return i.some(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!N.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var r=i+t;t=this.decodeFragment(t.replace(U,""));if(this.fragment===t)return;this.fragment=t;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe.contentWindow)){var n=this.iframe.contentWindow;if(!e.replace){n.document.open();n.document.close()}this._updateHash(n.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new N;var q=function(t,e){var r=this;var n;if(t&&i.has(t,"constructor")){n=t.constructor}else{n=function(){return r.apply(this,arguments)}}i.extend(n,r,e);n.prototype=i.create(r.prototype,t);n.prototype.constructor=n;n.__super__=r.prototype;return n};y.extend=x.extend=$.extend=k.extend=N.extend=q;var F=function(){throw new Error('A "url" property or function must be specified')};var B=function(t,e){var i=e.error;e.error=function(r){if(i)i.call(e.context,t,r,e);t.trigger("error",t,r,e)}};return e}); +//# sourceMappingURL=backbone-min.map \ No newline at end of file diff --git a/src/lib/bootstrap.min.js b/src/lib/bootstrap.min.js new file mode 100644 index 0000000..7c1561a --- /dev/null +++ b/src/lib/bootstrap.min.js @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.2.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.2.0",d.prototype.close=function(b){function c(){f.detach().trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",c).emulateTransitionEnd(150):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.2.0",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),d[e](null==f[b]?this.options[b]:f[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b).on("keydown.bs.carousel",a.proxy(this.keydown,this)),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.2.0",c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},c.prototype.keydown=function(a){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.to=function(b){var c=this,d=this.getItemIndex(this.$active=this.$element.find(".item.active"));return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=e[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:g});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,f&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(e)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:g});return a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one("bsTransitionEnd",function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger(m)),f&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(b=!b),e||d.data("bs.collapse",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};c.VERSION="3.2.0",c.DEFAULTS={toggle:!0},c.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},c.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var c=a.Event("show.bs.collapse");if(this.$element.trigger(c),!c.isDefaultPrevented()){var d=this.$parent&&this.$parent.find("> .panel > .in");if(d&&d.length){var e=d.data("bs.collapse");if(e&&e.transitioning)return;b.call(d,"hide"),e||d.data("bs.collapse",null)}var f=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[f](0),this.transitioning=1;var g=function(){this.$element.removeClass("collapsing").addClass("collapse in")[f](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return g.call(this);var h=a.camelCase(["scroll",f].join("-"));this.$element.one("bsTransitionEnd",a.proxy(g,this)).emulateTransitionEnd(350)[f](this.$element[0][h])}}},c.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},c.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var d=a.fn.collapse;a.fn.collapse=b,a.fn.collapse.Constructor=c,a.fn.collapse.noConflict=function(){return a.fn.collapse=d,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(c){var d,e=a(this),f=e.attr("data-target")||c.preventDefault()||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""),g=a(f),h=g.data("bs.collapse"),i=h?"toggle":e.data(),j=e.attr("data-parent"),k=j&&a(j);h&&h.transitioning||(k&&k.find('[data-toggle="collapse"][data-parent="'+j+'"]').not(e).addClass("collapsed"),e[g.hasClass("in")?"addClass":"removeClass"]("collapsed")),b.call(g,i)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.2.0",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('