Home page Forum Wiki Mail Jabber Devel NIX-FILES

AltLUG Git

Git-repositories of Altai Linux User Group

Lint: Tighten .jshintrc options and enforce them.
authorTimo Tijhof <krinklemail@gmail.com>
Tue, 30 Oct 2012 06:12:04 +0000 (07:12 +0100)
committerTimo Tijhof <krinklemail@gmail.com>
Tue, 30 Oct 2012 06:12:04 +0000 (07:12 +0100)
Re-ordered .jshintrc to be alphabetical once again (like on
jshint.com/docs/) and by section (predef, restriction,
toleration, environment, legacy).

Enforce eqeqeq:true, and hard-code camelcase:false since we
have a few underscore ones.

"delete x" problem:
* "delete x" never passes jshint, we should use window.x instead.
* "delete window.x" doesn't work in IE6-8 (throws exception)
* "delete x" only works for "x = 1", not for "window.x".
* Only solution I see: use IE @cc comments for the IE version
  of the test.
* See also http://jsfiddle.net/8X6cS/6/
  IE6: supportDeleteProperty = false, jscriptVersion = 5.6
  IE7: supportDeleteProperty = false, jscriptVersion = 5.7
  IE8: supportDeleteProperty = false, jscriptVersion = 5.8
  IE9: supportDeleteProperty = true, jscriptVersion = 9
  IE10: supportDeleteProperty = true, jscriptVersion = 10

Follows-up dbd005333d23dc1b248a3b6d17f32ab2b2396c66

grunt.js
qunit/.jshintrc
qunit/qunit.js
test/.jshintrc
test/deepEqual.js
test/test.js

index ad60639..c0cb61f 100644 (file)
--- a/grunt.js
+++ b/grunt.js
@@ -18,9 +18,8 @@ grunt.initConfig({
        lint: {
                qunit: 'qunit/qunit.js',
                addons: 'addons/**.js',
-               grunt: 'grunt.js'
-               // TODO fix remaining warnings
-               // tests: 'test/**.js'
+               grunt: 'grunt.js',
+               tests: 'test/**.js'
        },
        // TODO rmeove this one grunt 0.4 is out, see jquery-ui for other details
        jshint: (function() {
index 04aa9de..e867457 100644 (file)
@@ -1,22 +1,27 @@
 {
-       "onevar": true,
-       "browser": true,
+       "predef": [
+               "jQuery",
+               "exports"
+       ],
+
        "bitwise": true,
+       "camelcase": false,
        "curly": true,
-       "trailing": true,
+       "eqeqeq": true,
        "immed": true,
        "latedef": false,
        "newcap": true,
        "noarg": false,
        "noempty": true,
        "nonew": true,
-       "sub": true,
        "undef": true,
-       "eqnull": true,
+
        "proto": true,
        "smarttabs": true,
-       "predef": [
-               "jQuery",
-               "exports"
-       ]
+       "sub": true,
+       "trailing": true,
+
+       "browser": true,
+
+       "onevar": true
 }
index 85fdaef..e1b355b 100644 (file)
@@ -162,11 +162,11 @@ Test.prototype = {
        },
        finish: function() {
                config.current = this;
-               if ( config.requireExpects && this.expected == null ) {
+               if ( config.requireExpects && this.expected === null ) {
                        QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
-               } else if ( this.expected != null && this.expected != this.assertions.length ) {
+               } else if ( this.expected !== null && this.expected !== this.assertions.length ) {
                        QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
-               } else if ( this.expected == null && !this.assertions.length ) {
+               } else if ( this.expected === null && !this.assertions.length ) {
                        QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
                }
 
@@ -225,7 +225,7 @@ Test.prototype = {
 
                        addEvent(b, "dblclick", function( e ) {
                                var target = e && e.target ? e.target : window.event.srcElement;
-                               if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
+                               if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) {
                                        target = target.parentNode;
                                }
                                if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
@@ -460,6 +460,7 @@ assert = {
         * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
         */
        equal: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
                QUnit.push( expected == actual, actual, expected, message );
        },
 
@@ -468,6 +469,7 @@ assert = {
         * @function
         */
        notEqual: function( actual, expected, message ) {
+               /*jshint eqeqeq:false */
                QUnit.push( expected != actual, actual, expected, message );
        },
 
@@ -758,7 +760,7 @@ extend( QUnit, {
 
        // Safe object type checking
        is: function( type, obj ) {
-               return QUnit.objectType( obj ) == type;
+               return QUnit.objectType( obj ) === type;
        },
 
        objectType: function( obj ) {
@@ -817,7 +819,7 @@ extend( QUnit, {
                        actual = escapeInnerText( QUnit.jsDump.parse(actual) );
                        output += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" + expected + "</pre></td></tr>";
 
-                       if ( actual != expected ) {
+                       if ( actual !== expected ) {
                                output += "<tr class='test-actual'><th>Result: </th><td><pre>" + actual + "</pre></td></tr>";
                                output += "<tr class='test-diff'><th>Diff: </th><td><pre>" + QUnit.diff( expected, actual ) + "</pre></td></tr>";
                        }
@@ -1227,7 +1229,7 @@ function extractStacktrace( e, offset ) {
                if ( fileName ) {
                        include = [];
                        for ( i = offset; i < stack.length; i++ ) {
-                               if ( stack[ i ].indexOf( fileName ) != -1 ) {
+                               if ( stack[ i ].indexOf( fileName ) !== -1 ) {
                                        break;
                                }
                                include.push( stack[ i ] );
@@ -1448,6 +1450,7 @@ QUnit.equiv = (function() {
 
                        // for string, boolean, number and null
                        function useStrictEquality( b, a ) {
+                               /*jshint eqeqeq:false */
                                if ( b instanceof a.constructor || a instanceof b.constructor ) {
                                        // to catch short annotaion VS 'new' annotation of a
                                        // declaration
@@ -1653,16 +1656,16 @@ QUnit.jsDump = (function() {
                                type = typeof parser;
                                inStack = inArray( obj, stack );
 
-                               if ( inStack != -1 ) {
+                               if ( inStack !== -1 ) {
                                        return "recursion(" + (inStack - stack.length) + ")";
                                }
-                               if ( type == "function" )  {
+                               if ( type === "function" )  {
                                        stack.push( obj );
                                        res = parser.call( this, obj, stack );
                                        stack.pop();
                                        return res;
                                }
-                               return ( type == "string" ) ? parser : this.parsers.error;
+                               return ( type === "string" ) ? parser : this.parsers.error;
                        },
                        typeOf: function( obj ) {
                                var type;
@@ -1878,6 +1881,7 @@ function inArray( elem, array ) {
  * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
  */
 QUnit.diff = (function() {
+       /*jshint eqeqeq:false, eqnull:true */
        function diff( o, n ) {
                var i,
                        ns = {},
@@ -1907,7 +1911,7 @@ QUnit.diff = (function() {
                        if ( !hasOwn.call( ns, i ) ) {
                                continue;
                        }
-                       if ( ns[i].rows.length == 1 && typeof os[i] != "undefined" && os[i].rows.length == 1 ) {
+                       if ( ns[i].rows.length === 1 && os[i] !== undefined && os[i].rows.length === 1 ) {
                                n[ ns[i].rows[0] ] = {
                                        text: n[ ns[i].rows[0] ],
                                        row: os[i].rows[0]
@@ -2013,7 +2017,7 @@ QUnit.diff = (function() {
 
 // for CommonJS enviroments, export everything
 if ( typeof exports !== "undefined" ) {
-       extend(exports, QUnit);
+       extend( exports, QUnit );
 }
 
 // get at whatever the global object is, like window in browsers
index 7edcc8f..b14a0bc 100644 (file)
@@ -2,6 +2,8 @@
        "predef": [
                "QUnit"
        ],
-       "browser": true,
-       "smarttabs": true
+
+       "smarttabs": true,
+
+       "browser": true
 }
index 6f1e901..7894485 100644 (file)
@@ -70,38 +70,43 @@ test("Primitive types and constants", function () {
        equal(QUnit.equiv('', null), false, "string");
        equal(QUnit.equiv('', undefined), false, "string");
 
+       // Rename for lint validation.
+       // We know this is bad, we are asserting whether we can coop with bad code like this.
+       var SafeNumber = Number, SafeString = String, SafeBoolean = Boolean, SafeObject = Object;
+
        // primitives vs. objects
-       equal(QUnit.equiv(0, new Number()), true, "primitives vs. objects");
-       equal(QUnit.equiv(new Number(), 0), true, "primitives vs. objects");
-       equal(QUnit.equiv(1, new Number(1)), true, "primitives vs. objects");
-       equal(QUnit.equiv(new Number(1), 1), true, "primitives vs. objects");
-       equal(QUnit.equiv(new Number(0), 1), false, "primitives vs. objects");
-       equal(QUnit.equiv(0, new Number(1)), false, "primitives vs. objects");
-
-       equal(QUnit.equiv(new String(), ""), true, "primitives vs. objects");
-       equal(QUnit.equiv("", new String()), true, "primitives vs. objects");
-       equal(QUnit.equiv(new String("My String"), "My String"), true, "primitives vs. objects");
-       equal(QUnit.equiv("My String", new String("My String")), true, "primitives vs. objects");
-       equal(QUnit.equiv("Bad String", new String("My String")), false, "primitives vs. objects");
-       equal(QUnit.equiv(new String("Bad String"), "My String"), false, "primitives vs. objects");
-
-       equal(QUnit.equiv(false, new Boolean()), true, "primitives vs. objects");
-       equal(QUnit.equiv(new Boolean(), false), true, "primitives vs. objects");
-       equal(QUnit.equiv(true, new Boolean(true)), true, "primitives vs. objects");
-       equal(QUnit.equiv(new Boolean(true), true), true, "primitives vs. objects");
-       equal(QUnit.equiv(true, new Boolean(1)), true, "primitives vs. objects");
-       equal(QUnit.equiv(false, new Boolean(false)), true, "primitives vs. objects");
-       equal(QUnit.equiv(new Boolean(false), false), true, "primitives vs. objects");
-       equal(QUnit.equiv(false, new Boolean(0)), true, "primitives vs. objects");
-       equal(QUnit.equiv(true, new Boolean(false)), false, "primitives vs. objects");
-       equal(QUnit.equiv(new Boolean(false), true), false, "primitives vs. objects");
-
-       equal(QUnit.equiv(new Object(), {}), true, "object literal vs. instantiation");
-       equal(QUnit.equiv({}, new Object()), true, "object literal vs. instantiation");
-       equal(QUnit.equiv(new Object(), {a:1}), false, "object literal vs. instantiation");
-       equal(QUnit.equiv({a:1}, new Object()), false, "object literal vs. instantiation");
-       equal(QUnit.equiv({a:undefined}, new Object()), false, "object literal vs. instantiation");
-       equal(QUnit.equiv(new Object(), {a:undefined}), false, "object literal vs. instantiation");
+
+       equal(QUnit.equiv(0, new SafeNumber()), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeNumber(), 0), true, "primitives vs. objects");
+       equal(QUnit.equiv(1, new SafeNumber(1)), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeNumber(1), 1), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeNumber(0), 1), false, "primitives vs. objects");
+       equal(QUnit.equiv(0, new SafeNumber(1)), false, "primitives vs. objects");
+
+       equal(QUnit.equiv(new SafeString(), ""), true, "primitives vs. objects");
+       equal(QUnit.equiv("", new SafeString()), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeString("My String"), "My String"), true, "primitives vs. objects");
+       equal(QUnit.equiv("My String", new SafeString("My String")), true, "primitives vs. objects");
+       equal(QUnit.equiv("Bad String", new SafeString("My String")), false, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeString("Bad String"), "My String"), false, "primitives vs. objects");
+
+       equal(QUnit.equiv(false, new SafeBoolean()), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeBoolean(), false), true, "primitives vs. objects");
+       equal(QUnit.equiv(true, new SafeBoolean(true)), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeBoolean(true), true), true, "primitives vs. objects");
+       equal(QUnit.equiv(true, new SafeBoolean(1)), true, "primitives vs. objects");
+       equal(QUnit.equiv(false, new SafeBoolean(false)), true, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeBoolean(false), false), true, "primitives vs. objects");
+       equal(QUnit.equiv(false, new SafeBoolean(0)), true, "primitives vs. objects");
+       equal(QUnit.equiv(true, new SafeBoolean(false)), false, "primitives vs. objects");
+       equal(QUnit.equiv(new SafeBoolean(false), true), false, "primitives vs. objects");
+
+       equal(QUnit.equiv(new SafeObject(), {}), true, "object literal vs. instantiation");
+       equal(QUnit.equiv({}, new SafeObject()), true, "object literal vs. instantiation");
+       equal(QUnit.equiv(new SafeObject(), {a:1}), false, "object literal vs. instantiation");
+       equal(QUnit.equiv({a:1}, new SafeObject()), false, "object literal vs. instantiation");
+       equal(QUnit.equiv({a:undefined}, new SafeObject()), false, "object literal vs. instantiation");
+       equal(QUnit.equiv(new SafeObject(), {a:undefined}), false, "object literal vs. instantiation");
 });
 
 test("Objects Basics.", function() {
index a761604..1e3a121 100644 (file)
@@ -62,13 +62,32 @@ module("setup/teardown test", {
        setup: function() {
                state = true;
                ok(true);
-               x = 1;
+               // Assert that we can introduce and delete globals in setup/teardown
+               // without noglobals sounding any alarm.
+
+               // Using an implied global variable instead of explicit window property
+               // because there is no way to delete a window.property in IE6-8
+               // `delete x` only works for `x = 1, and `delete window.x` throws exception.
+               // No one-code fits all solution possible afaic. Resort to @cc.
+
+               /*@cc_on
+                       @if (@_jscript_version < 9)
+                               x = 1;
+                       @else @*/
+                               window.x = 1;
+                       /*@end
+               @*/
        },
        teardown: function() {
                ok(true);
-               // can introduce and delete globals in setup/teardown
-               // without noglobals sounding the alarm
-               delete x;
+
+               /*@cc_on
+                       @if (@_jscript_version < 9)
+                               delete x;
+                       @else @*/
+                               delete window.x;
+                       /*@end
+               @*/
        }
 });
 
@@ -84,20 +103,18 @@ test("module without setup/teardown", function() {
        ok(true);
 });
 
-
-
 var orgDate;
 
 module("Date test", {
        setup: function() {
                orgDate = Date;
-               Date = function () {
+               window.Date = function () {
                        ok( false, 'QUnit should internally be independant from Date-related manipulation and testing' );
                        return new orgDate();
                };
        },
        teardown: function() {
-               Date = orgDate;
+               window.Date = orgDate;
        }
 });
 
@@ -129,7 +146,8 @@ test("parameter passed to stop increments semaphore n times", function() {
        stop(3);
        setTimeout(function() {
                state = "not enough starts";
-               start(), start();
+               start();
+               start();
        }, 13);
        setTimeout(function() {
                state = "done";
@@ -139,7 +157,9 @@ test("parameter passed to stop increments semaphore n times", function() {
 
 test("parameter passed to start decrements semaphore n times", function() {
        expect(1);
-       stop(), stop(), stop();
+       stop();
+       stop();
+       stop();
        setTimeout(function() {
                state = "done";
                start(3);

Hosting is provided AltSPAHow to use Git
Please direct any questions on jabber alex.wolf@jabber.ru

Valid HTML 4.0 Transitional Valid CSS!

Designer Alexander Wolf