Harmony
.,ad88888888baa,
,d8P""" ""9888ba.
.a8" ,ad88888888888a
aP' ,88888888888888888a
,8" ,88888888888888888888,
,8' (888888888( )888888888,
,8' `8888888888888888888888
8) `888888888888888888888,
8 "8888888888888888888)
8 `888888888888888888)
8) "8888888888888888
(b "88888888888888'
`8, (8) 8888888888888)
"8a ,888888888888)
V8, d88888888888"
`8b, ,d8888888888P'
`V8a, ,ad8888888888P'
""88888888888888888P"
""""""""""""
Summary
Harmony provides a simple DSL to execute javascript + DOM code within ruby.
Examples
Simple Javascript Parsing
require 'harmony'
page = Harmony::Page.new(<<-HTML)
<html>
<head>
<title>Foo</title>
</head>
<body></body>
</html>
HTML
page.execute_js("1+1") #=> 2
page.execute_js("document.title") #=> "Foo"
The Page object's #execute_js
method (aliased as #x
for convenience) takes a
string of javascript code, executes it and returns the last statement's value
(just like a ruby method).
Javascript Unit Tests
One interesting use of Harmony is to test your javascript code within your ruby application's own tests (test/unit, minitest, RSpec, nanotest, etc). Which consequently means that you can now run browser-less, fully command-line based, DOM-javascript tests.
require 'test/unit'
require 'harmony'
class JavascriptTest < Test::Unit::TestCase
def setup
@page = Harmony::Page.new
@page.load('public/javascripts/foo.js')
end
def test_foo
assert_equal "world", @page.execute_js(<<-JS)
foo = new Foo;
foo.hello();
JS
end
end
DOM Handling
Don't be affraid to throw in your favorite client-side js framework, like
JQuery or Prototype. And notice that scripts linked to in <script>
tags will
automatically get pulled in.
require 'harmony'
page = Harmony::Page.new(<<-HTML)
<html>
<head>
<script src="javascripts/jquery.js" type="text/javascript"></script>
</head>
<body>
<div id="widget">ohaie</div>
</body>
</html>
HTML
page.execute_js("$('#widget').innerHTML") #=> "ohaie"
Fetching Documents
Use Harmony::Page.fetch(uri)
to create a page from a remote document.
require 'harmony'
page = Harmony::Page.fetch('http://example.com')
page.execute_js('document.title') #=> "Example Web Page"
fetch
also accepts "file://" uris.
Install
# There's a gem dependency bug in rubygems currently, so we'll have to
# install some dependencies manually. This will be fixed soon.
gem install stackdeck
gem install johnson -v "2.0.0.pre3"
gem install harmony
See Also
- holygrail: Harmony plugin for Rails tests
Acknowledgement
Harmony is a thin DSL wrapper around three amazing libs, Johnson, env.js and Envjs . The authors of those libs have been doing a huge amount of great work for quite a while, so please go recommend them on WorkingWithRails right now and/or follow them on github:
jbarnette, tenderlove, smparkes, wycats, matthewd, thatcher, jeresig
Special thanks go to smparkes for his patient help, and for providing the last puzzle pieces that made everything work together.
Links
- code: http://github.com/mynyml/harmony
- docs: http://yardoc.org/docs/mynyml-harmony
- wiki: http://wiki.github.com/mynyml/harmony
- bugs: http://github.com/mynyml/harmony/issues
YinYang ASCII art is © Normand Veilleux (nveilleuATemr1.emrDOTca)