shenandoah 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/.gitignore +1 -0
  2. data/ChangeLog.markdown +9 -0
  3. data/Rakefile +21 -2
  4. data/VERSION.yml +3 -2
  5. data/features/buildr.feature +29 -0
  6. data/features/example_projects/base/Rakefile +7 -0
  7. data/features/example_projects/base/lib/cells.js +105 -0
  8. data/features/example_projects/base/lib/life.js +30 -0
  9. data/features/example_projects/base/spec/cells.html +13 -0
  10. data/features/example_projects/base/spec/cells_spec.js +234 -0
  11. data/features/example_projects/base/spec/life.html +13 -0
  12. data/features/example_projects/base/spec/life_spec.js +28 -0
  13. data/features/plain-rake.feature +30 -0
  14. data/features/rails.feature +39 -0
  15. data/features/step_definitions/buildr_steps.rb +26 -0
  16. data/features/step_definitions/rails_steps.rb +38 -0
  17. data/features/step_definitions/rake_steps.rb +45 -0
  18. data/features/support/env.rb +48 -0
  19. data/lib/shenandoah/css/shenandoah.sass +138 -0
  20. data/lib/shenandoah/javascript/browser/index.js +18 -0
  21. data/lib/shenandoah/javascript/browser/multirunner-single.js +32 -0
  22. data/lib/shenandoah/javascript/browser/multirunner.js +87 -0
  23. data/lib/shenandoah/javascript/common/jquery.parsequery.js +19 -0
  24. data/lib/shenandoah/server.rb +81 -16
  25. data/lib/shenandoah/server/views/index.haml +18 -8
  26. data/lib/shenandoah/server/views/multirunner.haml +6 -0
  27. data/rails_generators/shen_spec/templates/fixture.html.erb +1 -1
  28. data/rails_generators/shenandoah/templates/application.html +1 -1
  29. data/spec/rails_generators/shen_spec_generator_spec.rb +2 -2
  30. data/spec/rails_generators/shenandoah_generator_spec.rb +3 -3
  31. data/spec/shenandoah/server_spec.rb +156 -15
  32. metadata +32 -3
  33. data/lib/shenandoah/css/screw.css +0 -90
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+
4
+ <head>
5
+ <title>life.js | JavaScript Testing Results</title>
6
+ <link rel="stylesheet" href="/shenandoah.css" type="text/css" charset="utf-8" />
7
+ <script type="text/javascript" src="/shenandoah/browser-runner.js"></script>
8
+ </head>
9
+
10
+ <body>
11
+ <!-- Put any HTML fixture elements here. -->
12
+ </body>
13
+ </html>
@@ -0,0 +1,28 @@
1
+ require_main('cells.js');
2
+ require_main('life.js');
3
+
4
+ Screw.Unit(function () {
5
+ describe('Life', function () {
6
+ var game;
7
+ before(function () {
8
+ game = new Life(new Cells([
9
+ [0, 1, 0],
10
+ [0, 1, 0],
11
+ [0, 1, 0]
12
+ ]));
13
+ });
14
+
15
+ it("steps", function () {
16
+ game.step();
17
+ expect(game.cells.get(0, 0).age).to(equal, 0);
18
+ expect(game.cells.get(0, 1).age).to(equal, 0);
19
+ expect(game.cells.get(0, 2).age).to(equal, 0);
20
+ expect(game.cells.get(1, 0).age).to(equal, 1);
21
+ expect(game.cells.get(1, 1).age).to(equal, 2);
22
+ expect(game.cells.get(1, 2).age).to(equal, 1);
23
+ expect(game.cells.get(2, 0).age).to(equal, 0);
24
+ expect(game.cells.get(2, 1).age).to(equal, 0);
25
+ expect(game.cells.get(2, 2).age).to(equal, 0);
26
+ });
27
+ });
28
+ });
@@ -0,0 +1,30 @@
1
+ Feature: Testing projects which just use rake
2
+
3
+ Scenario: Defined tasks
4
+ Given a plain-rake project
5
+ When I list the available rake tasks
6
+ Then the task list should include shen:serve
7
+ And the task list should include shen:generate[basename]
8
+ And the task list should include shen:spec[pattern]
9
+ And the task list should include shen:shell
10
+
11
+ Scenario: Running the server
12
+ Given a plain-rake project
13
+ When I execute `rake shen:serve`
14
+ Then the server should be running
15
+
16
+ Scenario: Running all specs
17
+ Given a plain-rake project
18
+ When I execute `rake shen:spec`
19
+ Then 49 specs should run
20
+
21
+ Scenario: Running one spec
22
+ Given a plain-rake project
23
+ When I execute `rake shen:spec[life_spec]`
24
+ Then 1 spec should run
25
+
26
+ Scenario: Generating a spec
27
+ Given an empty plain-rake project
28
+ When I execute `rake shen:generate[pre_view]`
29
+ Then the file "spec/pre_view_spec.js" should exist
30
+ And the file "spec/pre_view.html" should exist
@@ -0,0 +1,39 @@
1
+ Feature: Testing rails projects
2
+
3
+ Scenario: Defined tasks
4
+ Given a rails project
5
+ When I list the available rake tasks
6
+ Then the task list should include shen:serve
7
+ And the task list should not include shen:generate[basename]
8
+ And the task list should include shen:spec[pattern]
9
+ And the task list should include shen:shell
10
+
11
+ Scenario: Running the server
12
+ Given a rails project
13
+ When I execute `rake shen:serve`
14
+ Then the server should be running
15
+
16
+ Scenario: Running all specs
17
+ Given a rails project
18
+ When I execute `rake shen:spec`
19
+ Then 49 specs should run
20
+
21
+ Scenario: Running one spec
22
+ Given a rails project
23
+ When I execute `rake shen:spec[life_spec]`
24
+ Then 1 spec should run
25
+
26
+ Scenario: Integrating with a new rails project
27
+ Given an empty rails project
28
+ When I execute `script/generate shenandoah`
29
+ Then the file "lib/tasks/shenandoah.rake" should exist
30
+ And the directory "test/javascript" should exist
31
+ And the file "test/javascript/spec_helper.js" should exist
32
+ And the file "test/javascript/application.html" should exist
33
+ And the file "test/javascript/application_spec.js" should exist
34
+
35
+ Scenario: Generating a spec
36
+ Given a rails project
37
+ When I execute `script/generate shen_spec pre_view`
38
+ Then the file "test/javascript/pre_view_spec.js" should exist
39
+ And the file "test/javascript/pre_view.html" should exist
@@ -0,0 +1,26 @@
1
+ Given /a buildr project/ do
2
+ switch_to_project('buildr')
3
+
4
+ open("buildfile", 'w') do |f|
5
+ f.write <<-RUBY
6
+ $LOAD_PATH.unshift(File.join(#{root_path.inspect}, 'lib'))
7
+ require 'shenandoah/buildr'
8
+
9
+ define 'life' do
10
+ test.using :shenandoah
11
+ end
12
+ RUBY
13
+ end
14
+
15
+ mkdir_p 'src/main/javascript'
16
+ cp Dir["#{base_project}/lib/**/*"], 'src/main/javascript'
17
+
18
+ mkdir_p 'src/spec/javascript'
19
+ cp Dir["#{base_project}/spec/**/*"], 'src/spec/javascript'
20
+ end
21
+
22
+ When /^I list the available buildr tasks$/ do
23
+ @tasks = `buildr help:tasks`.scan(/\n\s*(\S+)\s*#/).collect { |m| m.first }
24
+ $?.should == 0
25
+ end
26
+
@@ -0,0 +1,38 @@
1
+
2
+ Given /an empty rails project/ do
3
+ switch_to_project('rails')
4
+ system("rails . > /dev/null")
5
+
6
+ File.open('config/initializers/shenandoh_dev.rb', 'w') do |f|
7
+ f.write <<-RUBY
8
+ require 'rails_generator'
9
+
10
+ begin
11
+ $LOAD_PATH.unshift(File.join(#{root_path.inspect}, 'lib'))
12
+
13
+ Rails::Generator::Base.prepend_sources(
14
+ Rails::Generator::PathSource.new(
15
+ :shenandoah_dev, File.join(#{root_path.inspect}, 'rails_generators')))
16
+ end
17
+ RUBY
18
+ end
19
+ end
20
+
21
+ Given /a rails project/ do
22
+ Given "an empty rails project"
23
+
24
+ File.open('lib/tasks/shenandoah.rake', 'w') do |f|
25
+ f.write <<-RUBY
26
+ begin
27
+ $LOAD_PATH.unshift(File.join(#{root_path.inspect}, 'lib'))
28
+ end
29
+
30
+ require 'shenandoah/rails/tasks'
31
+ Shenandoah::Rails::Tasks.new
32
+ RUBY
33
+ end
34
+
35
+ mkdir "test/javascript"
36
+ cp Dir["#{base_project}/lib/*"], "public/javascripts"
37
+ cp Dir["#{base_project}/spec/*"], "test/javascript"
38
+ end
@@ -0,0 +1,45 @@
1
+ require 'open-uri'
2
+
3
+ Given /^a plain-rake project$/ do
4
+ cd base_project
5
+ end
6
+
7
+ Given /^an empty plain-rake project$/ do
8
+ switch_to_project('starter')
9
+ cp "#{base_project}/Rakefile", "Rakefile"
10
+ end
11
+
12
+ When /^I list the available rake tasks$/ do
13
+ @tasks = `rake -T`.scan(/rake (\S+)/).collect { |m| m.first }
14
+ $?.should == 0
15
+ end
16
+
17
+ Then /^the task list should (not )?include (\S+)$/ do |no, task_name|
18
+ if no
19
+ @tasks.should_not include(task_name)
20
+ else
21
+ @tasks.should include(task_name)
22
+ end
23
+ end
24
+
25
+ When %r{^I execute \`([^`]+)\`$} do |command|
26
+ @pipe = IO.popen(command)
27
+ end
28
+
29
+ Then %r{^(\d+) specs? should run$} do |count|
30
+ @pipe.read.
31
+ scan(/(\d+) test\(s\)/).
32
+ collect { |matches| matches.first.to_i }.
33
+ inject(0) { |s, i| s + i }.
34
+ should == count.to_i
35
+ end
36
+
37
+ Then %r{^the server should be running$} do
38
+ sleep 10
39
+ open('http://localhost:4410/') { |f| f.read }.should_not be_nil
40
+ end
41
+
42
+ Then /^the (?:file|directory) "([^\"]*)" should exist$/ do |filename|
43
+ @pipe.read if @pipe
44
+ File.exist?(filename).should be_true
45
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec/expectations'
2
+
3
+ Before do
4
+ @original_wd = FileUtils.pwd
5
+ end
6
+
7
+ After do
8
+ FileUtils.cd @original_wd
9
+ if @pipe
10
+ Process.kill 15, @pipe.pid
11
+ @pipe.close
12
+ end
13
+ cleanup
14
+ end
15
+
16
+ class ShenandoahWorld
17
+ include FileUtils
18
+
19
+ def root_path
20
+ @root ||= File.expand_path("../../..")
21
+ end
22
+
23
+ def base_project
24
+ @base_project ||= File.expand_path("../example_projects/base", File.dirname(__FILE__))
25
+ end
26
+
27
+ def switch_to_project(name)
28
+ path = File.expand_path("../#{name}", base_project);
29
+ self.temp_projects << path
30
+ mkdir_p path
31
+ cd path
32
+ path
33
+ end
34
+
35
+ def cleanup
36
+ self.temp_projects.each { |dir| rm_rf dir }
37
+ end
38
+
39
+ protected
40
+
41
+ def temp_projects
42
+ @temp_projects ||= []
43
+ end
44
+ end
45
+
46
+ World do
47
+ ShenandoahWorld.new
48
+ end
@@ -0,0 +1,138 @@
1
+ @import compass/reset
2
+
3
+ !running = #CC6600
4
+ !passed = #5A753D
5
+ !failed = #993300
6
+ !border_color = #6E6E6E
7
+ !background_color = #EDEBD5
8
+
9
+ body
10
+ padding: 0.5em
11
+ font-family: Helvetica, sans-serif
12
+ background= !background_color
13
+
14
+ li
15
+ list-style-type: none
16
+
17
+ .focused
18
+ background-color: #F4F2E4
19
+ *
20
+ opacity: 1.0
21
+
22
+ h3.status
23
+ font-style: italic
24
+ padding-bottom: 1em
25
+
26
+ h1, h2, p
27
+ opacity: 0.4
28
+
29
+ .describes
30
+ padding-left: 0
31
+
32
+ h1
33
+ font-size: 1.1em
34
+ color: #877C21
35
+ line-height: 1.8em
36
+ margin: 0pt 0pt 0.6em
37
+ border-bottom: 1px solid transparent
38
+ font-weight: bold
39
+
40
+ &:hover
41
+ cursor: pointer
42
+ color: #000
43
+ background-color: #F4F2E4
44
+ border-bottom: 1px solid #9A8E51
45
+
46
+ .describe
47
+ margin-left: 0.6em
48
+ padding-left: 0.6em
49
+ margin-bottom: 2px
50
+ margin-right: 2px
51
+ border= 1px "dotted" !border_color
52
+
53
+ .its .it
54
+ list-style-type: lower-roman
55
+ list-style-position: outside
56
+ margin-left: 2.0em
57
+
58
+ h2
59
+ font-weight: normal
60
+ font-style: normal
61
+ padding-left: 0.5em
62
+ font-size: 1.0em
63
+ color: #877C21
64
+ line-height: 1.8em
65
+ margin: 0 0 0.5em
66
+ border-bottom: 1px solid transparent
67
+
68
+ &.enqueued h2
69
+ background-color= !running
70
+ color: white !important
71
+
72
+ &.passed h2
73
+ background-color= !passed
74
+ color: white !important
75
+
76
+ &.failed
77
+ h2
78
+ background-color= !failed
79
+ color: white !important
80
+
81
+ p
82
+ margin-left: 1em
83
+ color= !failed
84
+
85
+ h2:hover
86
+ cursor: pointer
87
+ color: #000 !important
88
+ border-bottom: 1px solid #9A8E51
89
+
90
+ // Index styles
91
+
92
+ body#index
93
+ padding: 3em
94
+ ul li
95
+ margin-left: 1.2em
96
+ list-style-type: disc
97
+ line-height: 1.2em
98
+ h2
99
+ font-size: 1.2em
100
+ margin: 0.5em 0
101
+ #controls
102
+ margin-top: 1em
103
+ #select-all
104
+ margin-left: 1.2em
105
+
106
+ // Multirunner styles
107
+
108
+ #frames
109
+ clear: both
110
+
111
+ #frames iframe
112
+ width: 94%
113
+ height: 90%
114
+ display: none
115
+ border= 2px "solid" !border_color
116
+ margin: 1em 2%
117
+ clear: both
118
+ &.active
119
+ display: block
120
+
121
+ #specs li
122
+ display: block
123
+ padding: 4px
124
+ margin: 2px
125
+ background-color= !background_color - #333
126
+ float: left
127
+ border= 2px "solid" !background_color
128
+ cursor: pointer
129
+ &.active
130
+ border-color= !border_color
131
+ &.passed
132
+ background-color= !passed
133
+ color: #ddd
134
+ &.failed
135
+ background-color= !failed
136
+ color: #ddd
137
+ span.name
138
+ color: #fff
@@ -0,0 +1,18 @@
1
+ (function ($) {
2
+ $(document).ready(function () {
3
+ var checkboxes_selector = "form input";
4
+
5
+ $('#select-all input').click(function () {
6
+ if ($(this).is(':checked')) {
7
+ $(checkboxes_selector).attr('checked', true);
8
+ } else {
9
+ $(checkboxes_selector).attr('checked', false);
10
+ }
11
+ });
12
+
13
+ $(checkboxes_selector).click(function () {
14
+ $('#select-all input').attr('checked',
15
+ $(checkboxes_selector).filter(':checked').size() == $(checkboxes_selector).size());
16
+ });
17
+ });
18
+ }(jQuery));
@@ -0,0 +1,32 @@
1
+ if (!window.shenandoah) { shenandoah = { }; }
2
+
3
+ (function ($) {
4
+ shenandoah.MultirunnerFrame = function () {
5
+ // Finds the IFRAME which contains this window in the parent DOM
6
+ var containingFrame = $.grep(window.parent.jQuery('iframe'), function (iframe, idx) {
7
+ return iframe.contentWindow === window;
8
+ })[0];
9
+
10
+ function parentTrigger(name, data) {
11
+ if (containingFrame) {
12
+ window.parent.jQuery(containingFrame).trigger(name, data);
13
+ }
14
+ }
15
+
16
+ this.register = function () {
17
+ $(Screw).bind('after', function () {
18
+ parentTrigger('complete', {
19
+ passed_count: $('.passed').length,
20
+ failed_count: $('.failed').length,
21
+ total_count: $('.passed').length + $('.failed').length
22
+ });
23
+ });
24
+ };
25
+ };
26
+
27
+
28
+ $(document).ready(function () {
29
+ new shenandoah.MultirunnerFrame().register();
30
+ });
31
+
32
+ }(jQuery));