Now we upgrade the code to pass the test (and, as usual, throw in a
couple more tweaks). Add this to public/stylesheets/application.css
:
.wiki_green { background-color: PaleGreen; } .wiki_red { background-color: Pink; }
We translate green
and red
into legible background colors. Bright
colors would irritate programmers trying to capture a bug.
Next, upgrade the @x.strong
command to pass in the correct wiki_
style class:
def format_tuple(hash, ypath) key = hash.keys.first.value ypath += ':' + key color = get_node_string(decode(ypath + ':color')) color = 'wiki_' + color unless color.blank? @x.strong :class => color, :id => 'title_' + ypath do ...
That turns nodes like test_WikiTestPage pale green, and it identifies the
<STRONG>
tag, so the next Ajax
event can access it.
Now upgrade the find_faults
action, and put everything together:
def find_faults yar = YarWiki.new(params[:page_name]) y = YAML.parse_file(yar.yaml_path) ypath = params[:ypath] color_ypath = ypath + '//color' color = y.select(color_ypath) render :update do |rjs| if color.size > 0 new_color = if params[:transcript] =~ /class=.fault/ then 'red' else 'green' end if color.first.value != new_color color.first.value = new_color File.open(yar.yaml_path, 'w'){|f| f.write(y.emit) } title_node = 'title_node' + ypath.gsub('//', ':') rjs[title_node].className = 'wiki_'+new_color color_node = 'node' + color_ypath.gsub('//', ':') rjs[color_node].className = new_color end end end end
This code reads the YAML, finds the relevant color node, changes its color (if needed), and sends an RJS command back to the web page to change its displayed color.
(This code would have used XPath.first()
, if I didn't hit a bug importing
its module, and some browsers [you might guess which] don't return good
XML from innerHTML
. As this project
matures, it could learn to read the transcript correctly, then do smart
things with each line.)
Now run the test. If it still doesn't work, your version of prototype.js
is obsolete, and has these two
blocks out of order:
try { (this.options['on' + state] || Prototype.emptyFunction)(transport, json); Ajax.Responders.dispatch('on' + state, this, transport, json); } catch (e) { this.dispatchException(e); } if (state == 'Complete') { if ((this.getHeader('Content-type') || '').strip(). match(/^(text|application)/(x-)?(java|ecma)script(;.*)?$/i)) this.evalResponse(); // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; }
The Ajax.Responders
...onComplete
should fire
after the completing event evaluates its response.
Get a newer version, or swap the position of those two blocks:
if (state == 'Complete') { if ((this.getHeader('Content-type') || '').strip(). match(/^(text|application)/(x-)?(java|ecma)script(;.*)?$/i)) this.evalResponse(); // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; } try { (this.options['on' + state] || Prototype.emptyFunction)(transport, json); Ajax.Responders.dispatch('on' + state, this, transport, json); } catch (e) { this.dispatchException(e); }
Run the TestWiki and click on the test link.
Figure 12. The outer Wiki's test node remained green because the inner Wiki's test node turned pink.
That concludes the "Architectural Spike" for this project; the rest of the work will be nothing but cleanup and productization, using the systems we created.
The current Wiki is a few tiny tweaks away from this prototypical usability:
Write a skeletal TestProject.yaml
file, with a text
editor
Put a target page into a page node
Hit the Wiki
Click test and look at the resulting page
Extract its id
s with a DOM
Inspector
Double-click a script node and enter assertions
<F8> to save, and click on the test button to re-run the test
Our humble features allow the primordial Test-Driven Development cycle to operate, mostly within the surface of one web page.
3.12.36.30