cuukie 0.1.3 → 0.1.4
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/.travis.yml +0 -1
- data/Gemfile +1 -0
- data/README.markdown +6 -2
- data/VERSION +1 -1
- data/cuukie.gemspec +11 -6
- data/doc/backlog.txt +13 -7
- data/doc/pomodoro.txt +14 -0
- data/lib/cuukie/cucumber/formatter/code_snippets.rb +23 -0
- data/lib/cuukie/cucumber/formatter/cuukie.rb +24 -13
- data/lib/cuukie/server.rb +39 -11
- data/lib/cuukie/views/index.erb +12 -7
- data/spec/code_snippets_spec.rb +93 -0
- data/spec/commands_spec.rb +5 -5
- data/spec/cuukie_spec.rb +44 -26
- data/spec/spec_helper.rb +4 -4
- data/spec/test_project/features/{4_show_multiline_args.feature → 2_show_multiline_args.feature} +0 -0
- data/spec/test_project/features/4_exception_with_no_source.feature +16 -0
- data/spec/test_project/features/step_definitions/exception_steps.rb +26 -0
- data/spec/test_project/features/step_definitions/{example_steps.rb → main_steps.rb} +0 -0
- metadata +30 -17
- data/lib/test.rb +0 -0
- data/spec/test_project/features/2_multiple_features.feature +0 -8
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -16,7 +16,11 @@ Require Cuukie from any file in your _features/support_ directory:
|
|
16
16
|
|
17
17
|
require 'cuukie'
|
18
18
|
|
19
|
-
|
19
|
+
Add this line to any Ruby file in your _features/support_ directory:
|
20
|
+
|
21
|
+
require 'cuukie'
|
22
|
+
|
23
|
+
Start the Cuukie server from a terminal window:
|
20
24
|
|
21
25
|
cuukie_server
|
22
26
|
|
@@ -44,4 +48,4 @@ Right now, Cuukie is not any more useful than Cucumber's own HTML formatter. My
|
|
44
48
|
|
45
49
|
## License
|
46
50
|
|
47
|
-
MIT License. Copyright (c) 2011 Paolo "Nusco" Perrotta.
|
51
|
+
MIT License. Copyright (c) 2011 Paolo "Nusco" Perrotta. I ripped a few lines of code off Cucumber's HTML formatter.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/cuukie.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "cuukie"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Paolo \"Nusco\" Perrotta"]
|
12
|
-
s.date = "2011-12-
|
12
|
+
s.date = "2011-12-08"
|
13
13
|
s.description = "Shows Cucumber results on a web page as they run."
|
14
14
|
s.email = "paolo.nusco.perrotta@gmail.com"
|
15
15
|
s.executables = ["cuukie_server"]
|
@@ -30,21 +30,23 @@ Gem::Specification.new do |s|
|
|
30
30
|
"doc/backlog.txt",
|
31
31
|
"doc/pomodoro.txt",
|
32
32
|
"lib/cuukie.rb",
|
33
|
+
"lib/cuukie/cucumber/formatter/code_snippets.rb",
|
33
34
|
"lib/cuukie/cucumber/formatter/cuukie.rb",
|
34
35
|
"lib/cuukie/public/cucumber.css",
|
35
36
|
"lib/cuukie/public/cuukie.js",
|
36
37
|
"lib/cuukie/public/jquery-1.7.min.js",
|
37
38
|
"lib/cuukie/server.rb",
|
38
39
|
"lib/cuukie/views/index.erb",
|
39
|
-
"
|
40
|
+
"spec/code_snippets_spec.rb",
|
40
41
|
"spec/commands_spec.rb",
|
41
42
|
"spec/cuukie_spec.rb",
|
42
43
|
"spec/spec_helper.rb",
|
43
44
|
"spec/test_project/features/1_show_scenarios.feature",
|
44
|
-
"spec/test_project/features/
|
45
|
+
"spec/test_project/features/2_show_multiline_args.feature",
|
45
46
|
"spec/test_project/features/3_failed_background.feature",
|
46
|
-
"spec/test_project/features/
|
47
|
-
"spec/test_project/features/step_definitions/
|
47
|
+
"spec/test_project/features/4_exception_with_no_source.feature",
|
48
|
+
"spec/test_project/features/step_definitions/exception_steps.rb",
|
49
|
+
"spec/test_project/features/step_definitions/main_steps.rb",
|
48
50
|
"spec/test_project/features/support/formatters.rb"
|
49
51
|
]
|
50
52
|
s.homepage = "http://github.com/nusco/cuukie"
|
@@ -60,12 +62,14 @@ Gem::Specification.new do |s|
|
|
60
62
|
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
61
63
|
s.add_runtime_dependency(%q<rest-client>, [">= 0"])
|
62
64
|
s.add_runtime_dependency(%q<cucumber>, [">= 0"])
|
65
|
+
s.add_runtime_dependency(%q<syntax>, [">= 0"])
|
63
66
|
s.add_development_dependency(%q<rake>, [">= 0"])
|
64
67
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
65
68
|
else
|
66
69
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
67
70
|
s.add_dependency(%q<rest-client>, [">= 0"])
|
68
71
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
72
|
+
s.add_dependency(%q<syntax>, [">= 0"])
|
69
73
|
s.add_dependency(%q<rake>, [">= 0"])
|
70
74
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
71
75
|
end
|
@@ -73,6 +77,7 @@ Gem::Specification.new do |s|
|
|
73
77
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
74
78
|
s.add_dependency(%q<rest-client>, [">= 0"])
|
75
79
|
s.add_dependency(%q<cucumber>, [">= 0"])
|
80
|
+
s.add_dependency(%q<syntax>, [">= 0"])
|
76
81
|
s.add_dependency(%q<rake>, [">= 0"])
|
77
82
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
78
83
|
end
|
data/doc/backlog.txt
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
-
MMF 0.
|
2
|
-
- show exceptions
|
3
|
-
- show code snippets
|
4
|
-
MMF 0.5
|
1
|
+
MMF 0.1.5
|
5
2
|
- show incomplete suite
|
6
3
|
- show undefined Scenarios/suite
|
7
4
|
- show undefined Steps
|
8
5
|
- show incomplete wrap-up for steps/scenarios
|
9
6
|
- show incomplete running time
|
10
|
-
MMF 0.6
|
7
|
+
MMF 0.1.6
|
11
8
|
- deal with Scenario Examples
|
12
|
-
|
9
|
+
- open/close steps
|
10
|
+
MMF 1.0.0
|
13
11
|
- nice graphics
|
14
12
|
- self-updating Steps
|
15
13
|
- self-updating Scenarios
|
@@ -24,6 +22,12 @@ Then...
|
|
24
22
|
|
25
23
|
- filter by tag
|
26
24
|
|
25
|
+
- instead of showing scenarios that appear one by one,
|
26
|
+
show the entire suite ASAP, and then proceed to make
|
27
|
+
each scenario red or green (or whatever). this
|
28
|
+
gives an immediate feeling of where you are in the
|
29
|
+
suite.
|
30
|
+
|
27
31
|
- show status for each table row (table rows have an
|
28
32
|
associated status in Cucumber formatters, and the
|
29
33
|
HTML formatter seems to take advantage of this. Why?
|
@@ -41,4 +45,6 @@ Then...
|
|
41
45
|
lines for steps than other rubies. I removed the line
|
42
46
|
numbers from tests b/c of this, and b/c they made the
|
43
47
|
tests fragile. Try to put back the line numbers,
|
44
|
-
and test under rbx)
|
48
|
+
and test under rbx)
|
49
|
+
|
50
|
+
- test against rbx
|
data/doc/pomodoro.txt
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
I use this file to track my own work on the project. Each line is a pomodoro (a 25' slot).
|
2
2
|
Latest pomodoro comes first:
|
3
3
|
|
4
|
+
- show code snippets (and release 0.1.4)
|
5
|
+
- show code snippets
|
6
|
+
- show code snippets
|
7
|
+
- show code snippets
|
8
|
+
- show code snippets
|
9
|
+
- show code snippets
|
10
|
+
- code snippet reader
|
11
|
+
- code snippet reader
|
12
|
+
- code snippet reader
|
13
|
+
- code snippet reader
|
14
|
+
- code snippet reader
|
15
|
+
- "fix" Travis build (i.e. remove rbx)
|
16
|
+
- show exception backtraces
|
17
|
+
- show exception messages
|
4
18
|
- run formatter with custom server
|
5
19
|
- run formatter with custom server
|
6
20
|
- run server on custom port
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Cuukie
|
2
|
+
module CodeSnippets
|
3
|
+
NULL_SNIPPET = Hash.new
|
4
|
+
|
5
|
+
def code_snippet(file, line)
|
6
|
+
return NULL_SNIPPET unless File.exist? file
|
7
|
+
|
8
|
+
all_lines = File.open(file) {|f| f.readlines}
|
9
|
+
return NULL_SNIPPET unless line <= all_lines.size
|
10
|
+
|
11
|
+
first_line = [1, line - 2].max
|
12
|
+
|
13
|
+
{:first_line => first_line,
|
14
|
+
:marked_line => line,
|
15
|
+
:raw_lines => all_lines[(first_line - 1)..line].join }
|
16
|
+
end
|
17
|
+
|
18
|
+
def backtrace_to_snippet(backtrace)
|
19
|
+
return NULL_SNIPPET unless backtrace[0] =~ /(.*):(\d+)/
|
20
|
+
code_snippet $1, $2.to_i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,9 +1,12 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/code_snippets"
|
1
2
|
require 'rest-client'
|
2
3
|
require 'json'
|
3
4
|
|
4
5
|
module Cucumber
|
5
6
|
module Formatter
|
6
7
|
class Cuukie
|
8
|
+
include ::Cuukie::CodeSnippets
|
9
|
+
|
7
10
|
def initialize(step_mother, path_or_io, options)
|
8
11
|
@server = ENV['CUUKIE_SERVER'] || 'http://localhost:4569'
|
9
12
|
ping
|
@@ -18,25 +21,33 @@ module Cucumber
|
|
18
21
|
end
|
19
22
|
|
20
23
|
def before_feature(feature)
|
21
|
-
|
22
|
-
|
23
|
-
'description' => feature.description }
|
24
|
+
post 'before_feature', { :short_name => feature.short_name,
|
25
|
+
:description => feature.description }
|
24
26
|
end
|
25
27
|
|
26
28
|
def scenario_name(keyword, name, file_colon_line, source_indent)
|
27
|
-
post 'scenario_name', {
|
28
|
-
|
29
|
-
|
29
|
+
post 'scenario_name', { :keyword => keyword,
|
30
|
+
:name => name,
|
31
|
+
:file_colon_line => file_colon_line }
|
30
32
|
end
|
31
33
|
|
32
34
|
def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
|
33
|
-
post 'before_step_result', {
|
34
|
-
|
35
|
-
|
35
|
+
post 'before_step_result', { :keyword => keyword,
|
36
|
+
:name => step_match.format_args,
|
37
|
+
:file_colon_line => step_match.file_colon_line }
|
36
38
|
end
|
37
39
|
|
40
|
+
def exception(exception, status)
|
41
|
+
source = backtrace_to_snippet(exception.backtrace)
|
42
|
+
post 'exception', { :message => exception.message,
|
43
|
+
:backtrace => exception.backtrace.join('\n'),
|
44
|
+
:first_line => source[:first_line],
|
45
|
+
:marked_line => source[:marked_line],
|
46
|
+
:raw_lines => source[:raw_lines] }
|
47
|
+
end
|
48
|
+
|
38
49
|
def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background)
|
39
|
-
post 'after_step_result', {
|
50
|
+
post 'after_step_result', { :status => status }
|
40
51
|
end
|
41
52
|
|
42
53
|
def after_steps(*)
|
@@ -48,15 +59,15 @@ module Cucumber
|
|
48
59
|
end
|
49
60
|
|
50
61
|
def table_cell_value(value, status)
|
51
|
-
post 'table_cell_value', {
|
62
|
+
post 'table_cell_value', { :value => value }
|
52
63
|
end
|
53
64
|
|
54
65
|
def doc_string(string)
|
55
|
-
post 'doc_string', {
|
66
|
+
post 'doc_string', { :multiline_string => string }
|
56
67
|
end
|
57
68
|
|
58
69
|
def after_features(features)
|
59
|
-
post 'after_features', {
|
70
|
+
post 'after_features', { :duration => features.duration }
|
60
71
|
end
|
61
72
|
|
62
73
|
private
|
data/lib/cuukie/server.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'json'
|
3
|
+
require 'syntax/convertors/html'
|
3
4
|
|
4
5
|
module Cuukie
|
5
6
|
class Server < Sinatra::Base
|
6
|
-
set :features,
|
7
|
-
set :build_status,
|
8
|
-
set :
|
9
|
-
set :
|
7
|
+
set :features, []
|
8
|
+
set :build_status, nil
|
9
|
+
set :duration, '?'
|
10
|
+
set :stats, {:scenarios => '', :steps => ''}
|
10
11
|
|
11
12
|
get '/' do
|
12
13
|
@features = settings.features
|
@@ -48,6 +49,11 @@ module Cuukie
|
|
48
49
|
'OK'
|
49
50
|
end
|
50
51
|
|
52
|
+
post '/exception' do
|
53
|
+
current_step['exception'] = read_from_request
|
54
|
+
'OK'
|
55
|
+
end
|
56
|
+
|
51
57
|
post '/after_step_result' do
|
52
58
|
current_step.merge! read_from_request
|
53
59
|
if current_step['status'] == 'failed'
|
@@ -96,6 +102,22 @@ module Cuukie
|
|
96
102
|
get('/ping') { 'pong!' }
|
97
103
|
delete('/') { exit! }
|
98
104
|
|
105
|
+
helpers do
|
106
|
+
def snippet(exception)
|
107
|
+
return '' unless exception['raw_lines']
|
108
|
+
result = '<pre class="ruby"><code>'
|
109
|
+
linenum = exception['first_line']
|
110
|
+
html_lines = htmlize(exception['raw_lines']).split "\n"
|
111
|
+
html_lines.each do |html_line|
|
112
|
+
line = "<span class=\"linenum\">#{linenum}</span>#{html_line}"
|
113
|
+
line = "<span class=\"offending\">#{line}</span>" if linenum == exception['marked_line']
|
114
|
+
result << "#{line}<br/>"
|
115
|
+
linenum += 1
|
116
|
+
end
|
117
|
+
result << '</code></pre>'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
99
121
|
def current_feature
|
100
122
|
settings.features.last
|
101
123
|
end
|
@@ -129,7 +151,6 @@ module Cuukie
|
|
129
151
|
result
|
130
152
|
end
|
131
153
|
|
132
|
-
# shamelessly ripped from Cucumber's HTML formatter
|
133
154
|
def counts(elements)
|
134
155
|
counts = ['failed', 'skipped', 'undefined', 'pending', 'passed'].map do |status|
|
135
156
|
selected = elements.find_all {|element| element['status'] == status }
|
@@ -138,16 +159,23 @@ module Cuukie
|
|
138
159
|
counts.any? ? " (#{counts.join(', ')})" : ''
|
139
160
|
end
|
140
161
|
|
141
|
-
|
142
|
-
|
143
|
-
[count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(' ')
|
162
|
+
def dump_count(count, what)
|
163
|
+
"#{count} #{what}#{count == 1 ? '' : 's'}"
|
144
164
|
end
|
145
165
|
|
166
|
+
def htmlize(ruby)
|
167
|
+
convertor = Syntax::Convertors::HTML.for_syntax("ruby")
|
168
|
+
convertor.convert(ruby, false)
|
169
|
+
end
|
170
|
+
|
146
171
|
include Rack::Utils
|
147
172
|
|
148
173
|
def read_from_request
|
149
|
-
|
150
|
-
result
|
174
|
+
data = JSON.parse request.body.read
|
175
|
+
result = data.clone
|
176
|
+
result.each do |k, v|
|
177
|
+
result[k] = escape_html(v) if v.class == String && k !~ /^raw_/
|
178
|
+
end
|
151
179
|
end
|
152
180
|
end
|
153
|
-
end
|
181
|
+
end
|
data/lib/cuukie/views/index.erb
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
</head>
|
9
9
|
|
10
10
|
<body>
|
11
|
+
<!-- header -->
|
11
12
|
<div class="cucumber"><div id="cucumber-header"><div id="label"><h1>Cucumber Features</h1></div>
|
12
13
|
<div id="summary">
|
13
14
|
<p id="stats"></p>
|
@@ -15,8 +16,13 @@
|
|
15
16
|
<div id="expand-collapse"><p id="expander">Expand All</p><p id="collapser">Collapse All</p></div>
|
16
17
|
</div>
|
17
18
|
</div>
|
18
|
-
|
19
19
|
<script><%= @build_status %>Colors('cucumber-header')</script>
|
20
|
+
<script type="text/javascript">
|
21
|
+
document.getElementById('duration').innerHTML = "Finished in <strong><%= @duration %> seconds</strong>";
|
22
|
+
</script>
|
23
|
+
<script type="text/javascript">
|
24
|
+
document.getElementById('stats').innerHTML = "<%= @stats[:scenarios] %><br/><%= @stats[:steps] %>";
|
25
|
+
</script>
|
20
26
|
|
21
27
|
<% @features.each do |feature| %>
|
22
28
|
<div class="feature">
|
@@ -37,6 +43,11 @@
|
|
37
43
|
<span class="keyword"><%= step['keyword'] %></span><span class="step val"><%= step['name'] %></span>
|
38
44
|
</div>
|
39
45
|
<div class="step_file"><span><%= step['file_colon_line'] %></span></div>
|
46
|
+
<% if step['exception'] %>
|
47
|
+
<div class="message"><pre><%= step['exception']['message'] %></pre></div>
|
48
|
+
<div class="backtrace"><pre><%= step['exception']['backtrace'].gsub('\n', '<br/>') %></pre></div>
|
49
|
+
<%= snippet step['exception'] %>
|
50
|
+
<% end %>
|
40
51
|
<% unless step['table'].empty? %>
|
41
52
|
<table>
|
42
53
|
<% step['table'].each_with_index do |rowdata, row| %>
|
@@ -58,12 +69,6 @@
|
|
58
69
|
<% end %>
|
59
70
|
</div>
|
60
71
|
<% end %>
|
61
|
-
<script type="text/javascript">
|
62
|
-
document.getElementById('duration').innerHTML = "Finished in <strong><%= @duration %> seconds</strong>";
|
63
|
-
</script>
|
64
|
-
<script type="text/javascript">
|
65
|
-
document.getElementById('stats').innerHTML = "<%= @stats[:scenarios] %><br/><%= @stats[:steps] %>";
|
66
|
-
</script>
|
67
72
|
</div>
|
68
73
|
</body>
|
69
74
|
</html>
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'cuukie/cucumber/formatter/code_snippets'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe "The code_snippet method" do
|
5
|
+
include Cuukie::CodeSnippets
|
6
|
+
|
7
|
+
before(:all) do
|
8
|
+
@source = Tempfile.new('source.rb')
|
9
|
+
@source.write <<SOURCE
|
10
|
+
# line one
|
11
|
+
line_two = 2
|
12
|
+
line_three()
|
13
|
+
line_four.each do |x|
|
14
|
+
x.line_five
|
15
|
+
end # line six
|
16
|
+
SOURCE
|
17
|
+
@source.close
|
18
|
+
end
|
19
|
+
|
20
|
+
after(:all) do
|
21
|
+
@source.delete
|
22
|
+
end
|
23
|
+
|
24
|
+
it "has a marked line number" do
|
25
|
+
snippet = code_snippet @source.path, 4
|
26
|
+
snippet[:marked_line].should == 4
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns a nil snippet if it cannot find the file" do
|
30
|
+
snippet = code_snippet 'no_such_file.txt', 4
|
31
|
+
snippet['lines'].should be_nil
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns nil if the file is not valid" do
|
35
|
+
snippet = code_snippet '', 4
|
36
|
+
snippet['lines'].should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns nil if it cannot find the line" do
|
40
|
+
snippet = code_snippet @source.path, 7
|
41
|
+
snippet['lines'].should be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns a snippet of the lines around the marked line" do
|
45
|
+
snippet = code_snippet @source.path, 5
|
46
|
+
snippet[:raw_lines].should == "line_three()\nline_four.each do |x|\n x.line_five\nend # line six\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a first line number" do
|
50
|
+
snippet = code_snippet @source.path, 5
|
51
|
+
snippet[:first_line].should == 3
|
52
|
+
end
|
53
|
+
|
54
|
+
it "clips lines at the beginning of the file" do
|
55
|
+
snippet = code_snippet @source.path, 2
|
56
|
+
snippet[:raw_lines].should == "# line one\nline_two = 2\nline_three()\n"
|
57
|
+
snippet[:first_line].should == 1
|
58
|
+
end
|
59
|
+
|
60
|
+
it "clips lines at the end of the file" do
|
61
|
+
snippet = code_snippet @source.path, 6
|
62
|
+
snippet[:raw_lines].should == "line_four.each do |x|\n x.line_five\nend # line six\n"
|
63
|
+
snippet[:first_line].should == 4
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "The backtrace_to_snippet method" do
|
68
|
+
include Cuukie::CodeSnippets
|
69
|
+
|
70
|
+
it "extracts file and line from a backtrace" do
|
71
|
+
source = Tempfile.new('source.rb')
|
72
|
+
source.write <<SOURCE
|
73
|
+
# one
|
74
|
+
# two
|
75
|
+
1 / 0
|
76
|
+
# four
|
77
|
+
SOURCE
|
78
|
+
source.close
|
79
|
+
begin
|
80
|
+
load source.path
|
81
|
+
rescue Exception => e
|
82
|
+
backtrace_to_snippet(e.backtrace).should == {:first_line => 1,
|
83
|
+
:marked_line => 3,
|
84
|
+
:raw_lines => "# one\n# two\n1 / 0\n# four\n"}
|
85
|
+
ensure
|
86
|
+
source.delete
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns nil if the extraction fails" do
|
91
|
+
backtrace_to_snippet(['abcd'])['lines'].should be_nil
|
92
|
+
end
|
93
|
+
end
|
data/spec/commands_spec.rb
CHANGED
@@ -31,7 +31,7 @@ describe "The cuukie formatter" do
|
|
31
31
|
wait_for_server_on_port 4569
|
32
32
|
cmd = "cd spec/test_project && \
|
33
33
|
cucumber features/1_show_scenarios.feature:9 \
|
34
|
-
|
34
|
+
--format cuukie > #{@out.path}"
|
35
35
|
system(cmd).should be_true
|
36
36
|
@out.read.should == ''
|
37
37
|
ensure
|
@@ -45,8 +45,8 @@ describe "The cuukie formatter" do
|
|
45
45
|
wait_for_server_on_port 4570
|
46
46
|
cmd = "cd spec/test_project && \
|
47
47
|
cucumber features/1_show_scenarios.feature:9 \
|
48
|
-
|
49
|
-
|
48
|
+
CUUKIE_SERVER=http://localhost:4570 \
|
49
|
+
--format cuukie > #{@out.path}"
|
50
50
|
system(cmd).should be_true
|
51
51
|
@out.read.should == ''
|
52
52
|
ensure
|
@@ -57,8 +57,8 @@ describe "The cuukie formatter" do
|
|
57
57
|
it "fails gracefully if the server is down" do
|
58
58
|
cmd = "cd spec/test_project && \
|
59
59
|
cucumber features/1_show_scenarios.feature:9 \
|
60
|
-
|
61
|
-
|
60
|
+
CUUKIE_SERVER=http://some.server:4570 \
|
61
|
+
--format cuukie > #{@out.path}"
|
62
62
|
system(cmd).should be_true
|
63
63
|
@out.read.should match 'I cannot find the cuukie_server on http://some.server:4570'
|
64
64
|
end
|
data/spec/cuukie_spec.rb
CHANGED
@@ -4,29 +4,6 @@ describe 'Cuukie' do
|
|
4
4
|
before(:all) { start_server }
|
5
5
|
after(:all) { stop_server_on_port 4569 }
|
6
6
|
|
7
|
-
describe 'shows suite result at the top of the page' do
|
8
|
-
it "contains essential information" do
|
9
|
-
run_cucumber
|
10
|
-
html.should match '<h1>Cucumber Features</h1>'
|
11
|
-
html.should match '<title>Cuukie</title>'
|
12
|
-
end
|
13
|
-
|
14
|
-
it "shows green if all scenarios passed" do
|
15
|
-
run_cucumber '1_show_scenarios.feature:9'
|
16
|
-
html.should match /passedColors\('cucumber-header'\)/
|
17
|
-
end
|
18
|
-
|
19
|
-
it "shows red if any scenario failed" do
|
20
|
-
run_cucumber '1_show_scenarios.feature'
|
21
|
-
html.should match /failedColors\('cucumber-header'\)/
|
22
|
-
end
|
23
|
-
|
24
|
-
it "shows yellow if no scenarios failed but some are pending" do
|
25
|
-
run_cucumber '1_show_scenarios.feature:19'
|
26
|
-
html.should match /pendingColors\('cucumber-header'\)/
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
7
|
describe 'in the content area' do
|
31
8
|
before(:all) { run_cucumber }
|
32
9
|
|
@@ -37,7 +14,7 @@ describe 'Cuukie' do
|
|
37
14
|
|
38
15
|
it "shows the feature names" do
|
39
16
|
html.should match '>Feature: Visualize Scenarios<'
|
40
|
-
html.should match '>Feature:
|
17
|
+
html.should match '>Feature: Show Failed Background<'
|
41
18
|
end
|
42
19
|
|
43
20
|
it "shows the feature narratives" do
|
@@ -77,14 +54,32 @@ describe 'Cuukie' do
|
|
77
54
|
end
|
78
55
|
|
79
56
|
it "shows the step source position" do
|
80
|
-
html.should match '>features/step_definitions/
|
57
|
+
html.should match '>features/step_definitions/main_steps.rb:'
|
81
58
|
end
|
82
59
|
|
83
60
|
it "shows the step status" do
|
84
61
|
html.should match 'class="step passed"'
|
85
62
|
html.should match 'class="step pending"'
|
86
63
|
end
|
87
|
-
|
64
|
+
|
65
|
+
it "shows exception messages" do
|
66
|
+
html.should match /main_steps.rb:7<\/span><\/div>[ \n]*<div class="message"><pre>Crash!<\/pre><\/div>/
|
67
|
+
end
|
68
|
+
|
69
|
+
it "shows exception backtraces" do
|
70
|
+
html.should match 'backtrace"><pre>./features/step_definitions/main_steps.rb:8:in `/I do'
|
71
|
+
html.should match '3_failed_background.feature:7:in `Given I do'
|
72
|
+
end
|
73
|
+
|
74
|
+
it "shows exception source snippets" do
|
75
|
+
html.should match '<pre class="ruby"><code><span class="linenum">6<\/span>'
|
76
|
+
html.should match '<span class="constant">I</span> <span class="keyword">do</span> <span class="ident">something'
|
77
|
+
end
|
78
|
+
|
79
|
+
it "marks the exception source in snippets" do
|
80
|
+
html.should match '<span class="offending"><span class="linenum">8<\/span> <span class=\"keyword\">raise'
|
81
|
+
end
|
82
|
+
|
88
83
|
it "escapes HTML output" do
|
89
84
|
html.should match 'I pass an "argument"'
|
90
85
|
end
|
@@ -108,4 +103,27 @@ describe 'Cuukie' do
|
|
108
103
|
html.should match /11 steps \(1 failed, 2 skipped, 1 pending, 7 passed\)/
|
109
104
|
end
|
110
105
|
end
|
106
|
+
|
107
|
+
describe 'in the page header' do
|
108
|
+
it "contains essential information" do
|
109
|
+
run_cucumber
|
110
|
+
html.should match '<h1>Cucumber Features</h1>'
|
111
|
+
html.should match '<title>Cuukie</title>'
|
112
|
+
end
|
113
|
+
|
114
|
+
it "shows green if all scenarios passed" do
|
115
|
+
run_cucumber '1_show_scenarios.feature:9'
|
116
|
+
html.should match /passedColors\('cucumber-header'\)/
|
117
|
+
end
|
118
|
+
|
119
|
+
it "shows red if any scenario failed" do
|
120
|
+
run_cucumber '1_show_scenarios.feature'
|
121
|
+
html.should match /failedColors\('cucumber-header'\)/
|
122
|
+
end
|
123
|
+
|
124
|
+
it "shows yellow if no scenarios failed but some are pending" do
|
125
|
+
run_cucumber '1_show_scenarios.feature:19'
|
126
|
+
html.should match /pendingColors\('cucumber-header'\)/
|
127
|
+
end
|
128
|
+
end
|
111
129
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -18,6 +18,10 @@ require 'rest-client'
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
def html
|
22
|
+
GET('/').body
|
23
|
+
end
|
24
|
+
|
21
25
|
def start_server
|
22
26
|
start_process "ruby bin/cuukie_server >/dev/null 2>&1"
|
23
27
|
wait_for_server_on_port 4569
|
@@ -37,7 +41,3 @@ def stop_server_on_port(port)
|
|
37
41
|
RestClient.delete "http://localhost:#{port}/"
|
38
42
|
rescue
|
39
43
|
end
|
40
|
-
|
41
|
-
def html
|
42
|
-
GET('/').body
|
43
|
-
end
|
data/spec/test_project/features/{4_show_multiline_args.feature → 2_show_multiline_args.feature}
RENAMED
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Exception with no source
|
2
|
+
As a Cuker
|
3
|
+
I want to visualize exceptions even if I cannot retrieve the code
|
4
|
+
So that I can still use Cuukie when the source is on another machine
|
5
|
+
|
6
|
+
Scenario: Exception with unknown file
|
7
|
+
When I get an exception referencing a file that doesn't exist
|
8
|
+
Then Cuukie should be OK with it
|
9
|
+
|
10
|
+
Scenario: Exception with wrong line
|
11
|
+
When I get an exception referencing a line that doesn't exist
|
12
|
+
Then Cuukie should be OK with it
|
13
|
+
|
14
|
+
Scenario: Exception with mangled backtrace
|
15
|
+
When I get an exception and I cannot even tell which file and line it's from
|
16
|
+
Then Cuukie should be OK with it
|
@@ -0,0 +1,26 @@
|
|
1
|
+
When /^I get an exception referencing a file that doesn't exist$/ do
|
2
|
+
begin
|
3
|
+
1 / 0
|
4
|
+
rescue Exception => e
|
5
|
+
e.backtrace[0].gsub! File.dirname(__FILE__), 'no_such_directory'
|
6
|
+
raise e
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I get an exception referencing a line that doesn't exist$/ do
|
11
|
+
begin
|
12
|
+
1 / 0
|
13
|
+
rescue Exception => e
|
14
|
+
e.backtrace[0].gsub! /:[\d]+:/, ':10000:'
|
15
|
+
raise e
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
When /^I get an exception and I cannot even tell which file and line it's from$/ do
|
20
|
+
begin
|
21
|
+
1 / 0
|
22
|
+
rescue Exception => e
|
23
|
+
e.backtrace[0].gsub! /:(.*):/, 'mangle mangle'
|
24
|
+
raise e
|
25
|
+
end
|
26
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cuukie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
16
|
-
requirement: &
|
16
|
+
requirement: &70339163759300 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70339163759300
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rest-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &70339163757860 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70339163757860
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: cucumber
|
38
|
-
requirement: &
|
38
|
+
requirement: &70339163755420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,21 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70339163755420
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: syntax
|
49
|
+
requirement: &70339163753560 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70339163753560
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: rake
|
49
|
-
requirement: &
|
60
|
+
requirement: &70339163760240 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,10 +65,10 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *70339163760240
|
58
69
|
- !ruby/object:Gem::Dependency
|
59
70
|
name: jeweler
|
60
|
-
requirement: &
|
71
|
+
requirement: &70339163758480 !ruby/object:Gem::Requirement
|
61
72
|
none: false
|
62
73
|
requirements:
|
63
74
|
- - ! '>='
|
@@ -65,7 +76,7 @@ dependencies:
|
|
65
76
|
version: '0'
|
66
77
|
type: :development
|
67
78
|
prerelease: false
|
68
|
-
version_requirements: *
|
79
|
+
version_requirements: *70339163758480
|
69
80
|
description: Shows Cucumber results on a web page as they run.
|
70
81
|
email: paolo.nusco.perrotta@gmail.com
|
71
82
|
executables:
|
@@ -87,21 +98,23 @@ files:
|
|
87
98
|
- doc/backlog.txt
|
88
99
|
- doc/pomodoro.txt
|
89
100
|
- lib/cuukie.rb
|
101
|
+
- lib/cuukie/cucumber/formatter/code_snippets.rb
|
90
102
|
- lib/cuukie/cucumber/formatter/cuukie.rb
|
91
103
|
- lib/cuukie/public/cucumber.css
|
92
104
|
- lib/cuukie/public/cuukie.js
|
93
105
|
- lib/cuukie/public/jquery-1.7.min.js
|
94
106
|
- lib/cuukie/server.rb
|
95
107
|
- lib/cuukie/views/index.erb
|
96
|
-
-
|
108
|
+
- spec/code_snippets_spec.rb
|
97
109
|
- spec/commands_spec.rb
|
98
110
|
- spec/cuukie_spec.rb
|
99
111
|
- spec/spec_helper.rb
|
100
112
|
- spec/test_project/features/1_show_scenarios.feature
|
101
|
-
- spec/test_project/features/
|
113
|
+
- spec/test_project/features/2_show_multiline_args.feature
|
102
114
|
- spec/test_project/features/3_failed_background.feature
|
103
|
-
- spec/test_project/features/
|
104
|
-
- spec/test_project/features/step_definitions/
|
115
|
+
- spec/test_project/features/4_exception_with_no_source.feature
|
116
|
+
- spec/test_project/features/step_definitions/exception_steps.rb
|
117
|
+
- spec/test_project/features/step_definitions/main_steps.rb
|
105
118
|
- spec/test_project/features/support/formatters.rb
|
106
119
|
homepage: http://github.com/nusco/cuukie
|
107
120
|
licenses:
|
@@ -118,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
131
|
version: '0'
|
119
132
|
segments:
|
120
133
|
- 0
|
121
|
-
hash: -
|
134
|
+
hash: -2459400379263552476
|
122
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
136
|
none: false
|
124
137
|
requirements:
|
data/lib/test.rb
DELETED
File without changes
|