# How to lex javascript for an assert\_js system?

**URL:** https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106
**Category:** ruby-talk
**Created:** [30 December 2006 06:25 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106 "2006-12-30T06:25:07Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![Phlip2](https://avatars.discourse-cdn.com/v4/letter/p/6a8cbe/32.png) [@Phlip2](https://rubytalk.org/u/Phlip2)
#### Post date: [30 December 2006 06:25 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/1 "2006-12-30T06:25:07Z")

</div>

Ruboids:

Someone recently posted this:

> &nbsp;&nbsp;o There's a difference between syntax checking and verification of  
> functional correctness

That is indeed why a test case that spot-checks your syntax is less useful  
than a test case that understands your needs. All unit testing  
starts at the former and aims at the latter. Here's an example of  
testing Javascript's syntax:

&nbsp;&nbsp;ondblclick = div.attributes['ondblclick']  
&nbsp;&nbsp;assert\_match /^new Ajax.Updater\("hammy\_id"/, ondblclick

It trivially asserts that a DIV (somewhere) contains an ondblclick  
handler, and that this has a Script.aculo.us Ajax.Updater in it. The  
assertion naturally cannot test that the Updater will indeed update a DIV.

To get closer to the problem, we might decide to get closer to the  
Javascript. We may need a mock-Javascript system, to evaluate that string.  
It could return the list of nuances commonly called a "Log String Test".  
Here's an example, using a slightly more verbose language:

public void testPaintGraphicsintint() {  
&nbsp;&nbsp;Mock mockGraphics = new Mock(Graphics.class);  
&nbsp;&nbsp;mockGraphics.expects(once()).method("setColor").with(eq(Color.decode("0x6491EE")));  
&nbsp;&nbsp;mockGraphics.expects(once()).method("setColor").with(same(Color.black));  
&nbsp;&nbsp;mockGraphics.expects(once()).method("drawPolygon");  
&nbsp;&nbsp;mockGraphics.expects(once()).method("drawPolygon");  
&nbsp;&nbsp;hex.paint((Graphics) mockGraphics.proxy());  
&nbsp;&nbsp;mockGraphics.verify();  
}

From the top, that mocks your graphics display driver, and retains its  
non-retained graphics commands. Then the mockGraphics object  
verifies a certain series of calls, with such-and-so parameters.

(That is a Log String Test because it's the equivalent of writing commands  
like "setColor" and "drawPolygon" into a log file, and then reading this  
to assert things.)

That test case indeed fits the ideal of moving away from testing raw  
syntax, and closer to testing semantics. Such a test, for example, could  
more easily ignore extraneous calls, and then check that two dynamic  
polygons did not overlap.

Now suppose I envision this testage:

&nbsp;&nbsp;def ondblclick(ypath)  
&nbsp;&nbsp;&nbsp;&nbsp;%(new Ajax.Updater("node",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"/ctrl/act",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ asynchronous:true,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evalScripts:true,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;method:"get",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parameters:"i\_b\_a=Parameter" })  
&nbsp;&nbsp;&nbsp;&nbsp;).gsub("\n", '').squeeze(' ')  
&nbsp;&nbsp;end

&nbsp;&nbsp;def test\_some\_js  
&nbsp;&nbsp;&nbsp;&nbsp;js = ondblclick()  
&nbsp;&nbsp;&nbsp;&nbsp;parse = assert\_js(js)  
&nbsp;&nbsp;&nbsp;&nbsp;statement = parse.first  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal 'new Ajax.Updater', statement.get\_method  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '"node"', statement.get\_param(0)  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '"/ctrl/act"', statement.get\_param(1)  
&nbsp;&nbsp;&nbsp;&nbsp;json = statement.get\_param(2)  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal true, json['evalScripts']  
&nbsp;&nbsp;end

The goal is the target JS can flex easily - can reorder its Json, or  
change fuzzy details, or add new features - without breaking the tests.  
Ideally, only changes that break project requirements will break tests.

Now suppose I want to write that assert\_js() using less than seven billion  
lines of code.

The first shortcut is to only parse code we expect. I'm aware that's  
generally against the general philosophy of parsing, but I'm trying to  
sell an application, not a JS parser. That's a private detail. I can  
accept, for example, only parsing the JS emitted by Rails's standard  
gizmos.

So before getting down to some actual questions, here's the code my  
exquisite parsing skills have thrashed out so far:

&nbsp;&nbsp;def test\_assert\_js  
&nbsp;&nbsp;&nbsp;&nbsp;source = 'new Ajax.Updater('+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'"node", '+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'"/controller/action", '+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'{ asynchronous:true, '+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'evalScripts:true, '+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'method:"get", '+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'parameters:"i\_b\_a=Parameter" })'

&nbsp;&nbsp;&nbsp;&nbsp;js = assert\_js(source)  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal 'new Ajax.Updater', js.keys.first  
&nbsp;&nbsp;&nbsp;&nbsp;parameters = js.values.first['()']  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '"node"', parameters[0]  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '"/controller/action"', parameters[1]  
&nbsp;&nbsp;&nbsp;&nbsp;json = parameters[2]['{}']  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal 'true', json['evalScripts']  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '"get"', json['method']  
&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal '"i\_b\_a=Parameter"', json['parameters']  
&nbsp;&nbsp;end

Now that's good enough for government work, and I could probably upgrade  
the interface to look more like my idealized example...

...but the implementation is a mish-mash of redundant  
Regexps and run-on methods:

&nbsp;&nbsp;Qstr = /^(["](?:(?:\\["])|(?:[^\\"]+))\*?["]),?\s\*/  
&nbsp;&nbsp;  
&nbsp;&nbsp;def assert\_json(source)  
&nbsp;&nbsp;&nbsp;&nbsp;js = {}  
&nbsp;&nbsp;&nbsp;&nbsp;identifier = /([[:alnum:]\_]+)😕

&nbsp;&nbsp;&nbsp;&nbsp;while m = source.match(identifier)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source = m.post\_match  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = source.match(/^([[:alnum:]\_]+),?\s\*/)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n = source.match(Qstr) unless n  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break unless n  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;js[m.captures[0]] = n.captures[0]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source = n.post\_match  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;return { '{}' =\> js }  
&nbsp;&nbsp;end

&nbsp;&nbsp;def assert\_js(source)  
&nbsp;&nbsp;&nbsp;&nbsp;js = {}  
&nbsp;&nbsp;&nbsp;&nbsp;qstr = /^(["](?:(?:\\["])|(?:[^\\"]+))\*?["]),?\s\*/  
&nbsp;&nbsp;&nbsp;&nbsp;json = /^(\{.\*\}),?\s\*/

&nbsp;&nbsp;&nbsp;&nbsp;if source =~ /^([^\("]+)(.\*)$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;js[$1] = assert\_js($2)  
&nbsp;&nbsp;&nbsp;&nbsp;elsif source =~ /^\((.\*)\)$/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;js['()'] = assert\_js($1)  
&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index = 0

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (m = source.match(qstr)) or  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(m = source.match(json))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break if m.size \< 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if source =~ /^\{/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;js[index] = assert\_json(m.captures[0])  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;js[index] = m.captures[0]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;source = m.post\_match  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index += 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;return js  
&nbsp;&nbsp;end

Now the questions. Is there some...

...way to severely beautify that implementation?  
...lexing library I could \_easily\_ throw in?  
...robust JS Lexer library already out there?  
...assert\_js already out there?

> **···**
>
> --  
> &nbsp;&nbsp;Phlip  
> &nbsp;&nbsp;[http://c2.com/cgi/wiki?ZeekLand](http://c2.com/cgi/wiki?ZeekLand) \<-- NOT a blog!!

---

<div class="post-metadata">

### Author: ![Luke\_Graham](https://avatars.discourse-cdn.com/v4/letter/l/e274bd/32.png) [@Luke\_Graham](https://rubytalk.org/u/Luke_Graham)
#### Post date: [2 January 2007 12:03 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/2 "2007-01-02T12:03:01Z")

</div>

Parsing with regexps makes baby Jesus cry. Javascript itself can be  
quite flexible, so it may be possible to do enough with a standard  
interpreter's run-time. Alternatively, have a look at the Mozilla  
projects repository for a real interpreter you could hack on.

> **···**
>
> On 12/30/06, Phlip \<phlip2005@nogmailspam.com\> wrote:
> 
> > Now the questions. Is there some...
> > 
> > ...way to severely beautify that implementation?  
> > ...lexing library I could \_easily\_ throw in?  
> > ...robust JS Lexer library already out there?  
> > ...assert\_js already out there?

---

<div class="post-metadata">

### Author: ![Ryan\_Platte](https://avatars.discourse-cdn.com/v4/letter/r/7ab992/32.png) [@Ryan\_Platte](https://rubytalk.org/u/Ryan_Platte)
#### Post date: [4 January 2007 16:45 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/3 "2007-01-04T16:45:10Z")

</div>

Phlip wrote:

> The goal is the target JS can flex easily - can reorder its Json, or  
> change fuzzy details, or add new features - without breaking the tests.  
> Ideally, only changes that break project requirements will break tests.
> 
> Now suppose I want to write that assert\_js() using less than seven billion  
> lines of code.
> 
> The first shortcut is to only parse code we expect. I'm aware that's  
> generally against the general philosophy of parsing, but I'm trying to  
> sell an application, not a JS parser. That's a private detail. I can  
> accept, for example, only parsing the JS emitted by Rails's standard  
> gizmos.

...

> Now the questions. Is there some...
> 
> ...way to severely beautify that implementation?

For Rails apps, by way of not testing the library('s JavaScript  
output): stub out RJS's JavaScriptGenerator ('page' object)? That was  
the first thing I thought when I heard about RJS. Surfing the code, it  
looks quite possible using Mocha if it was desirable. I haven't thought  
through all the ramifications. The OP includes testing the source page  
-- maybe also some work on the APIs to link to and submit forms to Ajax  
actions would permit those to be stubbed out as well.

Has someone already created such a beast? (Besides Google's GWT?)

> **···**
>
> --  
> Ryan Platte  
> Obtiva Training and Consulting  
> Agile, Ruby, Rails, Java Eclipse RCP  
> [http://obtiva.com/](http://obtiva.com/)

---

<div class="post-metadata">

### Author: ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)
#### Post date: [2 January 2007 12:40 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/4 "2007-01-02T12:40:10Z")

</div>

spooq wrote:

> Parsing with regexps makes baby Jesus cry. Javascript itself can be  
> quite flexible, so it may be possible to do enough with a standard  
> interpreter's run-time. Alternatively, have a look at the Mozilla  
> projects repository for a real interpreter you could hack on.

This question is for an academic paper, so it has even more ridiculous  
constraints on the amount of fun I can have. (And why hasn't the  
industry invented a Lex in a Bottle, using Regexp-like strings and a  
BNF notation?)

Can I add a parser to the Syntax library? It only does Ruby, XML, and  
YAML so far...

And, yes, JavaScript was designed to be parsed, unlike some other  
languages...

> **···**
>
> --  
> &nbsp;&nbsp;Phlip

---

<div class="post-metadata">

### Author: ![Phlip5](https://avatars.discourse-cdn.com/v4/letter/p/e99b99/32.png) [@Phlip5](https://rubytalk.org/u/Phlip5)
#### Post date: [5 January 2007 05:45 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/5 "2007-01-05T05:45:12Z")

</div>

Ryan Platte wrote:

> For Rails apps, by way of not testing the library('s JavaScript  
> output): stub out RJS's JavaScriptGenerator ('page' object)?

Ultimately we are up against a "log string test". That's where you call an  
emulator or a real deal of some type, it emits a log of its behavior, and  
you parse into this log.

You could, for example, take some server program, turn its log level up,  
call a high level function, read the log file as a string, and perform  
Regular Expressions on it to pull out target data. (/Error (.\*)/ is a good  
start!😉

Next, you might write a mock that records the calls sent to it as a sequence  
of data items, like the MockGraphics example I started this thread with.

Here's the diagnostic when an assert\_rjs fails:

Content did not include:  
$("moose\_panel").width = "50%";.  
\<"$(\"wiki\_panel\").width = \"50%\";\n$(\"mouse\_panel\").width =  
\"50%\";\nElement.update(\"mouse\_panel\", \"\<iframe height=\\\"100%\\\"  
src=\\\"/character/hammy\_squirrel\\\" id=\\\"test\_frame\\\"  
width=\\\"100%\\\"/\>\");\nElement.show(\"mouse\_panel\");"\> expected to be =~  
\</\$\("moose\_panel"\)\.width\ =\ "50%";/\>.

Note that's not even perfectly robust for a log string test. I could write  
page['moose\_panel'].width = '50%', then a few lines later write  
page['mouse\_panel'].width = '50%', and this won't catch the bug: assert\_rjs  
:page, 'moose\_panel', :width=, '50%'. It would find the first line spelled  
right, not the later line spelled wrong.

A better Log String Test would snarf each line as it tested.

Don't get me wrong - assert\_rjs is an excellent place to start; it's a  
lowest common denominator that at least matches Rails' incredible talent for  
lean and expressive statements. I would use it first before seeking a way to  
test semantics.

But that's what a mock RJS jigger would do - test that we called our RJS  
object in such-and-so ways.

> That was  
> the first thing I thought when I heard about RJS. Surfing the code, it  
> looks quite possible using Mocha if it was desirable. I haven't thought  
> through all the ramifications. The OP includes testing the source page  
> -- maybe also some work on the APIs to link to and submit forms to Ajax  
> actions would permit those to be stubbed out as well.

I want a test case that fails if two Ajax commands overlap each other and  
blot each other out. That requires emulating DOM, and I really think someone  
smarter than I could do the equivalent in 2% of the lines of code I  
envision.

> Has someone already created such a beast? (Besides Google's GWT?)

[http://www.google.com/search?domains=code.google.com&sitesearch=code.google.com&q=test](http://www.google.com/search?domains=code.google.com&sitesearch=code.google.com&q=test)

They seem aware of JUnit. 😉

> **···**
>
> --  
> &nbsp;&nbsp;Phlip  
> &nbsp;&nbsp;[http://www.greencheese.us/ZeekLand](http://www.greencheese.us/ZeekLand) \<-- NOT a blog!!!

---

<div class="post-metadata">

### Author: ![Luke\_Graham](https://avatars.discourse-cdn.com/v4/letter/l/e274bd/32.png) [@Luke\_Graham](https://rubytalk.org/u/Luke_Graham)
#### Post date: [2 January 2007 13:22 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/6 "2007-01-02T13:22:38Z")

</div>

> spooq wrote:
> 
> \> Parsing with regexps makes baby Jesus cry. Javascript itself can be  
> \> quite flexible, so it may be possible to do enough with a standard  
> \> interpreter's run-time. Alternatively, have a look at the Mozilla  
> \> projects repository for a real interpreter you could hack on.
> 
> This question is for an academic paper, so it has even more ridiculous  
> constraints on the amount of fun I can have. (And why hasn't the  
> industry invented a Lex in a Bottle, using Regexp-like strings and a  
> BNF notation?)

Not sure exactly how you want to improve on lex?

> Can I add a parser to the Syntax library? It only does Ruby, XML, and  
> YAML so far...

I don't see how that's better than grabbing the Javascript grammar off  
the web in BNF :  
[http://www.mozilla.org/js/language/es4/formal/lexer-grammar.html](http://www.mozilla.org/js/language/es4/formal/lexer-grammar.html)  
[http://www.antlr.org/grammar/1153976512034/ecmascriptA3.g](http://www.antlr.org/grammar/1153976512034/ecmascriptA3.g)  
etc.

> And, yes, JavaScript was designed to be parsed, unlike some other  
> languages...

No names need be mentioned... 😉

[Javascript::PurePerl](http://corion.net/perl-dev/Javascript-PurePerl.html) does javascript to  
xml, which seems the best/quickest solution that I've seen in my 2  
minutes of googling. Just write enough perl to put that into a file  
somewhere, and get into a nicer language ASAP 😉

> **···**
>
> On 1/2/07, Phlip \<phlip2005@gmail.com\> wrote:

---

<div class="post-metadata">

### Author: ![Luke\_Graham](https://avatars.discourse-cdn.com/v4/letter/l/e274bd/32.png) [@Luke\_Graham](https://rubytalk.org/u/Luke_Graham)
#### Post date: [2 January 2007 13:58 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/7 "2007-01-02T13:58:04Z")

</div>

[http://lxr.mozilla.org/mozilla/source/js/src/js.c](http://lxr.mozilla.org/mozilla/source/js/src/js.c)

Have a look around line 2315.

Doing some investigation into aspect-oriented programming in  
javascript may also be worthwhile.

I'll stop now 🙂

---

<div class="post-metadata">

### Author: ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)
#### Post date: [2 January 2007 15:50 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/8 "2007-01-02T15:50:09Z")

</div>

spooq wrote:

I might go with Javascript-Pure-Perl - see below. The following is just  
wrap-ups.

> [http://lxr.mozilla.org/mozilla/source/js/src/js.c](http://lxr.mozilla.org/mozilla/source/js/src/js.c)

> Have a look around line 2315.

Interesting, but I don't get It. The IT object ... exists at debug  
time, and traces all its calls?

> Not sure exactly how you want to improve on lex?

Regexp is itself also a "little language". However, to get to the  
language, we don't need to write a .regex file, compile it with special  
compilers, produce a .c file, compile this, link into it, bind to it,  
yack yack yack, and so on just to use it.

So, I envision Ruby lines like Lex.new.e(' LetterE -\> E | e'). Instead  
of externally compiling the little language, we just host it.

That is not important for the current project...

> \> Can I add a parser to the Syntax library? It only does Ruby, XML, and  
> \> YAML so far...
> 
> I don't see how that's better than grabbing the Javascript grammar off  
> the web in BNF :

In theory, I only need a dirt-simple way to spot-check the source; I'm  
not writing a JavaScript interpreter. But it could be better if it  
doesn't force me to externally compile the lexer.

> [Javascript::PurePerl](http://corion.net/perl-dev/Javascript-PurePerl.html) does javascript to  
> xml

Righteous! The project already uses XML (and unit tests with  
assert\_xpath), so that will fit right in!

Thanks! I honestly would never have thought to try Perl...

> **···**
>
> --  
> &nbsp;&nbsp;Phlip

---

<div class="post-metadata">

### Author: ![Luke\_Graham](https://avatars.discourse-cdn.com/v4/letter/l/e274bd/32.png) [@Luke\_Graham](https://rubytalk.org/u/Luke_Graham)
#### Post date: [2 January 2007 16:56 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/9 "2007-01-02T16:56:11Z")

</div>

> spooq wrote:
> 
> I might go with Javascript-Pure-Perl - see below. The following is just  
> wrap-ups.
> 
> \> [http://lxr.mozilla.org/mozilla/source/js/src/js.c](http://lxr.mozilla.org/mozilla/source/js/src/js.c)
> 
> \> Have a look around line 2315.
> 
> Interesting, but I don't get It. The IT object ... exists at debug  
> time, and traces all its calls?

It just makes a pre-defined object that you can poke at when you run  
scripts in that interpreter. The implication was that you could  
recreate the Ajax.\* methods and use them to log.

> \> Not sure exactly how you want to improve on lex?
> 
> Regexp is itself also a "little language". However, to get to the  
> language, we don't need to write a .regex file, compile it with special  
> compilers, produce a .c file, compile this, link into it, bind to it,  
> yack yack yack, and so on just to use it.

Lex generates C and lives by the rules of that coding universe. Doing  
stuff at run-time can be difficult and wierd there. Much easier to  
transform to a familiar language and compile and link with exactly the  
same tools you use for the rest of your project. Yack (yacc) is an  
entirely different project 😉

> So, I envision Ruby lines like Lex.new.e(' LetterE -\> E | e'). Instead  
> of externally compiling the little language, we just host it.

Which would be living by the rules and expectations of the Ruby  
universe. Not that theres anything wrong with that; I happen to quite  
like living there myself. It's just useful to remember there's more  
than one way of doing things.

> That is not important for the current project...

Agreed.

> \> \> Can I add a parser to the Syntax library? It only does Ruby, XML, and  
> \> \> YAML so far...  
> \>  
> \> I don't see how that's better than grabbing the Javascript grammar off  
> \> the web in BNF :
> 
> In theory, I only need a dirt-simple way to spot-check the source; I'm  
> not writing a JavaScript interpreter. But it could be better if it  
> doesn't force me to externally compile the lexer.
> 
> \> [Javascript::PurePerl](http://corion.net/perl-dev/Javascript-PurePerl.html) does javascript to  
> \> xml
> 
> Righteous! The project already uses XML (and unit tests with  
> assert\_xpath), so that will fit right in!

Not sure what assert\_path is, guess it's a function from some kind of  
test harness.

> Thanks! I honestly would never have thought to try Perl...

It's not exactly my first choice either, but any port will do in a  
storm. At least you found one acceptable suggestion in my ramblings 🙂

> **···**
>
> On 1/2/07, Phlip \<phlip2005@gmail.com\> wrote:

---

<div class="post-metadata">

### Author: ![Giles\_Bowkett](https://avatars.discourse-cdn.com/v4/letter/g/96bed5/32.png) [@Giles\_Bowkett](https://rubytalk.org/u/Giles_Bowkett)
#### Post date: [2 January 2007 17:52 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/10 "2007-01-02T17:52:53Z")

</div>

Sorry, why do you want to do this in the first place? The original  
post mentioned unit testing, if you want to unit test JavaScript,  
there are much easier ways.

> **···**
>
> --  
> Giles Bowkett  
> [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)
> 
> > **[Giles Bowkett](http://gilesbowkett.blogspot.com)**
> >
> > never not correct, except sometimes
> 
>   
> [http://gilesgoatboy.blogspot.com](http://gilesgoatboy.blogspot.com)

---

<div class="post-metadata">

### Author: ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)
#### Post date: [2 January 2007 18:10 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/11 "2007-01-02T18:10:06Z")

</div>

To spooq:

Consider this snip of C++, via Boost/Spirit:

rule\<\> LetterE = chr\_p('e') | chr\_p('E');

The bad news, of course, is all the excessive chr\_p stuff. The good  
news is that's raw C++, not even a string, and it all compiles at  
compile time.

Giles Bowkett wrote:

> Sorry, why do you want to do this in the first place? The original  
> post mentioned unit testing, if you want to unit test JavaScript,  
> there are much easier ways.

It's a secret. You'l see!...

> **···**
>
> --  
> &nbsp;&nbsp;Phlip

---

<div class="post-metadata">

### Author: ![Luke\_Graham](https://avatars.discourse-cdn.com/v4/letter/l/e274bd/32.png) [@Luke\_Graham](https://rubytalk.org/u/Luke_Graham)
#### Post date: [3 January 2007 10:24 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/12 "2007-01-03T10:24:08Z")

</div>

No doubt, I said as much in my first reply, but I elaborated on the  
parsing because that interests me.

> **···**
>
> On 1/2/07, Giles Bowkett \<gilesb@gmail.com\> wrote:
> 
> > Sorry, why do you want to do this in the first place? The original  
> > post mentioned unit testing, if you want to unit test JavaScript,  
> > there are much easier ways.

---

<div class="post-metadata">

### Author: ![Luke\_Graham](https://avatars.discourse-cdn.com/v4/letter/l/e274bd/32.png) [@Luke\_Graham](https://rubytalk.org/u/Luke_Graham)
#### Post date: [3 January 2007 10:38 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/13 "2007-01-03T10:38:18Z")

</div>

Boost is indeed cool, they push the boundaries of C++ further than  
anyone. I really like their XML parser, much better than that horrid  
Xerces port. C++ != C though, especially when lex was written. 🙂

Could you let me know how the perl script is going, either here or off-list?

> **···**
>
> On 1/2/07, Phlip \<phlip2005@gmail.com\> wrote:
> 
> > To spooq:
> > 
> > Consider this snip of C++, via Boost/Spirit:
> > 
> > rule\<\> LetterE = chr\_p('e') | chr\_p('E');
> > 
> > The bad news, of course, is all the excessive chr\_p stuff. The good  
> > news is that's raw C++, not even a string, and it all compiles at  
> > compile time.

---

<div class="post-metadata">

### Author: ![Giles\_Bowkett](https://avatars.discourse-cdn.com/v4/letter/g/96bed5/32.png) [@Giles\_Bowkett](https://rubytalk.org/u/Giles_Bowkett)
#### Post date: [4 January 2007 17:36 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/14 "2007-01-04T17:36:20Z")

</div>

No harm there, just trying to figure out if it's an exercise for the  
challenge itself or to address some obscure flaw in the existing  
techniques.

> **···**
>
> On 1/3/07, spooq \<spoooq@gmail.com\> wrote:
> 
> > On 1/2/07, Giles Bowkett \<gilesb@gmail.com\> wrote:  
> > \> Sorry, why do you want to do this in the first place? The original  
> > \> post mentioned unit testing, if you want to unit test JavaScript,  
> > \> there are much easier ways.
> > 
> > No doubt, I said as much in my first reply, but I elaborated on the  
> > parsing because that interests me.
> 
> --  
> Giles Bowkett  
> [http://www.gilesgoatboy.org](http://www.gilesgoatboy.org)
> 
> > **[Giles Bowkett](http://gilesbowkett.blogspot.com)**
> >
> > half-disavowed old blog. new blog at gilesbowkett.com
> 
> [http://gilesgoatboy.blogspot.com](http://gilesgoatboy.blogspot.com)

---

<div class="post-metadata">

### Author: ![Phlip2](https://avatars.discourse-cdn.com/v4/letter/p/6a8cbe/32.png) [@Phlip2](https://rubytalk.org/u/Phlip2)
#### Post date: [4 January 2007 00:10 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/15 "2007-01-04T00:10:15Z")

</div>

spooq wrote:

> Could you let me know how the perl script is going, either here or off-list?

Awesome - it works perfectly as a lexer, and it only produces two tiny  
bugs (so far). One is 'new Ajax.Updater' doesn't fly, and you need 'ajax =  
new Ajax.Updater'. The other is you gotta have a ; on the ends of lines.

So here's a sample test case. I am attempting to test-FIRST Javascript  
(thru Rails). That's much harder than just acceptance-testing it thru the  
existing test rigs, but the rewards will be substantial.

&nbsp;&nbsp;&nbsp;&nbsp;assert\_xpath '/form/textarea' do |textarea|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_js textarea.attributes['onkeydown'] do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_xpath 'Statement[1]' do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_xpath '//Identifier[@name = "Callee" and . = "editor\_keydown"]'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

assert\_xpath asserts that the hidden @xdoc variable can call XPath.first()  
on the given string without returning nil. So you can pack lots of goodies  
into your XPath strings, including queries and string comparisons.

The first assert\_xpath calls after something generated XHTML and then  
loaded it into @xdoc. So we can assert this XHTML contains a FORM  
containing a TEXTAREA.

assert\_js just copies the given Javascript into a temporary file, calls  
jsToXml.pl on it, and loads this into @xdoc.

The above test case trivially tests that \<TEXTAREA  
onkeydown='editor\_keydown(event);' ...\>. That looks too trivial to  
test-first, but it's the little things that add up into big bugs if you  
don't apply a little rigor to your development process!

> **···**
>
> --  
> &nbsp;&nbsp;Phlip

---

<div class="post-metadata">

### Author: ![Phlip1](https://avatars.discourse-cdn.com/v4/letter/p/df788c/32.png) [@Phlip1](https://rubytalk.org/u/Phlip1)
#### Post date: [4 January 2007 21:25 UTC](https://rubytalk.org/t/how-to-lex-javascript-for-an-assert-js-system/34106/16 "2007-01-04T21:25:06Z")

</div>

Giles Bowkett wrote:

> ... just trying to figure out if it's an exercise for the  
> challenge itself or to address some obscure flaw in the existing  
> techniques.

Yes.

> **···**
>
> --  
> &nbsp;&nbsp;Phlip
