fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-02-24 05:21 am

[dw-free] Create page to run multiple test pages using our js test framework

[commit: http://hg.dwscoalition.org/dw-free/rev/c7966d7a04db]

http://bugs.dwscoalition.org/show_bug.cgi?id=3534

Run multiple tests on the same page. /dev/tests now runs all tests that are
available; /dev/tests/testname runs the different libraries for /testname.

Patch by [personal profile] exor674.

Files modified:
  • cgi-bin/DW/Controller/Dev.pm
  • htdocs/js/tests/qunit-all.js
  • htdocs/stc/tests/qunit-all.css
  • views/dev/tests-all.tt
  • views/dev/tests.tt
--------------------------------------------------------------------------------
diff -r b79f5e330c01 -r c7966d7a04db cgi-bin/DW/Controller/Dev.pm
--- a/cgi-bin/DW/Controller/Dev.pm	Thu Feb 24 12:08:50 2011 +0800
+++ b/cgi-bin/DW/Controller/Dev.pm	Thu Feb 24 13:21:25 2011 +0800
@@ -22,16 +22,37 @@ use DW::Routing;
 
 DW::Routing->register_static( '/dev/classes', 'dev/classes.tt', app => 1 );
 
+if ( $LJ::IS_DEV_SERVER ) {
+    DW::Routing->register_string( '/dev/tests/index', \&tests_index_handler, app => 1 );
+    DW::Routing->register_regex( '/dev/tests/([^/]+)(?:/(.*))?', \&tests_handler, app => 1 )
+}
 
-DW::Routing->register_regex( '/dev/tests/([^/]+)(?:/(.*))?', \&tests_handler, app => 1 )
-    if $LJ::IS_DEV_SERVER;
+sub tests_index_handler {
+    my ( $opts ) = @_;
 
+    my $r = DW::Request->get;
+
+    $r->note( bml_use_scheme => "global" );
+    return DW::Template->render_template( "dev/tests-all.tt", {
+        all_tests => [ map { $_ =~ m!tests/([^/]+)\.js!; } glob("$LJ::HOME/views/dev/tests/*.js") ]
+    } );
+}
+    
 sub tests_handler {
     my ( $opts ) = @_;
     my $test = $opts->subpatterns->[0];
-    my $lib = $opts->subpatterns->[1] || "";
+    my $lib = $opts->subpatterns->[1];
 
     my $r = DW::Request->get;
+
+    if ( ! defined $lib ) {
+        return $r->redirect("$LJ::SITEROOT/dev/tests/$test/");
+    } elsif ( ! $lib ) {
+        $r->note( bml_use_scheme => "global" );
+        return DW::Template->render_template( "dev/tests-all.tt", {
+            test => $test,
+        } );
+    }
 
     my @includes;
     my $testcontent = eval{ DW::Template->template_string( "dev/tests/${test}.js" ) } || "";
diff -r b79f5e330c01 -r c7966d7a04db htdocs/js/tests/qunit-all.js
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/js/tests/qunit-all.js	Thu Feb 24 13:21:25 2011 +0800
@@ -0,0 +1,172 @@
+var _r = {
+    all_tests: [],
+    all_libs: ['old','jquery'],
+    next_test_idx: 0,
+    next_lib_idx: 0,
+    init: function() {
+        _r.next_test_idx = 0;
+        _r.next_lib_idx = 0;
+        _r.test_container = $("#qunit-tests");
+        _r.test_results = $("#qunit-testresult");
+        _r.test_banner = $("#qunit-banner");
+
+        _r.passed = 0;
+        _r.failed = 0;
+        _r.total  = 0;
+        _r.test_time = 0;
+
+        _r.start_time = new Date().getTime();
+
+        $("#qunit-filter-pass").attr("disabled",true);
+        $("#qunit-testresult .line1").text("Pending...");
+        _r.update_counts();
+    },
+    run_next: function() {
+        if ( _r.next_lib_idx >= _r.all_libs.length ) {
+            _r.next_lib_idx = 0;
+            _r.next_test_idx++;
+        }
+        if ( _r.next_test_idx >= _r.all_tests.length ) {
+            _r.done();
+            return;
+        }
+        if ( _r.next_lib_idx < _r.all_libs.length ) {
+            _r.run_test( _r.all_tests[_r.next_test_idx], _r.all_libs[_r.next_lib_idx++] );
+        }
+    },
+    skip_test: function() {
+        _r._next_lib_idx = 0;
+        _r.next_test_idx++;
+        _r.run_next();
+    },
+    update_counts: function() {
+        $("#qunit-testresult .passed").text(_r.passed);
+        $("#qunit-testresult .failed").text(_r.failed);
+        $("#qunit-testresult .total").text(_r.total);
+        var banner_class = "qunit-pass";
+        if ( _r.failed ) {
+            banner_class = "qunit-fail";
+        }
+        _r.test_banner.attr("class",banner_class);
+    },
+    run_test: function(test,lib) {
+        $("#qunit-testresult .line1").text("Running test: " + test + ", lib: " + lib + "...");
+        _r.cur_test = test;
+        _r.cur_lib = lib;
+
+        var url = "/dev/tests/"+test+"/"+lib;
+        var li = $("<li>");
+        li.attr("id","test-"+test+"-"+lib);
+        _r.current_li = li;
+        _r.test_container.append(li);
+
+        var strong = $("<strong>");
+        li.append(strong);
+
+        var module_name = $("<span>");
+        module_name.addClass("module-name");
+        module_name.text(test + "-" + lib);
+        strong.append(module_name);
+
+        strong.append(": ");
+
+        var counts = $("<span>");
+        counts.addClass("counts");
+        counts.text("Running...");
+        strong.append(counts);
+
+        var iframe = $("<iframe>");
+        li.append(iframe);
+        _r.current_iframe = iframe;
+
+        iframe.hide();
+        iframe.attr("src",url);
+
+
+        iframe.load(function () {
+            _r.poll_iframe();
+        });
+        strong.click(function () {
+            iframe.toggle();
+        })
+    },
+    done: function () {
+        var end_time = new Date().getTime();
+        var ms = Math.round(end_time - _r.start_time);
+        $("#qunit-testresult .line1").text("Tests completed in " + ms + " milliseconds (" + _r.test_time + " milliseconds in tests).");
+        $("#qunit-filter-pass").removeAttr("disabled");
+    },
+    poll_iframe: function () {
+        var iframe = _r.current_iframe;
+        var content = iframe.contents();
+
+        var notests = content.find("#notests");
+        if( notests.size() > 0 ) {
+            _r.current_li
+                .find(".counts").text("No tests defined for " + _r.cur_test).end()
+                .find("iframe").remove();
+            _r.skip_test();
+            return;
+        }
+
+        var results = content.find("#qunit-testresult");
+
+        if ( results.size() == 0 ) {
+            setTimeout(_r.poll_iframe, 10);
+            return;
+        }
+
+        var passed_i = results.find(".passed");
+        var total_i  = results.find(".total");
+        var failed_i = results.find(".failed");
+
+        var tct = passed_i.size() + total_i.size() + failed_i.size();
+
+        if ( tct != 3 ) {
+            setTimeout(_r.poll_iframe, 10);
+            return;
+        }
+
+        _r.passed += parseInt( passed_i.text(), 10 );
+        _r.failed += parseInt( failed_i.text(), 10 );
+        _r.total  += parseInt( total_i.text(),  10 );
+        _r.update_counts();
+
+        var match_result = /in ([0-9]+) millisecond/.exec(results.text());
+        _r.test_time += parseInt( match_result[1], 10 );
+
+        var nodes = content.find("#qunit-tests > li");
+        nodes.detach();
+        _r.test_container.append(nodes);
+        nodes.each( function(_,node_d) {
+            var node = $(node_d);
+            node.addClass("test-"+_r.cur_test);
+            node.addClass("lib-"+_r.cur_lib);
+            node.addClass("testlib-"+_r.cur_test+"-"+_r.cur_lib);
+            node.attr("id",node.attr("id")+"-"+_r.cur_test+"-"+_r.cur_lib)
+            var element = node.find(".module-name");
+            var lib = $("<span class='lib-type'>");
+            lib.text(" (" +_r.cur_test + "/" + _r.cur_lib + ")");
+            element.append(lib);
+        });
+        _r.current_li.remove();
+        _r.run_next();
+    },
+    hide_passed: function (hide) {
+        _r.test_container.find("> li").show();
+        if ( hide ) {
+            _r.test_container.find("> li.pass").hide();
+        }
+    }
+}
+
+function register_all_tests(t) {
+    _r.all_tests = _r.all_tests.concat(t);
+}
+
+$(function () {
+    _r.init();
+    $("#qunit-userAgent").text( navigator.userAgent );
+    $("#qunit-filter-pass").change( function() { _r.hide_passed( this.checked ) })
+    _r.run_next();
+});
diff -r b79f5e330c01 -r c7966d7a04db htdocs/stc/tests/qunit-all.css
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/stc/tests/qunit-all.css	Thu Feb 24 13:21:25 2011 +0800
@@ -0,0 +1,4 @@
+#qunit-tests > li .module-name .lib-type {
+    color: #111;
+    font-size: .85em;
+}
\ No newline at end of file
diff -r b79f5e330c01 -r c7966d7a04db views/dev/tests-all.tt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/views/dev/tests-all.tt	Thu Feb 24 13:21:25 2011 +0800
@@ -0,0 +1,25 @@
+[%-
+    # it's all right to require jquery here because the other tests load up in a sandbox
+    # and the different js library versions can't interfere with one another
+    dw.need_res( { group => "jquery" }, "stc/tests/qunit.css", "stc/tests/qunit-all.css", "js/tests/qunit-all.js" );
+    CALL dw.active_resource_group( "jquery" );
+    sections.head = BLOCK -%]
+<script type="text/javascript">
+[%- IF all_tests -%]
+register_all_tests([ [% FOREACH test IN all_tests; UNLESS loop.first %],[% END %]"[% test %]"[% END %] ]);
+[%- ELSE -%]
+register_all_tests([ "[% test %]" ]);
+[%- END -%]
+</script>
+[%- END -%]
+
+<h1 id="qunit-header">[%- IF all_tests -%]
+All Tests
+[%- ELSE -%]
+All Libraries for [% test | html %]
+[%- END -%]</h1>
+<h2 id="qunit-banner"></h2>
+<div id="qunit-testrunner-toolbar"><input type="checkbox" id="qunit-filter-pass"/><label for="qunit-filter-pass">Hide passed tests</label></div>
+<h2 id="qunit-userAgent"></h2>
+<p id="qunit-testresult" class="result"><span class="line1"></span><br/><span class="line2"><span class="passed">0</span> test(s) of <span class="total">0</span> passed, <span class="failed">0</span> failed.</span></p>
+<ol id="qunit-tests"></ol>
diff -r b79f5e330c01 -r c7966d7a04db views/dev/tests.tt
--- a/views/dev/tests.tt	Thu Feb 24 12:08:50 2011 +0800
+++ b/views/dev/tests.tt	Thu Feb 24 13:21:25 2011 +0800
@@ -65,4 +65,5 @@ if ( lib && ! location.search ) {
     </div>
 [% ELSE %]
     <h1 id="qunit-header">No tests for [% testname %]</h1>
+    <ol id="notests"></ol>
 [%- END -%]
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
No Subject Icon Selected
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org