cukable 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/History.md +17 -0
- data/README.md +55 -2
- data/cukable.gemspec +2 -1
- data/features/cuke_fixture.feature +62 -10
- data/features/slim_json_formatter.feature +1 -3
- data/features/step_definitions/cukable_steps.rb +23 -26
- data/features/support/env.rb +44 -45
- data/lib/cukable/conversion.rb +13 -7
- data/lib/cukable/cuke.rb +71 -26
- metadata +30 -13
- data/Gemfile.lock +0 -47
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/History.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Cukable History
|
2
|
+
===============
|
3
|
+
|
4
|
+
0.1.2
|
5
|
+
-----
|
6
|
+
|
7
|
+
- Multiple-project capability
|
8
|
+
- Support for RVM and bundler
|
9
|
+
|
10
|
+
|
11
|
+
0.1.1
|
12
|
+
-----
|
13
|
+
|
14
|
+
- SlimJSON output formatter for Cucumber
|
15
|
+
- Cuke fixture for running tests from FitNesse
|
16
|
+
- Basic single-project support (one FitNesse instance per project)
|
17
|
+
|
data/README.md
CHANGED
@@ -32,8 +32,10 @@ To install Cukable, do:
|
|
32
32
|
Cukable requires [rubyslim](http://github.com/unclebob/rubyslim) in order to
|
33
33
|
work; as of this writing, rubyslim is not officially packaged as a gem, making
|
34
34
|
it slightly more difficult to get Cukable working. For this reason, a makeshift
|
35
|
-
rubyslim gem is provided in the `vendor/cache` directory of Cukable.
|
36
|
-
|
35
|
+
rubyslim gem is provided in the `vendor/cache` directory of Cukable. Use `gem
|
36
|
+
list cukable -d` to find out the full installation path for cukable, then
|
37
|
+
append `/vendor/cache/rubyslim-0.1.1.gem` on the end of that,a nd install like
|
38
|
+
so:
|
37
39
|
|
38
40
|
$ gem install /path/to/cukable/vendor/cache/rubyslim-0.1.1.gem
|
39
41
|
|
@@ -43,6 +45,19 @@ please report any issues with it to the
|
|
43
45
|
[Cukable issue tracker](http://github.com/wapcaplet/cukable/issues).
|
44
46
|
|
45
47
|
|
48
|
+
Configuration
|
49
|
+
-------------
|
50
|
+
|
51
|
+
FitNesse uses a JSON format for its test reporting, so you must enable the SLIM
|
52
|
+
JSON output formatter provided by Cukable. To make Cucumber aware of this
|
53
|
+
formatter, add this line:
|
54
|
+
|
55
|
+
require 'cukable/slim_json_formatter'
|
56
|
+
|
57
|
+
to your `features/support/env.rb`, `features/support/custom_env.rb`, or
|
58
|
+
wherever you're keeping custom initialization for your Cucumber environment.
|
59
|
+
|
60
|
+
|
46
61
|
Converting existing features
|
47
62
|
----------------------------
|
48
63
|
|
@@ -291,6 +306,44 @@ any arguments passed to individual tables, because Cucumber is only executed
|
|
291
306
|
once for the entire suite.
|
292
307
|
|
293
308
|
|
309
|
+
Multiple projects
|
310
|
+
-----------------
|
311
|
+
|
312
|
+
As of Cukable version 0.1.2, you can run tests in multiple project directories.
|
313
|
+
For example, you may have two applications that you want to test with Cukable:
|
314
|
+
|
315
|
+
- `/home/eric/projects/A`: First application you want to test
|
316
|
+
- `/home/eric/projects/B`: Second application you want to test
|
317
|
+
- `/home/eric/projects/FitNesseRoot`: Where your wiki is stored
|
318
|
+
|
319
|
+
Projects `A` and `B` may have different dependencies, and you want Cukable to
|
320
|
+
mimic the process of running `cucumber` within each of those directories. If
|
321
|
+
`A` and `B` are Rails applications, and you know what's good for you, you're
|
322
|
+
already using [bundler](http://gembundler.com/) to manage each application's
|
323
|
+
gem dependencies, and [RVM](http://rvm.beginrescueend.com/) with two distinct
|
324
|
+
gemsets to keep the projects' dependencies from interfering with one another.
|
325
|
+
This is what Cukable expects that you are doing.
|
326
|
+
|
327
|
+
In your wiki pages (either in a `Cuke` table, or in the `accelerate` function
|
328
|
+
call), you can pass a third argument (after `CUCUMBER_ARGS`) that indicates the
|
329
|
+
directory where that test should be executed. For instance, you could have a
|
330
|
+
wiki page with two tests--one for each project:
|
331
|
+
|
332
|
+
!| Table: Cuke | | /home/eric/projects/A |
|
333
|
+
| When I run a test on project A |
|
334
|
+
| Then the test should pass |
|
335
|
+
|
336
|
+
!| Table: Cuke | | /home/eric/projects/B |
|
337
|
+
| When I run a different test on project B |
|
338
|
+
| Then the test should pass |
|
339
|
+
|
340
|
+
These two tests will be executed in their respective directories. If the two
|
341
|
+
applications have differing gem dependencies, you should put an `.rvmrc` file
|
342
|
+
in both the `A` and `B` directories, containing the correct `rvm` command to
|
343
|
+
switch gemsets; if Cukable finds an `.rvmrc` in a project directory, it will be
|
344
|
+
sourced so that Cucumber runs within the context of that gemset.
|
345
|
+
|
346
|
+
|
294
347
|
Support
|
295
348
|
-------
|
296
349
|
|
data/cukable.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "cukable"
|
3
|
-
s.version = "0.1.
|
3
|
+
s.version = "0.1.2"
|
4
4
|
s.summary = "Runs Cucumber tests from FitNesse"
|
5
5
|
s.description = <<-EOS
|
6
6
|
Cukable allows running Cucumber test scenarios from FitNesse
|
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.add_dependency 'cucumber'
|
15
15
|
s.add_dependency 'diff-lcs'
|
16
16
|
|
17
|
+
s.add_development_dependency 'rake', '~> 0.8.7'
|
17
18
|
s.add_development_dependency 'rspec', '>= 2.2.0'
|
18
19
|
s.add_development_dependency 'rcov'
|
19
20
|
s.add_development_dependency 'yard'
|
@@ -4,7 +4,7 @@ Feature: Cuke fixture
|
|
4
4
|
Given a standard Cucumber project directory structure
|
5
5
|
|
6
6
|
Scenario: Do table
|
7
|
-
Given a Cuke fixture
|
7
|
+
Given a default Cuke fixture
|
8
8
|
When I do this table:
|
9
9
|
| Feature: Table |
|
10
10
|
| Scenario: Table |
|
@@ -18,19 +18,19 @@ Feature: Cuke fixture
|
|
18
18
|
"""
|
19
19
|
|
20
20
|
Scenario: Write features
|
21
|
-
Given a Cuke fixture
|
21
|
+
Given a default Cuke fixture
|
22
22
|
And a FitNesse wiki
|
23
|
-
And a
|
23
|
+
And a Suite "TestSuite" containing:
|
24
24
|
"""
|
25
25
|
!contents
|
26
26
|
"""
|
27
|
-
And a
|
27
|
+
And a Test "TestSuite/HelloWorld" containing:
|
28
28
|
"""
|
29
29
|
| Table: Cuke |
|
30
30
|
| Feature: Hello |
|
31
31
|
| Scenario: Hello |
|
32
32
|
"""
|
33
|
-
And a
|
33
|
+
And a Test "TestSuite/GoodbyeWorld" containing:
|
34
34
|
"""
|
35
35
|
| Table: Cuke |
|
36
36
|
| Feature: Goodbye |
|
@@ -50,9 +50,60 @@ Feature: Cuke fixture
|
|
50
50
|
"""
|
51
51
|
|
52
52
|
|
53
|
+
Scenario: Write features for multiple projects
|
54
|
+
Given a FitNesse wiki
|
55
|
+
And a Suite "TestSuite" containing:
|
56
|
+
"""
|
57
|
+
!define TEST_SYSTEM {slim}
|
58
|
+
!define TEST_RUNNER {rubyslim}
|
59
|
+
!define COMMAND_PATTERN {rubyslim}
|
60
|
+
!contents
|
61
|
+
"""
|
62
|
+
|
63
|
+
And a Suite "TestSuite/ProjectA" containing:
|
64
|
+
"""
|
65
|
+
!contents
|
66
|
+
"""
|
67
|
+
And a Test "TestSuite/ProjectA/HelloWorld" containing:
|
68
|
+
"""
|
69
|
+
| Table: Cuke |
|
70
|
+
| Feature: Hello |
|
71
|
+
| Scenario: Hello |
|
72
|
+
"""
|
73
|
+
And a Cuke fixture with arguments:
|
74
|
+
| project_dir | project_a |
|
75
|
+
|
76
|
+
When I write features for suite "TestSuite/ProjectA"
|
77
|
+
Then "project_a/features/fitnesse/HelloWorld_0.feature" should contain:
|
78
|
+
"""
|
79
|
+
Feature: Hello
|
80
|
+
Scenario: Hello
|
81
|
+
"""
|
82
|
+
|
83
|
+
Given a Suite "TestSuite/ProjectB" containing:
|
84
|
+
"""
|
85
|
+
!contents
|
86
|
+
"""
|
87
|
+
And a Test "TestSuite/ProjectB/GoodbyeWorld" containing:
|
88
|
+
"""
|
89
|
+
| Table: Cuke |
|
90
|
+
| Feature: Goodbye |
|
91
|
+
| Scenario: Goodbye |
|
92
|
+
"""
|
93
|
+
And a Cuke fixture with arguments:
|
94
|
+
| project_dir | project_b |
|
95
|
+
|
96
|
+
When I write features for suite "TestSuite/ProjectB"
|
97
|
+
Then "project_b/features/fitnesse/GoodbyeWorld_0.feature" should contain:
|
98
|
+
"""
|
99
|
+
Feature: Goodbye
|
100
|
+
Scenario: Goodbye
|
101
|
+
"""
|
102
|
+
|
103
|
+
|
53
104
|
Scenario: Accelerate suite
|
54
105
|
Given a FitNesse wiki
|
55
|
-
And a Cuke fixture
|
106
|
+
And a default Cuke fixture
|
56
107
|
And a Suite "FeatureS" containing:
|
57
108
|
"""
|
58
109
|
!define TEST_SYSTEM {slim}
|
@@ -88,7 +139,7 @@ Feature: Cuke fixture
|
|
88
139
|
[
|
89
140
|
["report:Feature: Passing"],
|
90
141
|
["report:Scenario: Passing"],
|
91
|
-
["
|
142
|
+
["pass:Given a step passes"]
|
92
143
|
]
|
93
144
|
"""
|
94
145
|
|
@@ -97,16 +148,18 @@ Feature: Cuke fixture
|
|
97
148
|
[
|
98
149
|
["report:Feature: Failing"],
|
99
150
|
["report:Scenario: Failing"],
|
100
|
-
["
|
151
|
+
["fail:Given a step fails"]
|
101
152
|
]
|
102
153
|
"""
|
103
154
|
|
104
155
|
|
105
156
|
@wip
|
157
|
+
@focus
|
106
158
|
Scenario: Accelerate suite with skipped tags
|
107
159
|
# FIXME: Fails when run with other scenarios. Lack of init/cleanup in self_test dir?
|
108
160
|
Given a FitNesse wiki
|
109
|
-
And a Cuke fixture
|
161
|
+
And a Cuke fixture with arguments:
|
162
|
+
| cucumber_args | --tags ~@skip |
|
110
163
|
|
111
164
|
And a Test "FeatureS/SkippedScenariosFeature" containing:
|
112
165
|
"""
|
@@ -131,7 +184,6 @@ Feature: Cuke fixture
|
|
131
184
|
| Given a step fails |
|
132
185
|
"""
|
133
186
|
|
134
|
-
When I set CUCUMBER_ARGS to "--tags ~@skip"
|
135
187
|
And I run the accelerator for suite "FeatureS"
|
136
188
|
|
137
189
|
Then "slim_results/features/fitnesse/SkippedScenariosFeature_0.feature.json" should contain JSON:
|
@@ -1,4 +1,3 @@
|
|
1
|
-
@wip
|
2
1
|
Feature: Slim JSON Formatter
|
3
2
|
|
4
3
|
Background:
|
@@ -146,8 +145,7 @@ Feature: Slim JSON Formatter
|
|
146
145
|
["report:Examples: "],
|
147
146
|
["report: ", "pass:result"],
|
148
147
|
["report: ", "pass:passes"],
|
149
|
-
["
|
150
|
-
["fail:<br/>"]
|
148
|
+
["fail:", "fail:fails"]
|
151
149
|
]
|
152
150
|
"""
|
153
151
|
|
@@ -12,17 +12,6 @@ end
|
|
12
12
|
|
13
13
|
Given /^a FitNesse wiki$/ do
|
14
14
|
create_standard_fitnesse_dir
|
15
|
-
@fitnesse_root = 'FitNesseRoot'
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
Given /^a FitNesse suite "(.+)" with:$/ do |page_name, content|
|
20
|
-
create_fitnesse_page(page_name, content)
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
Given /^a FitNesse test "(.+)" with:$/ do |page_name, content|
|
25
|
-
create_fitnesse_page(page_name, content)
|
26
15
|
end
|
27
16
|
|
28
17
|
|
@@ -38,12 +27,16 @@ end
|
|
38
27
|
|
39
28
|
|
40
29
|
Then /^"(.+)" should contain:$/ do |filename, text|
|
41
|
-
|
30
|
+
in_test_dir do
|
31
|
+
file_should_contain(filename, text)
|
32
|
+
end
|
42
33
|
end
|
43
34
|
|
44
35
|
|
45
36
|
Then /^"(.+)" should contain JSON:$/ do |filename, json_text|
|
46
|
-
|
37
|
+
in_test_dir do
|
38
|
+
file_should_contain_json(filename, json_text)
|
39
|
+
end
|
47
40
|
end
|
48
41
|
|
49
42
|
|
@@ -57,25 +50,34 @@ end
|
|
57
50
|
|
58
51
|
|
59
52
|
Given /^a (Test|Suite) "(.+)" containing:$/ do |type, filename, content|
|
60
|
-
content_file = File.join(
|
61
|
-
properties_file = File.join(
|
53
|
+
content_file = File.join(fitnesse_dir, filename, 'content.txt')
|
54
|
+
properties_file = File.join(fitnesse_dir, filename, 'properties.xml')
|
62
55
|
create_file(content_file, content)
|
63
56
|
create_file(properties_file, xml_content(type))
|
64
57
|
end
|
65
58
|
|
66
59
|
|
67
60
|
Then /^I should have a (Test|Suite) "(.+)" containing:$/ do |type, filename, content|
|
68
|
-
content_file = File.join(
|
69
|
-
properties_file = File.join(
|
61
|
+
content_file = File.join(fitnesse_dir, filename, 'content.txt')
|
62
|
+
properties_file = File.join(fitnesse_dir, filename, 'properties.xml')
|
70
63
|
file_should_contain(content_file, content)
|
71
64
|
file_should_contain(properties_file, xml_content(type))
|
72
65
|
end
|
73
66
|
|
74
67
|
|
75
|
-
Given /^a Cuke fixture$/ do
|
68
|
+
Given /^a default Cuke fixture$/ do
|
76
69
|
in_test_dir do
|
77
70
|
@cuke = Cukable::Cuke.new
|
78
|
-
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
Given /^a Cuke fixture with arguments:$/ do |arg_table|
|
76
|
+
args = arg_table.rows_hash
|
77
|
+
cucumber_args = args['cucumber_args'] or ''
|
78
|
+
project_dir = args['project_dir'] or ''
|
79
|
+
in_test_dir do
|
80
|
+
@cuke = Cukable::Cuke.new(cucumber_args, project_dir)
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
@@ -89,7 +91,7 @@ end
|
|
89
91
|
|
90
92
|
When /^I write features for suite "(.+)"$/ do |suite_name|
|
91
93
|
in_test_dir do
|
92
|
-
@cuke.write_suite_features(
|
94
|
+
@cuke.write_suite_features(File.join(fitnesse_dir, suite_name))
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
@@ -97,16 +99,11 @@ end
|
|
97
99
|
When /^I convert features to FitNesse$/ do
|
98
100
|
in_test_dir do
|
99
101
|
@converter = Cukable::Converter.new
|
100
|
-
@converter.features_to_fitnesse('features',
|
102
|
+
@converter.features_to_fitnesse('features', fitnesse_dir)
|
101
103
|
end
|
102
104
|
end
|
103
105
|
|
104
106
|
|
105
|
-
When /^I set CUCUMBER_ARGS to "(.+)"$/ do |args|
|
106
|
-
@cucumber_args = args
|
107
|
-
end
|
108
|
-
|
109
|
-
|
110
107
|
When /^I run the accelerator for suite "(.+)"$/ do |suite_name|
|
111
108
|
in_test_dir do
|
112
109
|
@cuke.accelerate("#{suite_name}.AaaAccelerator", @cucumber_args)
|
data/features/support/env.rb
CHANGED
@@ -16,12 +16,23 @@ class CukableHelper
|
|
16
16
|
end
|
17
17
|
|
18
18
|
|
19
|
+
def fitnesse_dir
|
20
|
+
@fitnesse_dir ||= File.join(test_dir, "FitNesseRoot")
|
21
|
+
end
|
22
|
+
|
23
|
+
|
19
24
|
# Execute `block` within `test_dir`
|
20
25
|
def in_test_dir(&block)
|
21
26
|
Dir.chdir(test_dir, &block)
|
22
27
|
end
|
23
28
|
|
24
29
|
|
30
|
+
# Execute `block` within `fitnesse_dir`
|
31
|
+
def in_fitnesse_dir(&block)
|
32
|
+
Dir.chdir(fitnesse_dir, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
25
36
|
# Create a standard cucumber features/ directory in `test_dir`
|
26
37
|
def create_standard_cucumber_dir
|
27
38
|
in_test_dir do
|
@@ -35,7 +46,7 @@ class CukableHelper
|
|
35
46
|
|
36
47
|
def create_standard_fitnesse_dir
|
37
48
|
in_test_dir do
|
38
|
-
FileUtils.mkdir_p
|
49
|
+
FileUtils.mkdir_p fitnesse_dir
|
39
50
|
end
|
40
51
|
end
|
41
52
|
|
@@ -50,18 +61,6 @@ class CukableHelper
|
|
50
61
|
end
|
51
62
|
|
52
63
|
|
53
|
-
def create_fitnesse_page(page_name, content)
|
54
|
-
in_test_dir do
|
55
|
-
page_dir = File.join('FitNesseRoot', page_name)
|
56
|
-
page_file = File.join(page_dir, 'content.txt')
|
57
|
-
FileUtils.mkdir_p page_dir
|
58
|
-
File.open(page_file, 'w') do |file|
|
59
|
-
file.puts(content)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
|
65
64
|
# Create features/support/env.rb with necessary configuration for running
|
66
65
|
# cucumber there
|
67
66
|
def create_env_rb
|
@@ -75,27 +74,25 @@ class CukableHelper
|
|
75
74
|
|
76
75
|
|
77
76
|
def create_stepdefs
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
cell.should == 'OK'
|
94
|
-
end
|
77
|
+
File.open('features/step_definitions/simple_steps.rb', 'w') do |file|
|
78
|
+
file.puts <<-EOF
|
79
|
+
Given /^a step passes$/ do
|
80
|
+
true.should == true
|
81
|
+
end
|
82
|
+
Given /^a step fails$/ do
|
83
|
+
true.should == false
|
84
|
+
end
|
85
|
+
Given /^a step is skipped$/ do
|
86
|
+
true.should == true
|
87
|
+
end
|
88
|
+
Given /^I have a table:$/ do |table|
|
89
|
+
table.raw.each do |row|
|
90
|
+
row.each do |cell|
|
91
|
+
cell.should == 'OK'
|
95
92
|
end
|
96
93
|
end
|
97
|
-
|
98
|
-
|
94
|
+
end
|
95
|
+
EOF
|
99
96
|
end
|
100
97
|
end
|
101
98
|
|
@@ -129,26 +126,23 @@ class CukableHelper
|
|
129
126
|
# Ensure that the given file contains exactly the given text
|
130
127
|
# (extra newlines/whitespace at beginning or end don't count)
|
131
128
|
def file_should_contain(filename, text)
|
132
|
-
|
133
|
-
IO.read(filename).strip.should == text.strip
|
134
|
-
end
|
129
|
+
IO.read(filename).strip.should == text.strip
|
135
130
|
end
|
136
131
|
|
137
132
|
|
138
133
|
# Ensure that the given filename contains JSON text.
|
139
134
|
#
|
140
|
-
# JSON does not need to match exactly; the output of each line
|
141
|
-
#
|
142
|
-
#
|
135
|
+
# JSON does not need to match exactly; the output of each line should *start*
|
136
|
+
# with the expected JSON text, but could contain additional stuff afterwards.
|
137
|
+
# (This is done so that a <span> with the source filename can appear after
|
138
|
+
# the line, and that kind of thing is too volatile to test for.)
|
143
139
|
def file_should_contain_json(filename, json_text)
|
144
|
-
|
145
|
-
|
146
|
-
want_json = JSON.parse(json_text)
|
140
|
+
got_json = JSON.load(File.open(filename))
|
141
|
+
want_json = JSON.parse(json_text)
|
147
142
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
143
|
+
got_json.zip(want_json).each do |got_row, want_row|
|
144
|
+
got_row.zip(want_row).each do |got, want|
|
145
|
+
got.should =~ /^#{want}/
|
152
146
|
end
|
153
147
|
end
|
154
148
|
end
|
@@ -181,3 +175,8 @@ After do
|
|
181
175
|
#remove_test_dir
|
182
176
|
end
|
183
177
|
|
178
|
+
Before do
|
179
|
+
remove_test_dir
|
180
|
+
create_test_dir
|
181
|
+
end
|
182
|
+
|
data/lib/cukable/conversion.rb
CHANGED
@@ -165,6 +165,9 @@ module Cukable
|
|
165
165
|
# Status messages to return
|
166
166
|
messages = []
|
167
167
|
|
168
|
+
# Strip trailing slash
|
169
|
+
fitnesse_path = fitnesse_path.gsub(/\/$/, '')
|
170
|
+
|
168
171
|
# Ensure FitNesse directory already exists
|
169
172
|
if !File.directory?(fitnesse_path)
|
170
173
|
raise ArgumentError, "FitNesse path must be an existing directory."
|
@@ -183,7 +186,7 @@ module Cukable
|
|
183
186
|
# Determine the appropriate wiki path name
|
184
187
|
wiki_path = File.join(fitnesse_path, wikify_path(feature_path))
|
185
188
|
# Fill ancestors of the wiki path with stubs for suites
|
186
|
-
create_suite_stubs(File.dirname(wiki_path))
|
189
|
+
create_suite_stubs(File.dirname(wiki_path), fitnesse_path)
|
187
190
|
# Convert the .feature to wikitext
|
188
191
|
content = feature_to_fitnesse(File.open(feature_path)).join("\n")
|
189
192
|
# Write the wikitext to a wiki page
|
@@ -243,17 +246,20 @@ module Cukable
|
|
243
246
|
# # FitNesseRoot/PageOne/PageTwo/content.txt
|
244
247
|
# # FitNesseRoot/PageOne/PageTwo/PageThree/content.txt
|
245
248
|
#
|
246
|
-
# @param [String]
|
249
|
+
# @param [String] wiki_path
|
247
250
|
# Directory name of deepest level in the wiki hierarchy where
|
248
251
|
# you want content stubs to be created
|
252
|
+
# @param [String] root_path
|
253
|
+
# FitNesseRoot directory--the stopping point in `wiki_path`'s
|
254
|
+
# ancestry, where no more content stubs will be created.
|
249
255
|
#
|
250
|
-
def create_suite_stubs(
|
256
|
+
def create_suite_stubs(wiki_path, root_path)
|
251
257
|
# Content string to put in each stub file
|
252
258
|
content = '!contents -R9 -p -f -h'
|
253
|
-
# Starting with `
|
254
|
-
path =
|
255
|
-
# Until
|
256
|
-
|
259
|
+
# Starting with `wiki_path`
|
260
|
+
path = wiki_path
|
261
|
+
# Until the root level is reached
|
262
|
+
until path == root_path || path == '.'
|
257
263
|
# If there is no content.txt file, create one
|
258
264
|
if !File.exists?(File.join(path, 'content.txt'))
|
259
265
|
create_wiki_page(path, content, 'suite')
|
data/lib/cukable/cuke.rb
CHANGED
@@ -35,6 +35,12 @@ module Cukable
|
|
35
35
|
@@last_suite_name = nil
|
36
36
|
|
37
37
|
|
38
|
+
# Execute a block inside `@project_dir`.
|
39
|
+
def in_project_dir(&block)
|
40
|
+
Dir.chdir(@project_dir, &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
|
38
44
|
# Create the fixture, with optional Cucumber command-line arguments.
|
39
45
|
#
|
40
46
|
# @param [String] cucumber_args
|
@@ -43,13 +49,17 @@ module Cukable
|
|
43
49
|
# test. Otherwise, the `cucumber_args` passed to `accelerate`
|
44
50
|
# take precedence.
|
45
51
|
#
|
46
|
-
def initialize(cucumber_args='')
|
47
|
-
#
|
52
|
+
def initialize(cucumber_args='', project_dir='')
|
53
|
+
# Path to where temporary .feature files will be written
|
54
|
+
# (relative to @project_dir)
|
48
55
|
@features_dir = File.join('features', 'fitnesse')
|
49
|
-
#
|
56
|
+
# Where JSON output files will be written by Cucumber
|
57
|
+
# (relative to @project_dir)
|
50
58
|
@output_dir = 'slim_results'
|
51
59
|
# Cucumber command-line arguments
|
52
|
-
@cucumber_args = cucumber_args
|
60
|
+
@cucumber_args = cucumber_args or ''
|
61
|
+
@project_dir = File.expand_path((project_dir or '.'))
|
62
|
+
ensure_directory(@project_dir)
|
53
63
|
end
|
54
64
|
|
55
65
|
|
@@ -67,10 +77,12 @@ module Cukable
|
|
67
77
|
# Command-line arguments to pass to Cucumber for this run.
|
68
78
|
# Affects all tests in the suite.
|
69
79
|
#
|
70
|
-
def accelerate(test_name, cucumber_args='')
|
80
|
+
def accelerate(test_name, cucumber_args='', project_dir='')
|
71
81
|
# Remove wiki cruft from the test_path
|
72
82
|
test_name = remove_cruft(test_name)
|
73
83
|
@cucumber_args = cucumber_args
|
84
|
+
@project_dir = File.expand_path((project_dir or '.'))
|
85
|
+
ensure_directory(@project_dir)
|
74
86
|
|
75
87
|
# Don't run the accelerator unless we're on a page called AaaAccelerator
|
76
88
|
if !(test_name =~ /^.*AaaAccelerator$/)
|
@@ -97,8 +109,10 @@ module Cukable
|
|
97
109
|
# two people are running different suites at the same time?
|
98
110
|
# The same suite at the same time?
|
99
111
|
[@features_dir, @output_dir].each do |dir|
|
100
|
-
|
101
|
-
|
112
|
+
in_project_dir do
|
113
|
+
FileUtils.rm_rf(dir)
|
114
|
+
FileUtils.mkdir(dir)
|
115
|
+
end
|
102
116
|
end
|
103
117
|
|
104
118
|
# Reset the digest-to-json map, then fill it in with the
|
@@ -106,8 +120,10 @@ module Cukable
|
|
106
120
|
@@output_files = Hash.new
|
107
121
|
|
108
122
|
# Write all .feature files and run Cucumber on them
|
109
|
-
|
110
|
-
|
123
|
+
in_project_dir do
|
124
|
+
feature_filenames = write_suite_features(suite)
|
125
|
+
run_cucumber(feature_filenames)
|
126
|
+
end
|
111
127
|
|
112
128
|
# Parse the results out over their sources.
|
113
129
|
return true # Wait for someone to test one of the same tables.
|
@@ -130,7 +146,9 @@ module Cukable
|
|
130
146
|
@features_dir, "#{feature}_#{number}.feature")
|
131
147
|
feature_filenames << feature_filename
|
132
148
|
begin
|
133
|
-
|
149
|
+
in_project_dir do
|
150
|
+
write_feature(table, feature_filename)
|
151
|
+
end
|
134
152
|
rescue FormatError => err
|
135
153
|
puts "!!!! Error writing #{feature_filename}:"
|
136
154
|
puts err.message
|
@@ -140,7 +158,7 @@ module Cukable
|
|
140
158
|
|
141
159
|
# Store the JSON filename in the digest hash
|
142
160
|
digest = table_digest(table)
|
143
|
-
json_filename = File.join(@output_dir, "#{feature_filename}.json")
|
161
|
+
json_filename = File.join(@project_dir, @output_dir, "#{feature_filename}.json")
|
144
162
|
@@output_files[digest] = json_filename
|
145
163
|
end
|
146
164
|
end
|
@@ -168,14 +186,14 @@ module Cukable
|
|
168
186
|
# Otherwise, run Cucumber from scratch on this table,
|
169
187
|
# and return the results
|
170
188
|
else
|
171
|
-
# FIXME: Move this to a separate method?
|
172
|
-
# Create @features_dir if it doesn't exist
|
173
|
-
FileUtils.mkdir(@features_dir) unless File.directory?(@features_dir)
|
174
189
|
feature_filename = File.join(@features_dir, 'fitnesse_test.feature')
|
175
190
|
# Create the feature file, run cucumber, return results
|
176
|
-
|
177
|
-
|
178
|
-
|
191
|
+
in_project_dir do
|
192
|
+
ensure_directory(@features_dir)
|
193
|
+
write_feature(table, feature_filename)
|
194
|
+
run_cucumber([feature_filename])
|
195
|
+
end
|
196
|
+
results = File.join(@project_dir, @output_dir, "#{feature_filename}.json")
|
179
197
|
end
|
180
198
|
|
181
199
|
# If the results file exists, parse it, merge with the original table,
|
@@ -243,7 +261,7 @@ module Cukable
|
|
243
261
|
got_feature = false
|
244
262
|
got_scenario = false
|
245
263
|
|
246
|
-
|
264
|
+
ensure_directory(@features_dir)
|
247
265
|
file = File.open(feature_filename, 'w')
|
248
266
|
|
249
267
|
# Error if there is not exactly one "Feature" row
|
@@ -277,22 +295,32 @@ module Cukable
|
|
277
295
|
|
278
296
|
|
279
297
|
# Run cucumber on `feature_filenames`, and output
|
280
|
-
# results in FitNesse table format to
|
298
|
+
# results in FitNesse table format to `@output_dir`.
|
281
299
|
#
|
282
300
|
# @param [Array] feature_filenames
|
283
301
|
# All `.feature` files to execute
|
284
|
-
# @param [String] output_dir
|
285
|
-
# Where to save the SlimJSON-formatted results
|
286
302
|
#
|
287
|
-
def run_cucumber(feature_filenames
|
288
|
-
|
303
|
+
def run_cucumber(feature_filenames)
|
304
|
+
# Tell cucumber to require the directory where this file lives,
|
305
|
+
# so it can find the SlimJSON formatter
|
306
|
+
lib = File.expand_path(File.dirname(__FILE__))
|
307
|
+
req = "--require #{lib} --require features"
|
289
308
|
format = "--format Cucumber::Formatter::SlimJSON"
|
290
|
-
output = "--out #{output_dir}"
|
309
|
+
output = "--out #{@output_dir}"
|
291
310
|
args = @cucumber_args
|
292
311
|
features = feature_filenames.join(" ")
|
312
|
+
cucumber_cmd = "#{cucumber_executable} #{req} #{format} #{output} #{args} #{features}"
|
293
313
|
|
294
|
-
|
295
|
-
|
314
|
+
|
315
|
+
in_project_dir do
|
316
|
+
# If project_dir contains an .rvmrc, wrap the command in a bash
|
317
|
+
# session that will use the correct environment
|
318
|
+
if File.exist?('.rvmrc')
|
319
|
+
cucumber_cmd = "bash -l -c 'source .rvmrc ; #{cucumber_cmd}' "
|
320
|
+
end
|
321
|
+
puts "Running: #{cucumber_cmd}"
|
322
|
+
system cucumber_cmd
|
323
|
+
end
|
296
324
|
|
297
325
|
# TODO: Ensure that the correct number of output files were written
|
298
326
|
#if !File.exist?(@results_filename)
|
@@ -300,6 +328,23 @@ module Cukable
|
|
300
328
|
#end
|
301
329
|
end
|
302
330
|
|
331
|
+
|
332
|
+
# Return the name of the cucumber executable. If `project_dir` contains a
|
333
|
+
# `Gemfile`, use `bundle exec cucumber`; otherwise, use `cucumber`.
|
334
|
+
def cucumber_executable
|
335
|
+
if File.exist?(File.join(@project_dir, 'Gemfile'))
|
336
|
+
return "bundle exec cucumber"
|
337
|
+
else
|
338
|
+
return "cucumber"
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
|
343
|
+
# Ensure that a directory `path` exists
|
344
|
+
def ensure_directory(path)
|
345
|
+
FileUtils.mkdir_p(path) unless File.directory?(path)
|
346
|
+
end
|
347
|
+
|
303
348
|
end
|
304
349
|
end
|
305
350
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cukable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 2
|
10
|
+
version: 0.1.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Eric Pierce
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-
|
19
|
+
date: 2011-07-09 00:00:00 -06:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -62,9 +62,25 @@ dependencies:
|
|
62
62
|
type: :runtime
|
63
63
|
version_requirements: *id003
|
64
64
|
- !ruby/object:Gem::Dependency
|
65
|
-
name:
|
65
|
+
name: rake
|
66
66
|
prerelease: false
|
67
67
|
requirement: &id004 !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ~>
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
hash: 49
|
73
|
+
segments:
|
74
|
+
- 0
|
75
|
+
- 8
|
76
|
+
- 7
|
77
|
+
version: 0.8.7
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rspec
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
68
84
|
none: false
|
69
85
|
requirements:
|
70
86
|
- - ">="
|
@@ -76,11 +92,11 @@ dependencies:
|
|
76
92
|
- 0
|
77
93
|
version: 2.2.0
|
78
94
|
type: :development
|
79
|
-
version_requirements: *
|
95
|
+
version_requirements: *id005
|
80
96
|
- !ruby/object:Gem::Dependency
|
81
97
|
name: rcov
|
82
98
|
prerelease: false
|
83
|
-
requirement: &
|
99
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
84
100
|
none: false
|
85
101
|
requirements:
|
86
102
|
- - ">="
|
@@ -90,11 +106,11 @@ dependencies:
|
|
90
106
|
- 0
|
91
107
|
version: "0"
|
92
108
|
type: :development
|
93
|
-
version_requirements: *
|
109
|
+
version_requirements: *id006
|
94
110
|
- !ruby/object:Gem::Dependency
|
95
111
|
name: yard
|
96
112
|
prerelease: false
|
97
|
-
requirement: &
|
113
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
98
114
|
none: false
|
99
115
|
requirements:
|
100
116
|
- - ">="
|
@@ -104,11 +120,11 @@ dependencies:
|
|
104
120
|
- 0
|
105
121
|
version: "0"
|
106
122
|
type: :development
|
107
|
-
version_requirements: *
|
123
|
+
version_requirements: *id007
|
108
124
|
- !ruby/object:Gem::Dependency
|
109
125
|
name: bluecloth
|
110
126
|
prerelease: false
|
111
|
-
requirement: &
|
127
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
112
128
|
none: false
|
113
129
|
requirements:
|
114
130
|
- - ">="
|
@@ -118,7 +134,7 @@ dependencies:
|
|
118
134
|
- 0
|
119
135
|
version: "0"
|
120
136
|
type: :development
|
121
|
-
version_requirements: *
|
137
|
+
version_requirements: *id008
|
122
138
|
description: " Cukable allows running Cucumber test scenarios from FitNesse\n"
|
123
139
|
email: wapcaplet88@gmail.com
|
124
140
|
executables:
|
@@ -128,9 +144,10 @@ extensions: []
|
|
128
144
|
extra_rdoc_files: []
|
129
145
|
|
130
146
|
files:
|
147
|
+
- .gitignore
|
131
148
|
- .yardopts
|
132
149
|
- Gemfile
|
133
|
-
-
|
150
|
+
- History.md
|
134
151
|
- README.md
|
135
152
|
- Rakefile
|
136
153
|
- bin/cuke2fit
|
data/Gemfile.lock
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
cukable (0.1.1)
|
5
|
-
cucumber
|
6
|
-
diff-lcs
|
7
|
-
json
|
8
|
-
|
9
|
-
GEM
|
10
|
-
remote: http://rubygems.org/
|
11
|
-
specs:
|
12
|
-
bluecloth (2.0.11)
|
13
|
-
builder (2.1.2)
|
14
|
-
cucumber (0.8.5)
|
15
|
-
builder (~> 2.1.2)
|
16
|
-
diff-lcs (~> 1.1.2)
|
17
|
-
gherkin (~> 2.1.4)
|
18
|
-
json_pure (~> 1.4.3)
|
19
|
-
term-ansicolor (~> 1.0.4)
|
20
|
-
diff-lcs (1.1.2)
|
21
|
-
gherkin (2.1.5)
|
22
|
-
trollop (~> 1.16.2)
|
23
|
-
json (1.5.1)
|
24
|
-
json_pure (1.4.6)
|
25
|
-
rcov (0.9.9)
|
26
|
-
rspec (2.5.0)
|
27
|
-
rspec-core (~> 2.5.0)
|
28
|
-
rspec-expectations (~> 2.5.0)
|
29
|
-
rspec-mocks (~> 2.5.0)
|
30
|
-
rspec-core (2.5.1)
|
31
|
-
rspec-expectations (2.5.0)
|
32
|
-
diff-lcs (~> 1.1.2)
|
33
|
-
rspec-mocks (2.5.0)
|
34
|
-
term-ansicolor (1.0.5)
|
35
|
-
trollop (1.16.2)
|
36
|
-
yard (0.6.4)
|
37
|
-
|
38
|
-
PLATFORMS
|
39
|
-
ruby
|
40
|
-
|
41
|
-
DEPENDENCIES
|
42
|
-
bluecloth
|
43
|
-
bundler (~> 1.0)
|
44
|
-
cukable!
|
45
|
-
rcov
|
46
|
-
rspec (>= 2.2.0)
|
47
|
-
yard
|