Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Monday, January 5, 2015

npm test (a sample case study of selected libraries)

What are people using as 'Test a package' script for their node packages ? I have taken several node modules from my test project and searched for scripts.test in their package.json.

Here is complete listing of script.test values from package.json files:

assert-plus
aws-sign2
bindings
byline
cli
combined-stream
core-util-is
cssom
ctype
delayed-stream
difflib
domelementtype
forever-agent
heap
inherits
jshint
json-diff.bin
mime
nan
node-uuid
nwmatcher
tunnel-agent
xml2js
xmlhttprequest
xpath
dreamopt             ./node_modules/.bin/mocha
json-diff            ./node_modules/mocha/bin/mocha
json-diff-patch      echo Error: no test specified && exit 1
wordwrap             expresso
when                 jshint . && buster-test -e node && promises-aplus-tests test/promises-aplus-adapter.js
json                 make test
printf               make test
qs                   make test
boom                 make test-cov
cryptiles            make test-cov
hawk                 make test-cov
hoek                 make test-cov
sntp                 make test-cov
entities             mocha && npm run lint
htmlparser2          mocha && npm run lint
domhandler           mocha -R list && jshint index.js test/
domutils             mocha test/tests/**.js && jshint index.js test/**/*.js lib/*.js
cli-color            node ./node_modules/tad/bin/tad lib
es5-ext              node ./node_modules/tad/bin/tad lib
jsdom                node ./test/runner
inherits             node test
marked               node test
json-stringify-safe  node test.js
oauth-sign           node test.js
sax                  node test/index.js
combined-stream      node test/run.js
form-data            node test/run.js
request              node tests/run.js
punycode             node tests/tests.js
open                 node_modules/mocha/bin/mocha
contextify           nodeunit test/
async                nodeunit test/test-async.js
cssstyle             nodeunit tests
xmldom               proof platform win32 && proof test */*/*.t.js || t/test
JSONStream           set -e; for t in test/*.js; do echo '***'  '***'; node ; done
through              set -e; for t in test/*.js; do node ; done
asn1                 tap ./tst
lru-cache            tap test
minimatch            tap test
glob                 tap test/*.js
graceful-fs          tap test/*.js
isarray              tap test/*.js
jsonparse            tap test/*.js
sigmund              tap test/*.js
readable-stream      tap test/simple/*.js
string_decoder       tap test/simple/*.js
http-signature       tap tst/*.js
tough-cookie         vows test.js

No test specified

25 modules have no test specified. It means they have no test or if they have it, you must read the manual how to run it.

tap (Test Anything Protocol tools for node)

11 modules uses tap.

mocha

7 modules uses mocha as their test runner. Also here are differencies, some people rely on global mocha installed, some use local node module.

dreamopt             ./node_modules/.bin/mocha
json-diff            ./node_modules/mocha/bin/mocha
entities             mocha && npm run lint
htmlparser2          mocha && npm run lint
domhandler           mocha -R list && jshint index.js test/
domutils             mocha test/tests/**.js && jshint index.js test/**/*.js lib/*.js
open                 node_modules/mocha/bin/mocha

make

8 uses make

vows

1 uses vows - Asynchronous BDD & continuous integration for node.js

Linting as part of test process

5 uses linting as part of their test process, some more can be hidden in make files (TODO:)

when                 jshint . && buster-test -e node && promises-aplus-tests test/promises-aplus-adapter.js
entities             mocha && npm run lint
htmlparser2          mocha && npm run lint
domhandler           mocha -R list && jshint index.js test/
domutils             mocha test/tests/**.js && jshint index.js test/**/*.js lib/*.js

npm run lint and scripts.lint

Some projects also use scrpts.lint property in their package.json file.

This is arbitrary script and can be run with npm run lint

scripts:{
    ....
    lint: jshint index.js lib/*.js test/*.js,
    ....
    lint: jshint lib/*.js test/*.js test/*/*.js
    ....
}

Naming your test folder

test vs. tests vs. tst or even using directories: in package.json

test modules and devDependencies

Please do not put test harnesses or transpilers in your dependencies object. See devDependencies, below.

Most of used modules use this correctly anyway, for mocha and tap based project.

Other patterns seen

TODO: finish the texts

directories: {
  test: tests
}

// in domutils/package.json

Lessons learned

How npm handles the scripts field

Must read: https://docs.npmjs.com/misc/scripts

Flexible definition of test frameworks

{
  devDependencies: {
    tap: ,
    mocha:
  },
  scripts: {
    test-tap: tap tst/*.js,
    test-mocha:mocha -R list .,

    test:npm run test-mocha
  }
}

Combining test from multile steps

{
  "devDependencies": {
    "tap": "",
    "mocha": "",
    "nsp": "",
    "jshint": ""
  },
  "scripts": {
    "test-tap": "tap tst/*.js",
    "test-mocha": "mocha -R list .",
    "lint": "jshint test/test.js",
    "test-security": "npm shrinkwrap && nsp audit-shrinkwrap",


    "test": "npm run test-mocha && npm run lint && npm run test-security"
  }
}   

This features also nsp, nodesecurity project, to check your dependencies for known vulnerabilities as part of test process.

tap vs. mocha vs. vows vs. ...

Currently I use mocha on my projects. Based on my dependency modules analyzed the tap seems more popular however.

In global mocha seems to be most popular an raising. see www.npm-stats.com for charts: vows, tap and mocha

Wednesday, March 26, 2014

Dojo and usage of has()

Quote from: http://livedocs.dojotoolkit.org/dojo/has Browser sniffing and feature inference are flawed techniques for detecting browser support in client side JavaScript. So lets face the truth, dojo's own code base and how many time has(something) is used
62 "ie"
14 "quirks"
14 "dojo-sync-loader"
12 "webkit"
11 "extend-dojo"
10 "opera"
 9 "touch"
 9 "host-browser"
 7 "safari"
 7 "mozilla"
 7 "dojo-combo-api"
 5 "mac"
 5 "dom-addeventlistener"
 5 "dojo-trace-api"
 5 "bug-for-in-skips-shadowed"
 4 "ios"
 4 "highcontrast"
 4 "dom"
 4 "dojo-requirejs-api"
 4 "config-deferredInstrumentation"
 4 "chrome"
 3 'activex'
 3 "khtml"
 3 "host-rhino"
 3 "host-node"
 3 "ff"
 3 "dojo-v1x-i18n-Api"
 3 "dojo-preload-i18n-Api"
 3 "dojo-loader-eval-hint-url"
 3 "dojo-loader"
 3 "dojo-inject-api"
 3 "dojo-config-api"
 3 "config-useDeferredInstrumentation"
 3 "config-dojo-loader-catches"
 3 "android"
 3 "air"
 2 name
 2 'native-xhr'
 2 'config-dojoBlankHtmlUrl'
 2 "trident"
 2 "ie-event-behavior"
 2 "dom-qsa2.1"
 2 "dojo-unit-tests"
 2 "dojo-undef-api"
 2 "dojo-publish-privates"
 2 "dojo-log-api"
 2 "dojo-debug-messages"
 2 "dojo-cdn"
 2 "dojo-amd-factory-scan"
 2 "array-extensible"
 1 term
 1 'script-readystatechange'
 1 'native-xhr2'
 1 'native-formdata'
 1 'mozilla'
 1 'host-node'
 1 'host-browser'
 1 'dom-qsa2.1'
 1 'dom-parser'
 1 'dojo-force-activex-xhr'
 1 'config-useXDomain'
 1 'config-requestProvider'
 1 "wii"
 1 "rtl-adjust-position-for-verticalScrollBar"
 1 "position-fixed-support"
 1 "native-xhr"
 1 "json-stringify"
 1 "json-parse"
 1 "jscript"
 1 "events-mousewheel"
 1 "events-keypress-typed"
 1 "event-stopimmediatepropagation"
 1 "event-orientationchange"
 1 "event-focusin"
 1 "dom-quirks"
 1 "dom-qsa3"
 1 "dom-qsa"
 1 "dom-parser"
 1 "dom-matches-selector"
 1 "dom-compliant-qsa"
 1 "dom-attributes-specified-flag"
 1 "dom-attributes-explicit"
 1 "dojo-timeout-api"
 1 "dojo-test-sniff"
 1 "dojo-sniff"
 1 "dojo-moduleUrl"
 1 "dojo-modulePaths"
 1 "dojo-has-api"
 1 "dojo-guarantee-console"
 1 "dojo-force-activex-xhr"
 1 "dojo-fast-sync-require"
 1 "dojo-enforceDefine"
 1 "dojo-dom-ready-api"
 1 "dojo-config-require"
 1 "dojo-config-addOnLoad"
 1 "dojo-built"
 1 "css-user-select"
 1 "config-tlmSiblingOfDojo"
 1 "config-stripStrict"
 1 "config-selectorEngine"
 1 "config-publishRequireResult"
 1 "config-_allow_leaks"

Thursday, July 4, 2013

XmlHttpRequest (XHR) and HTTP Redirects (testcase)

This is results of XHR behaviour in IE and Chrome regarding redirects. Enjoy.
Credits: dojo@gratex.com

Friday, April 13, 2012

QUIZ: JavaScript the Worst Parts ;-)

Every JS newcommer must love this language ;-))
Just and old collection, more is comming with anti-examples from "leading librares code";-))

Try to answer:

new Number(null)
new Number(undefined)
parseInt(null)
parseInt(undefined)
NaN instanceof Number
10 instanceof Number
Number(10) instanceof Number
typeof NaN
typeof 10
typeof new Number(10)
toString.call(NaN)
toString.call(10)
toString.call(Number(10))
NaN == NaN
NaN === NaN
NaN.toString
['a','b'][NaN]
if(NaN)

Thursday, February 24, 2011

Link of the day !

http://jdbartlett.github.com/innershiv/

thank you,thank you,thank you

Thursday, January 20, 2011

MSIE and incorrect .src and .href (final solution ?)

Could this be a final solution for uri resolving in .src and .href for MSIE ? (blogged before, search..)

function getUriRef(element, attrName) {
    //MSIE sometimes returns unnormalized .src or .href property 
    //for LINK and SCRIPT tags, it has not been observed on a.href
    // example: s.src returns "sss" instead of ptoto://auth/sss
    // this is observable always on "some" pages and "some" elements
    // in case .src does not work -> getAttribute('src',4) works
    // when .src works (returns abs. uri), getAttribute('src',4) does not work and returns (raw)
    // TODO: detect, dont do always, study reason why this happens
    var uri = element[attrName];
    if (uri != null) {
        if (!(/^[A-Z][0-9A-Z+\-\.]*:/i).test(uri)) {
            //TODO: TEST XB for additional param, but i dont expect any normal browser to fail here
            uri = element.getAttribute(attrName, 4);
        };
    }
    return uri;
}

Deadly jQuery Selectors (my naive jQuery programming)

Deadly jQuery Selectors (my naive jQuery programming)


// give me all tags with href or src attribute
*[href],*[src]

//MSIE 8: 20000 ms ;-(
//FF 3.6: 1 ms :-)

// simple fix for this is to use plain old dom:

var uri, uris=[], i, e;
for (es = d().getElementsByTagName("*"), i = es.length; i; ) {
e = es[--i];
uri = e.href || e.src;
if (uri) uris.push(uri);
}
// MSIE 8: 323 ms ;-| not so bad

Tuesday, January 18, 2011

waitFor function

Blind code (not tested)
any comments welcomed


function waitFor(condition, onSuccess, onTimeout, timeout, pollInterval) {
    // TODO: document + testcase
    pollInterval || (pollInterval = 100);
    var endTime = new Date().valueOf() + (timeout || 10000),
  errs, //condition eval errors
        c,    // condition eval result (can be object)  
        check = function () {
            try { c = condition(); }
            catch (ex) { (errs = (errs || [])).push(ex); }
            if (c)
                onSuccess(c);   //receives condition result (ca be {})
            else if (new Date().valueOf() < endTime)
                setTimeout(check, pollInterval);
            else if (onTimeout)
                onTimeout(errs); //receives err result (null or non empty [] of Error)
        };
    check();
};

Wednesday, January 12, 2011

Mobile Perf bookmarklet by @souders (Link of the day)

I have been very pleased by todays tweets
specially @souders compilation of other bookmarklets:

Mobile Perf bookmarklet

I have looked a bit closer to some of them:
First:
DOM Monster
and I have posted two comments to GitHub:

issue/8
and
issue/7
Happy to receive reply:

From: madrobby

You're welcome to submit pull requests/patches. However, I think DOM Monster will grow and change quite a bit so premature micro-optimizations might be a 

might early...

View Issue: https://github.com/madrobby/dom-monster/issues#issue/8/comment/672058

But:
I consider both issues as basic coding practice, not optimization ! (rename to JS Monster ?)
I'm not "skilled" with github (yet) sorry.

I'm willing to contribute, but cannot be forced into how and when.

Some ideas and wishes
from my own unfinished code performing "page analysis".
My code is not only performance based so some may not aplly to DOM Monster.
  • Inline Scripts Detection
  • Standard vs. Quircks mode
  • Empty ULs and others that cannot be empty (semantics)
  • Meta tag "best pracices"
  • Anti-SEO hunter (bad, old SEO practices detection)
  • jSession string and other identifiers in URLs
  • Accessibility checks
  • DHTML event registration
  • Ajax style links (# fragment links)
  • .... more and more

So my bookmarklet is/was mix and
I'm thinking (thanx to @souders)
about splitting it into more categories now
and maybe "reuse" existing code or whole bookmarklet,
once they will comply with minimal "js qualities" ;-)

Tuesday, November 16, 2010

ShadedBorder

http://www.ruzee.com/blog/shadedborder

almost unbelievable
what someone is willing
to do for "rounded corners" ;-))

Saturday, November 13, 2010

The Art & Science of JavaScript


http://www.sitepoint.com/books/jsdesign1/


The WORST book I have ordered and read this year !

Sorry for not being constructive and writing some detailed review, but I choose beer with friends instead.

Can not recomend unless you want to find what CUTTING-EDGE, INSPIRATIONAL and IMPRESSIVE and AMAZED is ment by sitepoint publisher.

Monday, October 11, 2010

VS2010 Code Snippets for Java Script

Just random notes about another "cool VS2010 feature"

"Visual Studio 2010 will include more than 200 built-in snippets
that you can immediately use when you install the product."

Excelent ;-) there are 13 "all useless" Java Script
snippets for basic lang constructs that hardly anyone needs
(if someone needs them I do not need her in my team)
including "deprecated with()" and "difficult to type alert()" ;-))

+ 5 incomplete XML Comments tags for VS2010 intellisence"
+ 3 MS Ajax snippets

Compared to easy creation of Toolbox items (drag and dropp)
the creation process of snippets
(XML file, edit, save, import etc..)
seems to be bit complicated if not unusable.

Snippet Designer

http://snippetdesigner.codeplex.com/
This helps with creation specially "extract snipped" context menu but still...
a lot of clicking to finish the snipped.
And if you make mistake (wrong language, wrong folder)
all gets complicated again.

After 30+ mins experimenting, I have managed to create this template
(it took me 5 minutes to press F4 and change properties ;-)))

What else we get with snippets ?

http://www.switchonthecode.com/tutorials/csharp-tutorial-visual-studio-code-snippets

If your not convinced that saved you that many keystrokes, theres another handy feature. See how the first "i" is highlighted

and the second two are surrounded by dotted lines? That means that those variables are supposed to be the same - which mean

that if you edit the first "i" right after you insert the code snippet, the other "i"s change to the new name automatically.

That 'linkage' isn't kept around forever, as soon as you go and edit something other than the snippet, those dotted lines go

away and any changes that you make later on don't automatically get propagated. But pretty cool, eh?
Cool but quite useless for while and for cycles.. but keep reading

MSDN (Offical Docs)


http://msdn.microsoft.com/en-us/library/ms165392(VS.80).aspx

Shortcut

a) type cnstr,TAB or cn,TAB,TAB and it will generate whole thing
b) change cnstr and p
and you have your own jQuery style construction pattern done.

After someone skilled creates template in 2-20 minutes
and ensures distribution of template to
"some sort of sharable location"
every "developer" can monkey type
and learn and memorize nothing.....

Next catch: Shortcut
This text is used as a shortcut for inserting the code snippet. The text value of a Shortcut element can only contain

alphanumeric characters, hyphens ( - ), and underscores ( _ ).
from http://msdn.microsoft.com/en-us/library/ms171440(v=VS.80).aspx

This is bug of code or bug of docs, if you name your shortcut with - or _
it will not work with TAB,TAB scenario.
It will be visisble in top level intellisence popup,
but will not expand.
So the best shortcut name to include some sort of namespacing is
hungarian notation as aitkCnstr, aitkModule, aitkSynchro etc...

So far...

I admit, this may be too quick experience but
i'm not impressed and I will love my "old memory" for obvious tasks
or
old fashion Toolbox + replace for more esoteric snippets.

I may write more when I learn more...

My first trial:

save somewhere to:
My Documents\Visual Studio 2010\Code Snippets\Visual Web Developer\My JScript Snippets\cnstr.snippet


<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Keywords>
<Keyword>construction</Keyword>
</Keywords>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
<Title>cnstr (jQuery style)</Title>
<Author>a.in.the.k</Author>
<Description>construction pattern ala jQuery</Description>
<HelpUrl>
</HelpUrl>
<Shortcut>aitkCnstr</Shortcut>
</Header>
<Snippet>
<Declarations>
<Literal Editable="true">
<ID>cnstr</ID>
<ToolTip>cnstr</ToolTip>
<Default>cnstr</Default>
<Function>
</Function>
</Literal>
<Literal Editable="true">
<ID>p</ID>
<ToolTip>p</ToolTip>
<Default>p</Default>
<Function>
</Function>
</Literal>
</Declarations>
<Code Language="jscript" Kind="type decl"><![CDATA[(function (window, undef) {

function $cnstr$($p$) {
/// <param name="$p$" type="String"></param>
/// <returns type="$cnstr$" />
return new $cnstr$.prototype.$cnstr$($p$);
}

$cnstr$.prototype = {
$cnstr$: function ($p$) {
this.$p$ = $p$;
}
};
$cnstr$.prototype.$cnstr$.prototype = $cnstr$.prototype;

// exports
window.$cnstr$ = $cnstr$;
})(window);]]></Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Friday, October 8, 2010

Fast and correct htmlEncoding for JavaScript

Feel free to adjust two last matches in the regexp to any of your needs. I encode all > 0x07 and from allowed ascii, I encode only big 5. Using regexp is still faster (specially on MSIE) than any other impl. var _encodeHtmlRegExpImpl = (function() { // performance is 78ms on MSIE 7 (the slowest one) // on 80KB html markup from: http://www.w3.org/TR/html4/ var re = new RegExp( // surrogate pair (sp) "([\uD800-\uDBFF][\uDC00-\uDFFF])" + // html UNUSED including standalone surogates (un) "|([\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F\uD800-\uDFFF])" + // out of ascii (oa) "|([^\u0000-\u007F])" + // big 5 + add others (b5) "|([\u0022\u0026\u0027\u003C\u003E])", "g" ), toCodePoint = function(high, low) { return ((high - 0xD800) << 10) + (low - 0xDC00) + 0x010000; }, enc = function(m, sp, un, oa, b5) { // extracted out from main function and ifs changed to ternary // thanx to Andrea Giammarchi return "&#" + (oa || b5 ? m.charCodeAt(0) : (un ? "xFFFD" : toCodePoint(m.charCodeAt(0), m.charCodeAt(1)))) + ";"; }; return function(s) { return s.replace(re, enc); } } ());

Thursday, September 23, 2010

string.replace with function benchmarks


function escapeRegExp(s) {
return s.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
};
function escapeRegExp_asFunction(s) {
return s.replace(/([-.*+?^${}()|[\]\/\\])/g, function(ch) {
return "\\" + ch;
});
};

Test case:

var loops = 10000,
s1 = "abcdefgjklmnoprstuvxyz",
s2 = "-.*+?^${}()|[]/\\",
s3 = "a-a.a*a+a?a^a$a{a}a(a)a|a[a]a/a\\a",
testStrings = [s1, s2, s3];

MSIE 7.0 results

escapeRegExp
78:abcdefgjklmnoprstuvxyz
110:\-\.\*\+\?\^\$\{\}\(\)\|\[\]\/\\
125:a\-a\.a\*a\+a\?a\^a\$a\{a\}a\(a\)a\|a\[a\]a\/a\\a

escapeRegExp_asFunction
110:abcdefgjklmnoprstuvxyz
797:\-\.\*\+\?\^\$\{\}\(\)\|\[\]\/\\
797:a\-a\.a\*a\+a\?a\^a\$a\{a\}a\(a\)a\|a\[a\]a\/a\\a


Using function as second parameter in replace is at least:

796/125 ~= 6 times slower than the first one on MSIE a
173/48 ~= 3 times slower on FF
77/61 ~= same speed on Safari !!!

on test string with half matched chars.

Tuesday, September 14, 2010

isArray, optimized ?

isArray optimized ?

The world has almost agreed that this is
correct check for Array in JavaScript.

var toString = Object.prototype.toString,
isArray: function(obj) {
return toString.call(obj) === "[object Array]";
};

Similar checks are used for Date or Numbers.
For those who may not know why, read this excelent explanation by kangax:

instanceof considered harmful (or how to write a robust isArray)


I have been curios about performance:

100 000 loops !!! times in mils compare native naive checks and the correct one.

MSIE 7.0
a instanceof Array 63:true
a.constructor === Array 62:true
toString.call(a) == [object Array] 235:true

Firefox/3.5.12
a instanceof Array 12:true
a.constructor === Array 41:true
toString.call(a) == [object Array] 51:true

Safari/533.18.5
a instanceof Array 2:true
a.constructor === Array 5:true
toString.call(a) == [object Array] 41:true

MSIE 7.0 is the slowest and penalty is >4 all browsers.

Again this is of course nothing in absolute numbers,
since we are talking about 100000 loops here !

Speedup for false checks

The penalty and measured times are "the same"
even if you pass null or undefined inside.

Since I use this method
often on attribute normalization
at the begining of my functions,
and many times the checked attribute is optional
(null, undefined or even "")

I propose small speed up with this code:

var toString = Object.prototype.toString,
isArray: function(obj) {
return (object!=null && toString.call(obj) === "[object Array]");
};

Yes the "evel twin" is intentional.
or even with

var toString = Object.prototype.toString,
isArray: function(obj) {
return (!!object && toString.call(obj) === "[object Array]");
};

Of course you pay some extra penalty for this (20ms/100000 loops on MSIE) in positive checks,
but it drops down false checks to almost no cost (31ms/100000 loops).
BTW do we need === to compare strings ?
Benchmarks:

arrLit toString.call(a) == [object Array] 219:true:[object Array]
arrLit optimized toString.call(a) 234:true:[object Array]

null toString.call(a) == [object Array] 203:false:[object Object]
null optimized toString.call(a) 31:false:[object Object]

You see the extra price on positive call 219 vs 234 and spped up 203 vs 31!
on null input

Of course you can still write the code outside of isArray
in each code where it makes sence
but I like it inside - optimized.

I see no sence to let null be converted to
[object Window] (on FF) and compared as string with [Object Array].

Thursday, September 2, 2010

JSLints and evil twins == (again)

This time I have used JSLint to recheck and possibly
polish some of my older sourcecodes:

As expected JSLint gave me
several messages

Problem at line 3 character 5: Expected '===' and instead saw '=='.

I decided to turn it off with /*jslint eqeqeq: false*/
and surpise... only SOME of the messages disapeared.

Try this:

1./*jslint eqeqeq: true*/
2.if(a==undefined){}
3.if(a==null){}
4. if(a==b){}


result (expected):

Error:
Problem at line 2 character 5: Expected '===' and instead saw '=='.
if(a==undefined){}
Problem at line 3 character 5: Expected '===' and instead saw '=='.
if(a==null){}
Problem at line 4 character 5: Expected '===' and instead saw '=='.
if(a==b){}
Implied global: a 2,3,4, b 4

all 3 lines reported as error.

Now try to turn it off:

/*jslint eqeqeq: false*/
if(a==undefined){}
if(a==null){}
if(a==b){}

Only the last line is not reported any more, first two are still considered harmfull:

Error:
Problem at line 2 character 5: Use '===' to compare with 'undefined'.
if(a==undefined){}
Problem at line 3 character 5: Use '===' to compare with 'null'.
if(a==null){}
Implied global: a 2,3,4, b 4


Why do I care ?

From habit (maybe very wrong one)
I use construction:

function(arg1,arg2,arg3)
if(arg3 == null)
or
if(arg3 != null)

bacause IMHO this is valid:

null==null
true
undefined==null
true
null!=null
false
undefined!=null
false

To simplyfy ifing for both undefined and null values
Otherwise I would have to write:

if(arg3 === null || typeof arg3 !== "undefined")
or
if(arg3 === null || arg3 === undefined)

with second option I use known trick,
"elimination of evil global undefined"
BTW: also used by jQuery:
(function( window, undefined ) {

})(window);

Trying this

/*jslint eqeqeq: false*/
(function(undefined) {
if(a==undefined){}
}());

with JSLint you get:

Error:
Problem at line 2 character 11: Expected an identifier and instead saw 'undefined' (a reserved word).
(function(undefined) {
Problem at line 3 character 9: Use '===' to compare with 'undefined'.
if(a==undefined){}
Implied global: a 3

Solution ?

Can anyone tell me how to turn off JSLint ==
In the way it ignores all not only some constructions ?

Can anyone tell me how to make effective and simple if
which returns true only for "null and undefined" and false for all other values ?
Suggestion by Mr.D on his page
If you only care that a value is truthy or falsy, then use the short form. Instead of
(foo != 0)
just say
(foo)
is not and option because we are latking about specified or valid (0, false) and uspecified or invalid (null,undefined) here...

Or shell I rewrite all my ifs from if(a!=null) into strange looking:

/*jslint eqeqeq: false*/
(function(undef) {
if(a!=undef){}
}());



Thanx in advance....

Try also my favorite blogger at:
http://webreflection.blogspot.com/search?q=JSLint

Update: 2011/06/07

It seems that current version Edition 2011-07-01
http://www.jslint.com/
works fine for all 3 cases and works correctly for null and undefined as well:

1./*jslint eqeqeq: true*/
2.if(a==undefined){}
3.if(a==null){}
4. if(a==b){}

Tuesday, August 31, 2010

org.owasp.esapi.encodeForURL (shocked again)

My quick look at OWASP ESAPI-2.0-rc6 again

java.lang.String encodeForURL(java.lang.String input) throws EncodingException
Encode for use in a URL. This method performs URL encoding on the entire string.

For the docs the "URL encoding" is defined by referencing wikipedia !
http://en.wikipedia.org/wiki/Percent-encoding
Don't we have RFCs for this ?

Being curious what it really does ? Look in the code:

return java.net.URLEncoder.encode(input,
ESAPI.securityConfiguration().getCharacterEncoding());


What ? Read JavaDoc !
Translates a string into application/x-www-form-urlencoded format.
This is not ment for building URLs but for encoding form data !
There is another JavaDoc:
The URLEncoder and URLDecoder classes can also be used,
but only for HTML form encoding,
which is not the same as the encoding scheme defined in RFC2396.
And another one:
The recommended way to manage the encoding and decoding of URLs is to use URI

Reading URI docs you will learn about all deviations Java has from RFC2396.
javase/6/docs/api/java/net/URI.html

The OWASP JavaScript version of "the same" is even "better"
(I bet a beer, not producing the same results as Java code):


encodeForURL: function(sInput) {
return !sInput ? null : escape(sInput);
}


Reading MDC docs:
escape and unescape Functions
The escape and unescape functions do not work properly for non-ASCII characters
and have been deprecated. In JavaScript 1.5

and later, use encodeURI, decodeURI, encodeURIComponent, and decodeURIComponent.


Bad naming or ignorance ?

There is just small chance that authors realy ment to code
"HTML form encoding" and not to solve URI building and encoding,
and that the method has just a bad name. I would suggest Encoder.encodeForHtmlForm
instead of misleading encodeForURL with even more confisung wiki link !



In the case OWASP really ment to solve
encoding for URI or http scheme URLs, there should be totaly
another code behind !!!!


If you really plan to encode URI components there is API needed to
encode path, path-segment, query, fragment with separate rules defined by
RFC (and I vote for the "new rfc3986" instead of buggy java implementation of old "RFC2396").

If you code or find rfc3986 compliant java uri implementation,
let me know,
until then I will not
replace my code for UNRELIABLE OWASP REFERENCE IMPLEMENTATION.


Strong suggestion again: search for "Jena IRI".

Friday, August 20, 2010

.href or setAttribute("href") in MSIE "sometimes" overrides the link text

Call to .href or setAttribute("href") in MSIE "sometimes" overrides the link text

If the text link contains ..@.. (hard to say exactly).
However MSIE DOES NOT override
the text if A tag contains other elements.

jQuery.attr does not solve the problem (or I use wrong API ?)

Proposed detection:

var supports = new (function() {
var a = document.createElement("a");
t = a.innerHTML = "a@a";
a.href = "http://msie";
this.aTextHrefOverride = (a.innerHTML != t);
});


Proposed solution:

var setAttributeHref = !supports.aTextHrefOverride ? function(that, value) { that.setAttribute("href", value); } : function(that, value) {
var t1 = getTextContent(that), t2;
that.setAttribute("href", value);
if ((t2 = getTextContent(that)) != t1) {
// asrt(has only text child no element childs);
setTextContent(that, t1);
}
}

getTextContent, setTextContent are XB helpers over .text and .textContent
properties.


TODo: lets check the dom-deviations

Monday, August 2, 2010

"Interesting project" - owasp-esapi-js

Just to keep in touch with some security topics, I have downloaded latest code of OWASP ESAPi for Java
and JavaScript today.
I'm bloging about the JavaScript part today.

This is the quote from original site (if you do not know OWASp and/or ESAPI:
http://code.google.com/p/owasp-esapi-js/
The purpose of the ESAPI is to provide a simple interface that provides all the security functions a developer is likely to need in a clear, consistent, and easy to use way. The ESAPI architecture is very simple, just a collection of classes that encapsulate the key security operations most applications need.

Just the first look is shocking:

the esapi.js
does not use closure to hide it's internal functions,
pulutes global space,
modifies Array and String prototypes,
$,
uses bad uncompressable techniques,
unefficient constructs,
and ...
is "unsecure" and "destructive".


Unsecure can be shown here:

if (!Array.prototype.each) {
Array.prototype.each = function(fIterator) {
if (typeof fIterator != 'function') {
throw 'Illegal Argument for Array.each';
}

for (var i = 0; i < this.length; i ++) {
fIterator(this[i]);
}
};
}


What is the purpose of the if here ? If already defined, use the defined function
override otherwise. Defined by who ?

Browser ? As far as I hnow, none JavaScript version supports Array.prototype.each
(there si forEach in JS 1.6)
Other library ? How trusted ?
Or injected poisoned version of XSSed script ?

This method and others constructed in the same style are then used in subsequent
"security APIs".

Destructive means:

var $type = function( oVar, oType ) {
if ( !oVar instanceof oType ) {
throw new SyntaxError();
}
};

In global scope of course.

Those two are ultimately candidates for criticism, specially in "security related library".

The rest of the code which is not big (3000 lines including spaces and comments),
shows quite inconsistent coding style,
and lack of professional Java Script knowledge.

So much for now, I will have deeper look later,
but I'm not impressed.

"Shame of OWASP label"

Thursday, July 22, 2010

Trinidad JavaScript

Trinidad JavaScript

In short ?
Bad,obsolete,space consuming,sub-optimal .... practices,
in the order discovered.....
judged by my average JS knowledge....

  1. everything in global scope
  2. using new Array()
  3. var; var; var;
  4. Browser detection (sniffing)

  5. Useless chars eg: typeof (elem) == "string"
  6. ... this makes no sence to continue.....
Shocking:
TrUIUtils.createCallback = function(thisObj, func) {
 // create a function that sets up "this" and delegates all of the parameters
 // to the passed in function
 var proxyFunction = new Function(var f=arguments.callee; return f._func.apply(f._owner, arguments);");

 // attach ourselves as "this" to the created function
 proxyFunction._owner = thisObj;

 // attach function to delegate to
 proxyFunction._func = func;

 return proxyFunction;
}
TrUIUtils._cssToJs = function(prop) {
 var jsProp = '';
 var upperNext = false;
 for (var c = 0; c < prop.length; c++) {
  if (prop.charAt(c) == '-') {
   upperNext = true;
   continue;
  }

  if (upperNext) {
   jsProp += prop.charAt(c).toUpperCase();
  }
  else {
   jsProp += prop.charAt(c);
  }

  upperNext = false;
 }
 return jsProp;
}
I had to stop after while... ... since this could be book of "JavaScript antisamples". I have no idea about the libs origin, they mention IE 4 versions, however Trinidad claim support to 6+, I belive a lot of code is "ported" from some other languages with little JS knowledge or care, or comes from aged libs written in the dark and deep web history. I have to quote Mr.D: http://javascript.crockford.com/style1.html
There are no good texts on JavaScript programming. Most of the people on the web who are producing JavaScript programs learned it by copying really bad examples from bad books, bad websites, and bad tools. We have an amazingly good community of JavaScript programmers here, but still we can benefit from better practice of style.