cukable 0.1.1 → 0.1.2
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 +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
|