Update: The Acid3 test is now final, I’ve updated the blog post to reflect this.

The new news on the block is that the upcoming Acid 3 test is in the oven, starting to get baked. Traditionally, the Acid test has served as a way to get browser vendors in line by testing them on really-annoying edge cases. This can, sometimes, get people tied up in knots but it actually serves as a devious way of getting people to meet a large part of a spec.

For example, in order for a browser to have some weird padding/margin test case solved – in CSS – they must also have a working box model. So while an Acid test may not, explicitly, test for a working box model, it will be done implicitly (by testing edge cases that result from it).

With that in mind, it’s time to take a look at Acid 3 which primarily focuses on technology that I find to be interesting: ECMAScript and the DOM. Let’s dig in and see what exactly is being tested – specifically, relating to ECMAScript.

Array Elisions – Making sure that stuff like [,,] has a length of 2 and [0,,1] has a length of 3.

– Making sure that stuff like has a length of 2 and has a length of 3. Array Methods – Doing an unshift with multiple arguments .unshift(0, 1, 2) , joining with an undefined argument .join(undefined) .

– Doing an unshift with multiple arguments , joining with an undefined argument . Number Conversion – Banging against .toFixed() , .toExponential() , and .toPrecision() – especially with decimals and negative numbers.

– Banging against , , and – especially with decimals and negative numbers. String Operations – Negative indicies in substr .substr(-7, 3) , character access by index "foo"[1] (part of the ECMAScript 4 spec).

– Negative indicies in substr , character access by index (part of the ECMAScript 4 spec). Date – Making sure that certain method calls result in NaN results (like d.setMilliseconds() , with no arguments) and also enforcing +1900 year offsets.

– Making sure that certain method calls result in NaN results (like , with no arguments) and also enforcing +1900 year offsets. Unicode in Identifiers – You can’t use escaped Unicode in identifiers, for example: eval("test.i\\u002b= 1;"); (that should throw an exception).

– You can’t use escaped Unicode in identifiers, for example: (that should throw an exception). Regular Expressions – /[]/ matches an empty set, /[])]/ should throw an exception, backreferences to non-existent captures, and negative lookaheads /(?!test)(test).exec("test test") .

– matches an empty set, should throw an exception, backreferences to non-existent captures, and negative lookaheads . Enumeration – Make sure that object properties are enumerated in the correct order, make sure that you’re able to enumerate properties of certain names (toString, hasOwnProperty, etc.).

– Make sure that object properties are enumerated in the correct order, make sure that you’re able to enumerate properties of certain names (toString, hasOwnProperty, etc.). Function Constructors – The user should be able to set custom constructors on the .constructor property, .constructor should not be enumerable, and .prototype.constructor should be deletable.

– The user should be able to set custom constructors on the property, should not be enumerable, and should be deletable. Function Expressions – (function test(){ ... })(); You should be able to call the function by name, within the function itself, you can’t directly overwrite the function name (only with a function-scoped variable), and ‘test’ isn’t leaked into the parent scope.

– You should be able to call the function by name, within the function itself, you can’t directly overwrite the function name (only with a function-scoped variable), and ‘test’ isn’t leaked into the parent scope. Exception Scope – Variables within the catch(){} should interact with the catch arguments primarily, followed by variables in an outer scope.

– Variables within the should interact with the catch arguments primarily, followed by variables in an outer scope. Assignment Expressions – s = a.length = "123"; – a.length has a return value of 123 (the number) which is assigned to ‘s’, rather than the correct result of the string “123”.

– – a.length has a return value of 123 (the number) which is assigned to ‘s’, rather than the correct result of the string “123”. Encoding – encodeURI() and encodeURIComponent() must gracefully handle null bytes.

All-in-all it’s a comprehensive smattering of weird ECMAScript edge cases – you’re bound to find at least one that fails in your favorite browser-of-choice. I’m sure we’ll see many more test cases coming in, in the upcoming days in weeks.

I’m looking forward to seeing the final results – and the competitive heat that’s been applied to CSS-spec implementors being applied to ECMAScript implementors.

For kicks, here’s the current results in a bunch of major browsers (including the correct reference rendering).

These are the preliminary results of the UNCOMPLETED Acid 3 test in UNCOMPLETED versions of major browsers – take with a grain of salt. Go here to view the final version of this test.

Reference Rendering:



Firefox 2:



Firefox 3b2:



Safari 3:



WebKit Nightly:



Opera 9.5b1:



Internet Explorer 7: (thanks chunghe!)

