Jdlrobson has submitted this change and it was merged.

Change subject: Refactor the way we run mobile JavaScript tests
......................................................................


Refactor the way we run mobile JavaScript tests

This introduces a few changes:

* /tests/javascripts follows the directory structure of /javascripts.

* onResourceLoaderTestModules hook automatically checks if there is a
  test file for every JavaScript file we use in our ResourceLoader
  modules and if it finds it, creates a corresponding RL test module.
  No more dependency problems when adding new JavaScript test files!

* Messages and templates are loaded for tests just as they are loaded in
  the extension itself (hence the changes in test_mf-photo.js,
  test_carousel.js and test_mf-navigation.js)).

* Our JavaScript tests now have to be run using mobile version of
  Special:JavaScriptTest page, this also ensures they run in the
  environment they were written for.

* Sinon.js updated to 1.6.0.

There are a couple of hacks in place
* mobile.tests.base is prefixed with a 0. to force earlier loading. On
Jon's Mac Air this was loading after mobile.toggling module

* The settings tests set a cookie for 400ms. By the time the check was
run this cookie had expired so the limit was increased.

Dependency: I84e0512590de9ff2dbdf519d983a0c1c2d007194
Change-Id: I593a9c0e8edcb04a351a06a457327f63d698a298
---
M Makefile
M includes/MobileContext.php
M includes/MobileFrontend.hooks.php
R scripts/qunit.sh
M tests/.htaccess
M tests/externals/sinon.js
R tests/javascripts/actions/test_mf-edit.js
R tests/javascripts/common/test_eventemitter.js
R tests/javascripts/common/test_mf-api.js
R tests/javascripts/common/test_mf-application.js
R tests/javascripts/common/test_mf-history.js
R tests/javascripts/common/test_mf-navigation.js
R tests/javascripts/common/test_mf-oop.js
R tests/javascripts/common/test_mf-settings.js
R tests/javascripts/common/test_mf-view.js
R tests/javascripts/fixtures.js
R tests/javascripts/modules/test_mf-last-modified.js
R tests/javascripts/modules/test_mf-photo.js
R tests/javascripts/modules/test_mf-references.js
R tests/javascripts/modules/test_mf-search.js
R tests/javascripts/modules/test_mf-toggle.js
R tests/javascripts/modules/test_mf-watchstar.js
R tests/javascripts/specials/test_mobilediff.js
R tests/javascripts/specials/test_uploads.js
R tests/javascripts/views/test_page.js
A tests/javascripts/widgets/test_carousel.js
R tests/javascripts/widgets/test_progress-bar.js
D tests/js/fixtures-templates.js
D tests/js/widgets/carousel.js
D tests/templates/template.html
D tests/templates/template2.html
31 files changed, 228 insertions(+), 167 deletions(-)

Approvals:
  Jdlrobson: Verified; Looks good to me, approved



diff --git a/Makefile b/Makefile
index 347bc8e..2efc291 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 .PHONY: less
 
 jshinttests:
-       jshint tests/js/* --config .jshintrc
+       jshint tests/javascripts/* --config .jshintrc
 
 jshint: jshinttests
        jshint javascripts/* --config .jshintrc
@@ -16,7 +16,7 @@
        cd ../../tests/phpunit && php phpunit.php --configuration 
../../extensions/MobileFrontend/tests/mfe.suite.xml --group=MobileFrontend
 
 qunit:
-       @tests/qunit.sh
+       @scripts/qunit.sh
 
 tests: jshint phpunit qunit
 
diff --git a/includes/MobileContext.php b/includes/MobileContext.php
index 66f1e0e..2cbe2e5 100644
--- a/includes/MobileContext.php
+++ b/includes/MobileContext.php
@@ -246,12 +246,6 @@
                        return false;
                }
 
-               $title = $this->getTitle() ? $this->getTitle()->getText() : 
false;
-               // Can't use Title::isSpecial() due to infinite recursion
-               if ( $title && $title == SpecialPage::getTitleFor( 
'JavaScriptTest', 'qunit' )->getText() ) {
-                       return false;
-               }
-
                if ( $isDiff ) {
                        return false;
                }
diff --git a/includes/MobileFrontend.hooks.php 
b/includes/MobileFrontend.hooks.php
index cbaa0b2..6e6089b 100644
--- a/includes/MobileFrontend.hooks.php
+++ b/includes/MobileFrontend.hooks.php
@@ -189,49 +189,48 @@
         * @return bool
         */
        public static function onResourceLoaderTestModules( array 
&$testModules, ResourceLoader &$resourceLoader ) {
-               $testModules['qunit']['ext.mobilefrontend.tests'] = array(
-                       'messages' => array(
-                               'mobile-frontend-search-noresults',
-                       ),
+               global $wgResourceModules, $wgResourceLoaderDebug;
+
+               // run RL in debug mode so that we get real line numbers on 
errors and
+               // so that sinon.js is loaded within global context
+               $wgResourceLoaderDebug = true;
+
+               $testModuleBoilerplate = array(
+                       'localBasePath' => dirname( __DIR__ ),
+                       'remoteExtPath' => 'MobileFrontend',
+                       'targets' => array( 'mobile' ),
+               );
+
+               // additional frameworks and fixtures we use in tests
+               // FIXME: Find a way to make this load before sibling 
dependencies without resorting to 0. prefix
+               $testModules['qunit']['0.mobile.tests.base'] = 
$testModuleBoilerplate + array(
                        'scripts' => array(
                                'tests/externals/sinon.js',
-                               'javascripts/externals/hogan.js',
-                               'javascripts/common/modules.js',
-                               'javascripts/common/eventemitter.js', 
'tests/js/test_eventemitter.js',
-                               'tests/js/fixtures.js', 
'javascripts/common/mf-application.js',
-                               'tests/js/fixtures-templates.js',
-                               'javascripts/common/mf-history.js', 
'tests/js/test_mf-history.js',
-                               'tests/js/test_application.js',
-                               'javascripts/common/mf-oop.js', 
'tests/js/test_mf-oop.js',
-                               'javascripts/common/mf-api.js', 
'tests/js/test_mf-api.js',
-                               'javascripts/common/mf-view.js', 
'tests/js/test_mf-view.js',
-                               'javascripts/widgets/progress-bar.js', 
'tests/js/widgets/test_progress-bar.js',
-                               'javascripts/modules/mf-search.js', 
'tests/js/test_beta_opensearch.js',
-                               'javascripts/common/mf-settings.js', 
'tests/js/test_settings.js',
-                               'javascripts/modules/mf-toggle.js', 
'tests/js/test_toggle.js',
-                               'javascripts/modules/mf-toggle-dynamic.js',
-                               'javascripts/actions/mf-edit.js', 
'tests/js/test_mf-edit.js',
-                               'javascripts/common/mf-navigation.js',
-                               'tests/js/common/mf-navigation.js',
-                               'javascripts/common/mf-notification.js',
-
-                               // special mobilediff
-                               'javascripts/externals/jsdiff.js',
-                               'javascripts/specials/mobilediff.js', 
'tests/js/specials/mobilediff.js',
-
-                               'javascripts/modules/mf-photo.js', 
'tests/js/test_mf-photo.js',
-                               'javascripts/modules/mf-references.js', 
'tests/js/test_references.js',
-                               'javascripts/modules/mf-watchstar.js', 
'tests/js/test_mf-watchstar.js',
-                               'javascripts/modules/mf-last-modified.js', 
'tests/js/test_mf-last-modified.js',
-                               'javascripts/views/page.js', 
'tests/js/views/page.js',
-
-                               'javascripts/widgets/carousel.js', 
'tests/js/widgets/carousel.js',
-                               'javascripts/specials/uploads.js', 
'tests/js/specials/uploads.js',
-                               ),
-                               'dependencies' => array( ),
-                               'localBasePath' => dirname( dirname( __FILE__ ) 
),
-                               'remoteExtPath' => 'MobileFrontend',
+                               'tests/javascripts/fixtures.js',
+                       ),
                );
+
+               // find test files for every RL module
+               foreach ( $wgResourceModules as $key => $module ) {
+                       if ( substr( $key, 0, 7 ) === 'mobile.' && isset( 
$module['scripts'] ) ) {
+                               $testFiles = array();
+                               foreach ( $module['scripts'] as $script ) {
+                                       $testFile = 'tests/' . dirname( $script 
) . '/test_' . basename( $script );
+                                       // if a test file exists for a given JS 
file, add it
+                                       if ( file_exists( 
$testModuleBoilerplate['localBasePath'] . '/' . $testFile ) ) {
+                                               $testFiles[] = $testFile;
+                                       }
+                               }
+                               // if test files exist for given module, create 
a corresponding test module
+                               if ( !empty( $testFiles ) ) {
+                                       $testModules['qunit']["$key.tests"] = 
$testModuleBoilerplate + array(
+                                               'dependencies' => array( 
'0.mobile.tests.base', $key ),
+                                               'scripts' => $testFiles,
+                                       );
+                               }
+                       }
+               }
+
                return true;
        }
 
diff --git a/tests/qunit.sh b/scripts/qunit.sh
similarity index 86%
rename from tests/qunit.sh
rename to scripts/qunit.sh
index 1be04fc..0a24f74 100755
--- a/tests/qunit.sh
+++ b/scripts/qunit.sh
@@ -4,7 +4,7 @@
   echo "Using $URL as a development environment host."
   echo "To specify a different host set MEDIAWIKI_URL environment variable"
   echo '(e.g. by running "export MEDIAWIKI_URL=http://localhost:8080/w";)'
-  phantomjs tests/externals/phantomjs-qunit-runner.js 
"$URL/index.php/Special:JavaScriptTest/qunit?filter=MobileFrontend"
+  phantomjs tests/externals/phantomjs-qunit-runner.js 
"$URL/index.php/Special:JavaScriptTest/qunit?filter=MobileFrontend&useformat=mobile"
 else
   echo "You need to install PhantomJS to run QUnit tests in terminal!"
   echo "See http://phantomjs.org/";
diff --git a/tests/.htaccess b/tests/.htaccess
index 3a42882..986a40a 100644
--- a/tests/.htaccess
+++ b/tests/.htaccess
@@ -1 +1,4 @@
 Deny from all
+<FilesMatch "\.js$">
+       Allow from all
+</FilesMatch>
diff --git a/tests/externals/sinon.js b/tests/externals/sinon.js
index c0728bb..d08a0e0 100644
--- a/tests/externals/sinon.js
+++ b/tests/externals/sinon.js
@@ -1,12 +1,12 @@
 /**
- * Sinon.JS 1.5.2, 2012/11/27
+ * Sinon.JS 1.6.0, 2013/02/18
  *
  * @author Christian Johansen ([email protected])
  * @author Contributors: 
https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
  *
  * (The BSD License)
  * 
- * Copyright (c) 2010-2012, Christian Johansen, [email protected]
+ * Copyright (c) 2010-2013, Christian Johansen, [email protected]
  * All rights reserved.
  * 
  * Redistribution and use in source and binary forms, with or without 
modification,
@@ -463,7 +463,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 var sinon = (function (buster) {
@@ -706,7 +706,7 @@
 
         calledInOrder: function (spies) {
             for (var i = 1, l = spies.length; i < l; i++) {
-                if (!spies[i - 1].calledBefore(spies[i])) {
+                if (!spies[i - 1].calledBefore(spies[i]) || !spies[i].called) {
                     return false;
                 }
             }
@@ -748,6 +748,13 @@
             }
             var string = Object.prototype.toString.call(value);
             return string.substring(8, string.length - 1).toLowerCase();
+        },
+
+        createStubInstance: function (constructor) {
+            if (typeof constructor !== "function") {
+                throw new TypeError("The constructor should be a function.");
+            }
+            return sinon.stub(sinon.create(constructor.prototype));
         }
     };
 
@@ -1031,19 +1038,19 @@
 }(typeof sinon == "object" && sinon || null));
 
 /**
- * @depend ../sinon.js
- * @depend match.js
- */
+  * @depend ../sinon.js
+  * @depend match.js
+  */
 /*jslint eqeqeq: false, onevar: false, plusplus: false*/
 /*global module, require, sinon*/
 /**
- * Spy functions
- *
- * @author Christian Johansen ([email protected])
- * @license BSD
- *
- * Copyright (c) 2010-2011 Christian Johansen
- */
+  * Spy functions
+  *
+  * @author Christian Johansen ([email protected])
+  * @license BSD
+  *
+  * Copyright (c) 2010-2013 Christian Johansen
+  */
 
 (function (sinon) {
     var commonJSModule = typeof module == "object" && typeof require == 
"function";
@@ -1066,7 +1073,7 @@
         }
 
         if (!object && !property) {
-            return spy.create(function () {});
+            return spy.create(function () { });
         }
 
         var method = object[property];
@@ -1139,7 +1146,7 @@
             var p;
             if (func.length) {
                 eval("p = (function proxy(" + vars.substring(0, func.length * 
2 - 1) +
-                  ") { return p.invoke(func, this, slice.call(arguments)); 
});");
+                    ") { return p.invoke(func, this, slice.call(arguments)); 
});");
             }
             else {
                 p = function proxy() {
@@ -1180,7 +1187,7 @@
                 var name;
 
                 if (typeof func != "function") {
-                    func = function () {};
+                    func = function () { };
                 } else {
                     name = sinon.functionName(func);
                 }
@@ -1237,8 +1244,8 @@
                 }
 
                 return spyCall.create(this, this.thisValues[i], this.args[i],
-                                      this.returnValues[i], this.exceptions[i],
-                                      this.callIds[i]);
+                                        this.returnValues[i], 
this.exceptions[i],
+                                        this.callIds[i]);
             },
 
             calledBefore: function calledBefore(spyFn) {
@@ -1348,12 +1355,23 @@
             throw new Error(this.toString() + " cannot call arg since it was 
not yet invoked.");
         });
         spyApi.callArgWith = spyApi.callArg;
+        delegateToCalls(spyApi, "callArgOn", false, "callArgOnWith", function 
() {
+            throw new Error(this.toString() + " cannot call arg since it was 
not yet invoked.");
+        });
+        spyApi.callArgOnWith = spyApi.callArgOn;
         delegateToCalls(spyApi, "yield", false, "yield", function () {
             throw new Error(this.toString() + " cannot yield since it was not 
yet invoked.");
         });
         // "invokeCallback" is an alias for "yield" since "yield" is invalid 
in strict mode.
         spyApi.invokeCallback = spyApi.yield;
+        delegateToCalls(spyApi, "yieldOn", false, "yieldOn", function () {
+            throw new Error(this.toString() + " cannot yield since it was not 
yet invoked.");
+        });
         delegateToCalls(spyApi, "yieldTo", false, "yieldTo", function 
(property) {
+            throw new Error(this.toString() + " cannot yield to '" + property +
+                "' since it was not yet invoked.");
+        });
+        delegateToCalls(spyApi, "yieldToOn", false, "yieldToOn", function 
(property) {
             throw new Error(this.toString() + " cannot yield to '" + property +
                 "' since it was not yet invoked.");
         });
@@ -1371,7 +1389,11 @@
                 var calls = [];
 
                 for (var i = 0, l = spy.callCount; i < l; ++i) {
-                    push.call(calls, "    " + spy.getCall(i).toString());
+                    var stringifiedCall = "    " + spy.getCall(i).toString();
+                    if (/\n/.test(calls[i - 1])) {
+                        stringifiedCall = "\n" + stringifiedCall;
+                    }
+                    push.call(calls, stringifiedCall);
                 }
 
                 return calls.length > 0 ? "\n" + calls.join("\n") : "";
@@ -1443,14 +1465,14 @@
             },
 
             calledWithMatch: function calledWithMatch() {
-              for (var i = 0, l = arguments.length; i < l; i += 1) {
-                  var actual = this.args[i];
-                  var expectation = arguments[i];
-                  if (!sinon.match || !sinon.match(expectation).test(actual)) {
-                      return false;
-                  }
-              }
-              return true;
+                for (var i = 0, l = arguments.length; i < l; i += 1) {
+                    var actual = this.args[i];
+                    var expectation = arguments[i];
+                    if (!sinon.match || 
!sinon.match(expectation).test(actual)) {
+                        return false;
+                    }
+                }
+                return true;
             },
 
             calledWithExactly: function calledWithExactly() {
@@ -1463,7 +1485,7 @@
             },
 
             notCalledWithMatch: function notCalledWithMatch() {
-              return !this.calledWithMatch.apply(this, arguments);
+                return !this.calledWithMatch.apply(this, arguments);
             },
 
             returned: function returned(value) {
@@ -1498,16 +1520,28 @@
                 this.args[pos]();
             },
 
+            callArgOn: function (pos, thisValue) {
+                this.args[pos].apply(thisValue);
+            },
+
             callArgWith: function (pos) {
-                var args = slice.call(arguments, 1);
-                this.args[pos].apply(null, args);
+                this.callArgOnWith.apply(this, [pos, 
null].concat(slice.call(arguments, 1)));
+            },
+
+            callArgOnWith: function (pos, thisValue) {
+                var args = slice.call(arguments, 2);
+                this.args[pos].apply(thisValue, args);
             },
 
             "yield": function () {
+                this.yieldOn.apply(this, [null].concat(slice.call(arguments, 
0)));
+            },
+
+            yieldOn: function (thisValue) {
                 var args = this.args;
                 for (var i = 0, l = args.length; i < l; ++i) {
                     if (typeof args[i] === "function") {
-                        args[i].apply(null, slice.call(arguments));
+                        args[i].apply(thisValue, slice.call(arguments, 1));
                         return;
                     }
                 }
@@ -1515,10 +1549,14 @@
             },
 
             yieldTo: function (prop) {
+                this.yieldToOn.apply(this, [prop, 
null].concat(slice.call(arguments, 1)));
+            },
+
+            yieldToOn: function (prop, thisValue) {
                 var args = this.args;
                 for (var i = 0, l = args.length; i < l; ++i) {
                     if (args[i] && typeof args[i][prop] === "function") {
-                        args[i][prop].apply(null, slice.call(arguments, 1));
+                        args[i][prop].apply(thisValue, slice.call(arguments, 
2));
                         return;
                     }
                 }
@@ -1579,7 +1617,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function (sinon) {
@@ -1625,7 +1663,8 @@
 
     function getChangingValue(stub, property) {
         var index = stub.callCount - 1;
-        var prop = index in stub[property] ? stub[property][index] : 
stub[property + "Last"];
+        var values = stub[property];
+        var prop = index in values ? values[index] : values[values.length - 1];
         stub[property + "Last"] = prop;
 
         return prop;
@@ -1682,8 +1721,6 @@
     var nextTick = (function () {
         if (typeof process === "object" && typeof process.nextTick === 
"function") {
             return process.nextTick;
-        } else if (typeof msSetImmediate === "function") {
-            return msSetImmediate.bind(window);
         } else if (typeof setImmediate === "function") {
             return setImmediate;
         } else {
@@ -1700,8 +1737,6 @@
             if (typeof func != "function") {
                 throw new TypeError(getCallbackError(stub, func, args));
             }
-
-            var index = stub.callCount - 1;
 
             var callbackArguments = getChangingValue(stub, 
"callbackArguments");
             var callbackContext = getChangingValue(stub, "callbackContexts");
@@ -1766,6 +1801,25 @@
                 functionStub.toString = sinon.functionToString;
 
                 return functionStub;
+            },
+
+            resetBehavior: function () {
+                var i;
+
+                this.callArgAts = [];
+                this.callbackArguments = [];
+                this.callbackContexts = [];
+                this.callArgProps = [];
+
+                delete this.returnValue;
+                delete this.returnArgAt;
+                this.returnThis = false;
+
+                if (this.fakes) {
+                    for (i = 0; i < this.fakes.length; i++) {
+                        this.fakes[i].resetBehavior();
+                    }
+                }
             },
 
             returns: function returns(value) {
@@ -1934,7 +1988,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function (sinon) {
@@ -2302,7 +2356,8 @@
                 }
 
                 var callStr = sinon.spyCall.toString.call({
-                    proxy: this.method, args: args
+                    proxy: this.method || "anonymous mock expectation",
+                    args: args
                 });
 
                 var message = callStr.replace(", [...", "[, ...") + " " +
@@ -2358,7 +2413,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function (sinon) {
@@ -2515,7 +2570,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 if (typeof sinon == "undefined") {
@@ -2656,6 +2711,8 @@
             if (firstException) {
               throw firstException;
             }
+
+            return this.now;
         },
 
         firstTimerInRange: function (from, to) {
@@ -2933,7 +2990,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 if (typeof sinon == "undefined") {
@@ -3162,6 +3219,8 @@
 
             if (this.async) {
                 this.readyStateChange(FakeXMLHttpRequest.HEADERS_RECEIVED);
+            } else {
+                this.readyState = FakeXMLHttpRequest.HEADERS_RECEIVED;
             }
         },
 
@@ -3407,7 +3466,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 if (typeof sinon == "undefined") {
@@ -3469,6 +3528,15 @@
         }
 
         return false;
+    }
+
+    function log(response, request) {
+        var str;
+
+        str =  "Request:\n"  + sinon.format(request)  + "\n\n";
+        str += "Response:\n" + sinon.format(response) + "\n\n";
+
+        sinon.log(str);
     }
 
     return {
@@ -3577,6 +3645,8 @@
                 }
 
                 if (request.readyState != 4) {
+                    log(response, request);
+
                     request.respond(response[0], response[1], response[2]);
                 }
             } catch (e) {
@@ -3612,7 +3682,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function () {
@@ -3692,7 +3762,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 if (typeof module == "object" && typeof require == "function") {
@@ -3816,7 +3886,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function (sinon) {
@@ -3889,7 +3959,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function (sinon) {
@@ -3986,7 +4056,7 @@
  * @author Christian Johansen ([email protected])
  * @license BSD
  *
- * Copyright (c) 2010-2011 Christian Johansen
+ * Copyright (c) 2010-2013 Christian Johansen
  */
 
 (function (sinon, global) {
diff --git a/tests/js/test_mf-edit.js 
b/tests/javascripts/actions/test_mf-edit.js
similarity index 100%
rename from tests/js/test_mf-edit.js
rename to tests/javascripts/actions/test_mf-edit.js
diff --git a/tests/js/test_eventemitter.js 
b/tests/javascripts/common/test_eventemitter.js
similarity index 100%
rename from tests/js/test_eventemitter.js
rename to tests/javascripts/common/test_eventemitter.js
diff --git a/tests/js/test_mf-api.js b/tests/javascripts/common/test_mf-api.js
similarity index 100%
rename from tests/js/test_mf-api.js
rename to tests/javascripts/common/test_mf-api.js
diff --git a/tests/js/test_application.js 
b/tests/javascripts/common/test_mf-application.js
similarity index 100%
rename from tests/js/test_application.js
rename to tests/javascripts/common/test_mf-application.js
diff --git a/tests/js/test_mf-history.js 
b/tests/javascripts/common/test_mf-history.js
similarity index 100%
rename from tests/js/test_mf-history.js
rename to tests/javascripts/common/test_mf-history.js
diff --git a/tests/js/common/mf-navigation.js 
b/tests/javascripts/common/test_mf-navigation.js
similarity index 82%
rename from tests/js/common/mf-navigation.js
rename to tests/javascripts/common/test_mf-navigation.js
index 57d9255..ecaf77d 100644
--- a/tests/js/common/mf-navigation.js
+++ b/tests/javascripts/common/test_mf-navigation.js
@@ -2,19 +2,20 @@
 
 QUnit.module( 'MobileFrontend: mf-navigation.js' );
 
-QUnit.test( 'Simple overlay', 2, function() {
+QUnit.test( 'Simple overlay', 1, function() {
        var overlay = new nav.Overlay( { heading: '<h2>Title</h2>', content: 
'Text' } );
        overlay.show();
        strictEqual( overlay.$el[0].parentNode, document.body, 'In DOM' );
-       strictEqual( overlay.$el.html(), '<h2>Title</h2>/Text' );
+       overlay.hide();
 } );
 
-QUnit.test( 'HTML overlay', 1, function() {
+QUnit.test( 'HTML overlay', 2, function() {
        var overlay = new nav.Overlay( {
-               heading: '<div>Awesome: <input></div>',
+               heading: '<div id="test">Awesome: <input></div>',
                content: '<div class="content">YO</div>'
        } );
-       strictEqual( overlay.$el.html(), '<div>Awesome: <input></div>/<div 
class="content">YO</div>' );
+       strictEqual( overlay.$el.find( '#test' ).html(), 'Awesome: <input>' );
+       strictEqual( overlay.$el.find( '.content' ).text(), 'YO' );
 } );
 
 QUnit.test( 'Close overlay', 1, function() {
@@ -41,6 +42,7 @@
        strictEqual( overlayTwo.$el[0].parentNode, null, 'No longer in DOM' );
        strictEqual( overlay.$el[0].parentNode, document.body, 'Still in DOM' );
        strictEqual( $( 'html' ).hasClass( 'overlay' ), true, 'Still in overlay 
mode' );
+       overlay.hide();
 } );
 
 
diff --git a/tests/js/test_mf-oop.js b/tests/javascripts/common/test_mf-oop.js
similarity index 100%
rename from tests/js/test_mf-oop.js
rename to tests/javascripts/common/test_mf-oop.js
diff --git a/tests/js/test_settings.js 
b/tests/javascripts/common/test_mf-settings.js
similarity index 76%
rename from tests/js/test_settings.js
rename to tests/javascripts/common/test_mf-settings.js
index 86b241e..a34495f 100644
--- a/tests/js/test_settings.js
+++ b/tests/javascripts/common/test_mf-settings.js
@@ -3,7 +3,7 @@
 
 QUnit.test( 'read and write cookies', 1, function() {
        var cookie_name = 'test_cookies_module', cookieVal;
-       MFEB.writeCookie(cookie_name, "yes", 400);
+       MFEB.writeCookie( cookie_name, 'yes', 40000 );
        cookieVal = MFEB.readCookie( cookie_name );
        strictEqual(cookieVal, "yes",
                "Are you running off localhost?");
@@ -11,8 +11,8 @@
 
 QUnit.test( 'read and write cookies with spaces', 1, function() {
        var cookie_name = 'test_cookies_module', cookieVal;
-       MFEB.writeCookie(cookie_name, "     yes this has spaces    ", 400);
-       MFEB.writeCookie(cookie_name + "2", "     yes this has spaces    ", 
400);
+       MFEB.writeCookie( cookie_name, '     yes this has spaces    ', 40000 );
+       MFEB.writeCookie( cookie_name + '2', '     yes this has spaces    ', 
40000 );
        cookieVal = MFEB.readCookie( cookie_name );
        strictEqual(cookieVal, "yes this has spaces",
                "spaces are kept and trailing whitespace is removed");
@@ -20,7 +20,7 @@
 
 QUnit.test( 'remove cookie via write', 1, function() {
        var cookie_name = 'test_cookies_module', cookieVal;
-       MFEB.writeCookie(cookie_name, "", -1);
+       MFEB.writeCookie( cookie_name, "", -1 );
        cookieVal = MFEB.readCookie( cookie_name );
        strictEqual(cookieVal, null, "Cookie deleted");
 });
diff --git a/tests/js/test_mf-view.js b/tests/javascripts/common/test_mf-view.js
similarity index 100%
rename from tests/js/test_mf-view.js
rename to tests/javascripts/common/test_mf-view.js
diff --git a/tests/js/fixtures.js b/tests/javascripts/fixtures.js
similarity index 76%
rename from tests/js/fixtures.js
rename to tests/javascripts/fixtures.js
index 0feb75c..d077f20 100644
--- a/tests/js/fixtures.js
+++ b/tests/javascripts/fixtures.js
@@ -1,3 +1,2 @@
 mw.config.set( 'wgInitOnDefine', false );
 mw.config.set( 'wgUserName', 'EvilPanda' );
-function _mwLogEvent() {}
diff --git a/tests/js/test_mf-last-modified.js 
b/tests/javascripts/modules/test_mf-last-modified.js
similarity index 100%
rename from tests/js/test_mf-last-modified.js
rename to tests/javascripts/modules/test_mf-last-modified.js
diff --git a/tests/js/test_mf-photo.js 
b/tests/javascripts/modules/test_mf-photo.js
similarity index 92%
rename from tests/js/test_mf-photo.js
rename to tests/javascripts/modules/test_mf-photo.js
index 3122430..4782a2c 100644
--- a/tests/js/test_mf-photo.js
+++ b/tests/javascripts/modules/test_mf-photo.js
@@ -45,21 +45,18 @@
 
 QUnit.test( 'PhotoUploadProgress', 3, function() {
        var progressPopup = new photo._PhotoUploadProgress();
-       strictEqual(
-               progressPopup.$( '.wait' ).text(),
-               '<mobile-frontend-image-uploading-wait>',
+       ok(
+               progressPopup.$( '.wait' ).text().match( /wait/ ),
                'set initial wait message'
        );
        this.clock.tick( 11000 );
-       strictEqual(
-               progressPopup.$( '.wait' ).text(),
-               '<mobile-frontend-image-uploading-long>',
+       ok(
+               progressPopup.$( '.wait' ).text().match( /still/ ),
                'set secondary wait message'
        );
        this.clock.tick( 11000 );
-       strictEqual(
-               progressPopup.$( '.wait' ).text(),
-               '<mobile-frontend-image-uploading-wait>',
+       ok(
+               progressPopup.$( '.wait' ).text().match( /wait/ ),
                'set initial wait message again'
        );
 } );
diff --git a/tests/js/test_references.js 
b/tests/javascripts/modules/test_mf-references.js
similarity index 100%
rename from tests/js/test_references.js
rename to tests/javascripts/modules/test_mf-references.js
diff --git a/tests/js/test_beta_opensearch.js 
b/tests/javascripts/modules/test_mf-search.js
similarity index 100%
rename from tests/js/test_beta_opensearch.js
rename to tests/javascripts/modules/test_mf-search.js
diff --git a/tests/js/test_toggle.js 
b/tests/javascripts/modules/test_mf-toggle.js
similarity index 100%
rename from tests/js/test_toggle.js
rename to tests/javascripts/modules/test_mf-toggle.js
diff --git a/tests/js/test_mf-watchstar.js 
b/tests/javascripts/modules/test_mf-watchstar.js
similarity index 100%
rename from tests/js/test_mf-watchstar.js
rename to tests/javascripts/modules/test_mf-watchstar.js
diff --git a/tests/js/specials/mobilediff.js 
b/tests/javascripts/specials/test_mobilediff.js
similarity index 100%
rename from tests/js/specials/mobilediff.js
rename to tests/javascripts/specials/test_mobilediff.js
diff --git a/tests/js/specials/uploads.js 
b/tests/javascripts/specials/test_uploads.js
similarity index 100%
rename from tests/js/specials/uploads.js
rename to tests/javascripts/specials/test_uploads.js
diff --git a/tests/js/views/page.js b/tests/javascripts/views/test_page.js
similarity index 100%
rename from tests/js/views/page.js
rename to tests/javascripts/views/test_page.js
diff --git a/tests/javascripts/widgets/test_carousel.js 
b/tests/javascripts/widgets/test_carousel.js
new file mode 100644
index 0000000..e454014
--- /dev/null
+++ b/tests/javascripts/widgets/test_carousel.js
@@ -0,0 +1,46 @@
+( function( M ) {
+
+       var Carousel = M.require( 'widgets/carousel' );
+
+       QUnit.module( 'MobileFrontend Carousel', {
+               setup: function() {
+                       this.c = new Carousel( {
+                               pages: [
+                                       { text: 'test-1', className: 'page-1', 
id: 1 },
+                                       { text: 'test-2', className: 'page-2', 
id: 2 },
+                                       { text: 'test-3', className: 'page-3', 
id: 3 }
+                               ]
+                       } );
+               }
+       } );
+
+       QUnit.test( '#next', 5, function() {
+               strictEqual( this.c.totalPages, 3, 'There are 3 pages in the 
carousel' );
+               strictEqual( this.c.page, 0, 'Initialises to page 0' );
+               this.c.next();
+               strictEqual( this.c.page, 1, 'Now page 1' );
+               this.c.next();
+               strictEqual( this.c.page, 2, 'Now page 2' );
+               this.c.next();
+               strictEqual( this.c.page, 2, 'Still page 2 (no more pages)' );
+       } );
+
+       QUnit.test( '#prev', 4, function() {
+               strictEqual( this.c.page, 0, 'Initialises to page 0' );
+               this.c.previous();
+               strictEqual( this.c.page, 0, 'No previous page' );
+               this.c.next();
+               strictEqual( this.c.page, 1, 'Now page 1' );
+               this.c.previous();
+               strictEqual( this.c.page, 0, 'Back on page 0' );
+       } );
+
+       QUnit.test( '#showCurrentPage', 3, function() {
+               strictEqual( this.c.page, 0, 'Initialises to page 0' );
+               this.c.next();
+               this.c.showCurrentPage();
+               strictEqual( this.c.$( '.page' ).eq( 0 ).css( 'display' ), 
'none', 'First page is hidden' );
+               strictEqual( this.c.$( '.page' ).eq( 1 ).css( 'display' ), 
'block', 'Second page is visible' );
+       } );
+
+}( mw.mobileFrontend, jQuery ) );
diff --git a/tests/js/widgets/test_progress-bar.js 
b/tests/javascripts/widgets/test_progress-bar.js
similarity index 100%
rename from tests/js/widgets/test_progress-bar.js
rename to tests/javascripts/widgets/test_progress-bar.js
diff --git a/tests/js/fixtures-templates.js b/tests/js/fixtures-templates.js
deleted file mode 100644
index e886b0e..0000000
--- a/tests/js/fixtures-templates.js
+++ /dev/null
@@ -1,8 +0,0 @@
-mw.mobileFrontend.template.add( 'photoUploadPreview', '' );
-mw.mobileFrontend.template.add( 'leadPhoto', '' );
-mw.mobileFrontend.template.add( 'photoUploader', '' );
-mw.mobileFrontend.template.add( 'ctaDrawer', '' );
-mw.mobileFrontend.template.add( 'overlay', '{{{heading}}}/{{{content}}}' );
-mw.mobileFrontend.template.add( 'overlays/photoCopyrightDialog', '' );
-mw.mobileFrontend.template.add( 'specials/uploads/carousel',
-       '<div class="carousel"><div class="page" /><div class="page" /><div 
class="page" /></div>' );
diff --git a/tests/js/widgets/carousel.js b/tests/js/widgets/carousel.js
deleted file mode 100644
index 904b87e..0000000
--- a/tests/js/widgets/carousel.js
+++ /dev/null
@@ -1,39 +0,0 @@
-( function( M ) {
-
-       var Carousel = M.require( 'widgets/carousel' );
-
-       QUnit.module( 'MobileFrontend Carousel' );
-
-       QUnit.test( '#next', 5, function() {
-               var c = new Carousel();
-               strictEqual( c.totalPages, 3, 'There are 3 pages in the 
carousel' );
-               strictEqual( c.page, 0, 'Initialises to page 0' );
-               c.next();
-               strictEqual( c.page, 1, 'Now page 1' );
-               c.next();
-               strictEqual( c.page, 2, 'Now page 2' );
-               c.next();
-               strictEqual( c.page, 2, 'Still page 2 (no more pages)' );
-       } );
-
-       QUnit.test( '#prev', 4, function() {
-               var c = new Carousel();
-               strictEqual( c.page, 0, 'Initialises to page 0' );
-               c.previous();
-               strictEqual( c.page, 0, 'No previous page' );
-               c.next();
-               strictEqual( c.page, 1, 'Now page 1' );
-               c.previous();
-               strictEqual( c.page, 0, 'Back on page 0' );
-       } );
-
-       QUnit.test( '#showCurrentPage', 3, function() {
-               var c = new Carousel();
-               strictEqual( c.page, 0, 'Initialises to page 0' );
-               c.next();
-               c.showCurrentPage();
-               strictEqual( c.$( '.page' ).eq( 0 ).css( 'display' ), 'none', 
'First page is hidden' );
-               strictEqual( c.$( '.page' ).eq( 1 ).css( 'display' ), 'block', 
'Second page is visible' );
-       } );
-
-}( mw.mobileFrontend, jQuery ) );
diff --git a/tests/templates/template.html b/tests/templates/template.html
deleted file mode 100644
index ce01362..0000000
--- a/tests/templates/template.html
+++ /dev/null
@@ -1 +0,0 @@
-hello
diff --git a/tests/templates/template2.html b/tests/templates/template2.html
deleted file mode 100644
index dd7e1c6..0000000
--- a/tests/templates/template2.html
+++ /dev/null
@@ -1 +0,0 @@
-goodbye

-- 
To view, visit https://gerrit.wikimedia.org/r/50442
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I593a9c0e8edcb04a351a06a457327f63d698a298
Gerrit-PatchSet: 12
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: JGonera <[email protected]>
Gerrit-Reviewer: JGonera <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: MaxSem <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to