shenandoah 0.1.3 → 0.2.0

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.
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));