8

I'm creating a text editor and I've just finished writing the highlighting algorithms to have each of the syntax appear in a different color, and render in the right position using the proper parse trees.

I was wondering if anyone could provide me with, or the location of a test or series of test cases to make sure nothing will break. The test case(s) should cover all of JavaScript syntax as it is used on the web including edge cases (i.e., including syntax like throw although it is rarely used), DOM creation and manipulation etc.

I have added the following static test case. It should cover all the syntax.

There are a few things to note: since the code is being parse recursively on a grammar level, only basic cases are required. For example, to the editor:

a[1]; and a[1][2][3][4][5]; would be the same syntax. Since the second line, is just recursively more subs then the the first line.

The test case I have created has been moved to an answer below.

GAgnew
  • 3,847
  • 3
  • 26
  • 28

4 Answers4

2

Interesting question. I think my initial approach, barring any other interesting suggestions here, would be to grab a bunch of JavaScript from fairly major libraries. I'm thinking jQuery, Mootools, Prototype, etc.

Then, once you've done a few major libs, do some smaller ones. I'd checkout Github. Maybe look at Underscore, HeadJS, and maybe some others at https://github.com/languages/JavaScript.

I would also take a couple minified libraries, run them through JSBeautifier. Not sure if beautified JS may have slightly altered syntax from the original.

Lastly, I would consider running some of these libraries through JSLint, and then manually go through and modify the sources to explicitly hit some of the 'rules' that JSLint has laid out.

EDIT: And by "hit", I mean make sure you cover both scenarios offered by each rule, not just the 'clean' version.

Matt
  • 41,216
  • 30
  • 109
  • 147
  • As you already said yourself below: JSLint can be quite restrictive, it even doesn't like `++` and `--`, which are entirely valid (and sound, IMHO). – Marcel Korpel May 25 '11 at 15:27
  • @Marcel Yep, that is why I suggested *explicity* hitting some of the rules it lays out there, to make sure those cases are covered. I did not mean to suggest using the tool to make sure the code was 'clean'. Edited to clarify. – Matt May 25 '11 at 15:29
  • Also nodejs apps, since those are also javascript but they aren't DOM-y – jcolebrand May 25 '11 at 15:32
  • I have already run large test's against my own code base, but maybe I will manually go through some large libraries and construct my own. – GAgnew May 25 '11 at 15:38
  • @Greg the benefit of using code from libraries other than your own is different people have different standard practices for coding and as such slight variations in code. – Matt May 25 '11 at 15:41
  • @Matt Good point, I'll make sure to use a good diversity of libraries. – GAgnew May 25 '11 at 15:50
1

One possible approach: there are various applications that will generate random pieces of code starting from a BNF grammar of a language (such as this one) and there are grammar files for javascript available.

That won't get you a static test case that you can script tests against with known expected results, necessarily, but might be a good way to test your parser against unexpected (but legal) strings and make sure it doesn't break.

Jacob Mattison
  • 50,258
  • 9
  • 107
  • 126
  • This is very interesting idea. I have not thought of using randomly generated code as a test case, and it is probably not efficient because I've covered common cases. However I may use this generator for a second aspect of the editor. Thanks. – GAgnew May 25 '11 at 15:36
1

This is so far the best test case I was able to come up with.

EDIT: Added regexp, and throw. This case is syntactically valid and should cover all cases of JS. Please message me directly if you find anything missing so that I can add it here.

a = 1;
b = { 'a' : a };
c = 'a';
d = this;
var patt1=/w3ghouls/i;
throw "Err3";
function e(a,b,c){
    d += a + b + c++;
    return d;
}
this.xy.z = function(a, b){
    var x = null;
}
var f = function(a,b){
    if(a == b || (b === a && a)){
        var f = [a,b];
        try{
            f = f.slice(0);
        }catch(e){
            console.log(e * e + '');
        }
    }else if(a){
        a = null;
        a = undefined;
        b = typeof a;
        b = true;
        b = false;
    }else{
        switch(c){
           case 'c':
             break;
           default:
             null;
             break;
        }
    }
}
for(var i =0; i <= a.length; i++){
    do{
       continue;
       null;
      }while(a != b);
}
if(a == b)
  (a) ? null : null;
/* This is a finished 
   test case */
GAgnew
  • 3,847
  • 3
  • 26
  • 28
0

A good way to start would be to run this through JSLint to see if your JavaScript is valid. It is the best checking tool I know of, but I'm not sure how well it will do to check if code broken. :(

Hope that helps.

Oliver Spryn
  • 16,871
  • 33
  • 101
  • 195
  • 2
    JSLint is a good tool, but it complains about a lot of things that are still 'valid', and should still be considered valid for the purposes of an editor. – Matt May 25 '11 at 15:22
  • The javaScript is already proven valid, I only worry that I have missed some valid cases. – GAgnew May 25 '11 at 15:32
  • @Matt Yes, I know it is hard to make JSLint happy. :) @Greg Sorry I couldn't help on this one. – Oliver Spryn May 25 '11 at 15:45