holygrail 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/LICENSE +19 -0
- data/Manifest +12 -0
- data/README.md +90 -0
- data/Rakefile +39 -0
- data/docs.watchr +25 -0
- data/holygrail.gemspec +15 -0
- data/lib/holygrail.rb +50 -0
- data/rails/init.rb +6 -0
- data/specs.watchr +36 -0
- data/test/holygrail_test.rb +56 -0
- data/test/test_helper.rb +8 -0
- metadata +85 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright © 2009 Martin Aumont (mynyml)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/Manifest
ADDED
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
HolyGrail
|
2
|
+
=========
|
3
|
+
|
4
|
+
Summary
|
5
|
+
-------
|
6
|
+
|
7
|
+
The Holy Grail of testing for front-end development; execute browser-less,
|
8
|
+
console-based, javascript + DOM code right from within your Rails test suite.
|
9
|
+
|
10
|
+
HolyGrail is a [Harmony][20] plugin for Ruby on Rails.
|
11
|
+
|
12
|
+
Examples
|
13
|
+
--------
|
14
|
+
|
15
|
+
Use the `js` method in your functional tests to execute javascript within the
|
16
|
+
context of a view (the last response body). `js` returns the value of the last
|
17
|
+
javascript statement, cast to an equivalent ruby object.
|
18
|
+
|
19
|
+
class PeopleControllerTest < ActionController::TestCase
|
20
|
+
|
21
|
+
test "executes simple js" do
|
22
|
+
assert_equal 2, js('1+1')
|
23
|
+
end
|
24
|
+
|
25
|
+
test "accesses the DOM" do
|
26
|
+
get :foo
|
27
|
+
assert_equal 'Foo', js("document.title")
|
28
|
+
assert_equal 2, js("document.getElementsByTagName('div').length")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Install
|
33
|
+
-------
|
34
|
+
|
35
|
+
Install the gem
|
36
|
+
|
37
|
+
# Note: there's a gem dependency bug in rubygems currently, so we'll have
|
38
|
+
# to install some dependencies manually. This will be fixed soon.
|
39
|
+
gem install stackdeck
|
40
|
+
gem install johnson -v "2.0.0.pre0" #exact version matters
|
41
|
+
|
42
|
+
gem install holygrail
|
43
|
+
|
44
|
+
and add it to your environment
|
45
|
+
|
46
|
+
config.gem "holygrail"
|
47
|
+
|
48
|
+
Acknowledgement
|
49
|
+
---------------
|
50
|
+
|
51
|
+
HolyGrail is based on [Harmony][20], which in turn is a thin DSL wrapper around
|
52
|
+
three **amazing** libs, [Johnson][1], [env.js][30] and [Envjs][2] . The authors
|
53
|
+
of those libs have been doing a huge amount of great work for quite a while, so
|
54
|
+
please go recommend them on WorkingWithRails right now and/or follow them on
|
55
|
+
github:
|
56
|
+
|
57
|
+
[jbarnette][3], [tenderlove][4], [smparkes][5], [wycats][6], [matthewd][7], [thatcher][8], [jeresig][9]
|
58
|
+
|
59
|
+
Special thanks go to [smparkes][10] for his patient help, and for providing the
|
60
|
+
last puzzle pieces that made [everything][12] [work][11] [together][13].
|
61
|
+
|
62
|
+
TODO
|
63
|
+
----
|
64
|
+
* Support integration tests
|
65
|
+
* Support Rails3
|
66
|
+
|
67
|
+
Links
|
68
|
+
-----
|
69
|
+
* code: <http://github.com/mynyml/holygrail>
|
70
|
+
* docs: <http://yardoc.org/docs/mynyml-holygrail>
|
71
|
+
* wiki: <http://wiki.github.com/mynyml/holygrail>
|
72
|
+
* bugs: <http://github.com/mynyml/holygrail/issues>
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
[1]: http://github.com/jbarnette/johnson/
|
77
|
+
[2]: http://env-js.appspot.com/
|
78
|
+
[3]: http://www.workingwithrails.com/person/10668-john-barnette
|
79
|
+
[4]: http://github.com/tenderlove/
|
80
|
+
[5]: http://www.workingwithrails.com/person/11739-steven-parkes
|
81
|
+
[6]: http://www.workingwithrails.com/person/1805-yehuda-katz
|
82
|
+
[7]: http://www.workingwithrails.com/person/6221-matthew-draper
|
83
|
+
[8]: http://github.com/thatcher/
|
84
|
+
[9]: http://ejohn.org/
|
85
|
+
[10]: http://github.com/smparkes/
|
86
|
+
[11]: http://github.com/smparkes/env-js/commit/49abe259813a505b0761e6d31dde671344b5bc87#L0R279
|
87
|
+
[12]: http://groups.google.com/group/envjs/msg/4ac719f7db7912f5
|
88
|
+
[13]: http://gemcutter.org/gems/envjs
|
89
|
+
[20]: http://github.com/mynyml/harmony
|
90
|
+
[30]: http://github.com/thatcher/env-js
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
def gem_opt
|
2
|
+
defined?(Gem) ? "-rubygems" : ""
|
3
|
+
end
|
4
|
+
|
5
|
+
# --------------------------------------------------
|
6
|
+
# Tests
|
7
|
+
# --------------------------------------------------
|
8
|
+
task(:default => "test:all")
|
9
|
+
|
10
|
+
namespace(:test) do
|
11
|
+
|
12
|
+
desc "Run all tests"
|
13
|
+
task(:all) do
|
14
|
+
exit system("ruby #{gem_opt} -I.:lib:test -e'%w( #{Dir['test/**/*_test.rb'].join(' ')} ).each {|p| require p }'")
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Run all tests on multiple ruby versions (requires rvm)"
|
18
|
+
task(:portability) do
|
19
|
+
versions = %w( 1.8.6 1.8.7 1.9 1.9.2 )
|
20
|
+
versions.each do |version|
|
21
|
+
system <<-BASH
|
22
|
+
bash -c 'source ~/.rvm/scripts/rvm;
|
23
|
+
rvm use #{version};
|
24
|
+
echo "--------- #{version} ----------";
|
25
|
+
rake -s test:all'
|
26
|
+
BASH
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# --------------------------------------------------
|
32
|
+
# Docs
|
33
|
+
# --------------------------------------------------
|
34
|
+
desc "Generate YARD Documentation"
|
35
|
+
task :yardoc do
|
36
|
+
require 'yard'
|
37
|
+
YARD::CLI::Yardoc.run *%w( --no-private -o doc/yard --readme README.md - LICENSE )
|
38
|
+
end
|
39
|
+
|
data/docs.watchr
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Run me with:
|
2
|
+
# $ watchr docs.watchr
|
3
|
+
|
4
|
+
require 'yard'
|
5
|
+
# --------------------------------------------------
|
6
|
+
# Rules
|
7
|
+
# --------------------------------------------------
|
8
|
+
watch( 'lib/.*\.rb' ) { yard }
|
9
|
+
watch( 'README.md' ) { yard }
|
10
|
+
|
11
|
+
# --------------------------------------------------
|
12
|
+
# Signal Handling
|
13
|
+
# --------------------------------------------------
|
14
|
+
Signal.trap('QUIT') { yard } # Ctrl-\
|
15
|
+
Signal.trap('INT' ) { abort("\n") } # Ctrl-C
|
16
|
+
|
17
|
+
# --------------------------------------------------
|
18
|
+
# Helpers
|
19
|
+
# --------------------------------------------------
|
20
|
+
def yard
|
21
|
+
print "Updating yardocs... "; STDOUT.flush
|
22
|
+
YARD::CLI::Yardoc.run *%w( --no-private -o doc/yard --readme README.md - LICENSE )
|
23
|
+
print "done\n"
|
24
|
+
end
|
25
|
+
|
data/holygrail.gemspec
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "holygrail"
|
3
|
+
s.version = "0.5"
|
4
|
+
s.summary = "Harmony plugin for Ruby on Rails tests"
|
5
|
+
s.description = "The Holy Grail of testing for front-end development; execute browser-less, console-based, javascript + DOM code right from within your Rails test suite."
|
6
|
+
s.author = "mynyml"
|
7
|
+
s.email = "mynyml@gmail.com"
|
8
|
+
s.homepage = "http://github.com/mynyml/holygrail"
|
9
|
+
s.rubyforge_project = "holygrail"
|
10
|
+
s.require_path = "lib"
|
11
|
+
s.files = File.read("Manifest").strip.split("\n")
|
12
|
+
|
13
|
+
s.add_dependency 'harmony'
|
14
|
+
s.add_development_dependency 'action_controller'
|
15
|
+
end
|
data/lib/holygrail.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'harmony'
|
2
|
+
|
3
|
+
module ActionController
|
4
|
+
module Assertions
|
5
|
+
module HolyGrail
|
6
|
+
|
7
|
+
# Clear harmony page on every request.
|
8
|
+
# Prevents changes to context from bleeding into the next one.
|
9
|
+
#
|
10
|
+
# @example
|
11
|
+
#
|
12
|
+
# get :index
|
13
|
+
# js("foo = 'bar'")
|
14
|
+
# js('foo') #=> "bar"
|
15
|
+
#
|
16
|
+
# get :index
|
17
|
+
# js('foo') #=> "Error: foo is not defined"
|
18
|
+
#
|
19
|
+
# @private
|
20
|
+
def process(*args) #:nodoc:
|
21
|
+
@__page = nil
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
# Execute javascript within the context of a view.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
#
|
29
|
+
# class PeopleControllerTest < ActionController::TestCase
|
30
|
+
# get :index
|
31
|
+
# assert_equal 'People: index', js('document.title')
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# @param [String]
|
35
|
+
# code javascript code to evaluate
|
36
|
+
#
|
37
|
+
# @return [Object]
|
38
|
+
# value of last javascript statement, cast to an equivalent ruby object
|
39
|
+
#
|
40
|
+
# @raise [Johnson::Error]
|
41
|
+
# javascript code exception
|
42
|
+
#
|
43
|
+
def js(code)
|
44
|
+
@__page ||= Harmony::Page.new(@response.body.to_s)
|
45
|
+
@__page.execute_js(code)
|
46
|
+
end
|
47
|
+
alias :execute_javascript :js
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/rails/init.rb
ADDED
data/specs.watchr
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Run me with:
|
2
|
+
# $ watchr specs.watchr
|
3
|
+
|
4
|
+
# --------------------------------------------------
|
5
|
+
# Rules
|
6
|
+
# --------------------------------------------------
|
7
|
+
watch( '^test.*/.*_test\.rb' ) {|m| ruby m[0] }
|
8
|
+
watch( '^lib/(.*)\.rb' ) {|m| ruby "test/#{m[1]}_test.rb" }
|
9
|
+
watch( '^rails/init\.rb' ) { ruby tests }
|
10
|
+
watch( '^test/test_helper\.rb' ) { ruby tests }
|
11
|
+
|
12
|
+
# --------------------------------------------------
|
13
|
+
# Signal Handling
|
14
|
+
# --------------------------------------------------
|
15
|
+
Signal.trap('QUIT') { ruby tests } # Ctrl-\
|
16
|
+
Signal.trap('INT' ) { abort("\n") } # Ctrl-C
|
17
|
+
|
18
|
+
# --------------------------------------------------
|
19
|
+
# Helpers
|
20
|
+
# --------------------------------------------------
|
21
|
+
def ruby(*paths)
|
22
|
+
run "ruby #{gem_opt} -I.:lib:test -e'%w( #{paths.flatten.join(' ')} ).each {|p| require p }'"
|
23
|
+
end
|
24
|
+
|
25
|
+
def tests
|
26
|
+
Dir['test/**/*_test.rb']
|
27
|
+
end
|
28
|
+
|
29
|
+
def run( cmd )
|
30
|
+
puts cmd
|
31
|
+
system cmd
|
32
|
+
end
|
33
|
+
|
34
|
+
def gem_opt
|
35
|
+
defined?(Gem) ? "-rubygems" : ""
|
36
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
|
3
|
+
ActionController::Routing::Routes.draw do |map|
|
4
|
+
map.root :controller => 'holy_grails', :action => 'foo'
|
5
|
+
end
|
6
|
+
|
7
|
+
class HolyGrailsController < ActionController::Base
|
8
|
+
def foo
|
9
|
+
render :text => <<-HTML
|
10
|
+
<html>
|
11
|
+
<head>
|
12
|
+
<title>Foo</title>
|
13
|
+
</head>
|
14
|
+
<body>
|
15
|
+
<div></div>
|
16
|
+
<div></div>
|
17
|
+
</body>
|
18
|
+
</html>
|
19
|
+
HTML
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class HolyGrailsControllerTest < ActionController::TestCase
|
24
|
+
test "api" do
|
25
|
+
assert_respond_to self, :execute_javascript
|
26
|
+
assert_respond_to self, :js
|
27
|
+
end
|
28
|
+
|
29
|
+
test "parses simple js" do
|
30
|
+
assert_equal 2, js('1+1')
|
31
|
+
end
|
32
|
+
|
33
|
+
test "every test is a different context" do
|
34
|
+
js("foo = 'bar'")
|
35
|
+
assert_equal 'bar', js('foo')
|
36
|
+
end
|
37
|
+
test "every test is a different context 2" do
|
38
|
+
assert_raises(Johnson::Error) { js('foo') }
|
39
|
+
end
|
40
|
+
|
41
|
+
test "response context doesn't bleed into next response" do
|
42
|
+
get :foo
|
43
|
+
js("foo = 'bar'")
|
44
|
+
assert_equal 'bar', js('foo')
|
45
|
+
|
46
|
+
get :foo
|
47
|
+
assert_raises(Johnson::Error) { js('foo') }
|
48
|
+
end
|
49
|
+
|
50
|
+
test "DOM" do
|
51
|
+
get :foo
|
52
|
+
assert_equal 'Foo', js("document.title")
|
53
|
+
assert_equal 2, js("document.getElementsByTagName('div').length")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: holygrail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.5"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mynyml
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-02-11 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: harmony
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: action_controller
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: The Holy Grail of testing for front-end development; execute browser-less, console-based, javascript + DOM code right from within your Rails test suite.
|
36
|
+
email: mynyml@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- LICENSE
|
46
|
+
- Manifest
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- docs.watchr
|
50
|
+
- holygrail.gemspec
|
51
|
+
- lib/holygrail.rb
|
52
|
+
- rails/init.rb
|
53
|
+
- specs.watchr
|
54
|
+
- test/holygrail_test.rb
|
55
|
+
- test/test_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/mynyml/holygrail
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project: holygrail
|
80
|
+
rubygems_version: 1.3.5
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Harmony plugin for Ruby on Rails tests
|
84
|
+
test_files: []
|
85
|
+
|