cukehead 0.1.1
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/LICENSE +20 -0
- data/README +55 -0
- data/Rakefile +101 -0
- data/bin/cukehead +7 -0
- data/lib/cukehead.rb +1 -0
- data/lib/cukehead/app.rb +241 -0
- data/lib/cukehead/feature_file_section.rb +73 -0
- data/lib/cukehead/feature_node.rb +111 -0
- data/lib/cukehead/feature_node_child.rb +58 -0
- data/lib/cukehead/feature_node_tags.rb +41 -0
- data/lib/cukehead/feature_part.rb +25 -0
- data/lib/cukehead/feature_reader.rb +78 -0
- data/lib/cukehead/feature_writer.rb +42 -0
- data/lib/cukehead/freemind_builder.rb +184 -0
- data/lib/cukehead/freemind_reader.rb +69 -0
- data/lib/cukehead/freemind_writer.rb +21 -0
- data/spec/app_spec.rb +275 -0
- data/spec/cukehead_spec.rb +104 -0
- data/spec/feature_file_section_spec.rb +93 -0
- data/spec/feature_node_spec.rb +115 -0
- data/spec/feature_part_spec.rb +37 -0
- data/spec/feature_reader_spec.rb +33 -0
- data/spec/feature_writer_spec.rb +73 -0
- data/spec/freemind_builder_spec.rb +91 -0
- data/spec/freemind_reader_spec.rb +62 -0
- data/spec/freemind_writer_spec.rb +25 -0
- data/spec/spec_helper.rb +88 -0
- metadata +93 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'cukehead/feature_file_section'
|
3
|
+
|
4
|
+
module Cukehead
|
5
|
+
|
6
|
+
describe "FeatureFileSection" do
|
7
|
+
|
8
|
+
it "should take a FreemindBuilder and a title as parameters when creating a new instance" do
|
9
|
+
builder = FreemindBuilder.new
|
10
|
+
title = "Feature: A test"
|
11
|
+
section = FeatureFileSection.new builder, title
|
12
|
+
section.should_not be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# it "should accept a line of text" do
|
16
|
+
# section = FeatureFileSection.new FakeFreemindBuilder.new, "Feature: A test"
|
17
|
+
# section.add "A line"
|
18
|
+
# section.finish
|
19
|
+
# section.lines.should have(1).line
|
20
|
+
# end
|
21
|
+
|
22
|
+
it "should have 'add', 'set_tags', and 'finish' methods" do
|
23
|
+
section = FeatureFileSection.new FakeFreemindBuilder.new, "Feature: A test"
|
24
|
+
section.should respond_to "add", "set_tags", "finish"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "is a base class and should raise an exception if the 'finish' method is called" do
|
28
|
+
section = FeatureFileSection.new FakeFreemindBuilder.new, "Feature: A test"
|
29
|
+
lambda{ section.finish }.should raise_exception
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "FeatureSection" do
|
35
|
+
|
36
|
+
it "should take a FreemindBuilder, a title, and a filename as parameters when creating a new instance" do
|
37
|
+
builder = FreemindBuilder.new
|
38
|
+
title = "Feature: A test"
|
39
|
+
filename = "test.feature"
|
40
|
+
section = FeatureSection.new builder, title, filename
|
41
|
+
section.should_not be_nil
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be a FeatureFileSection" do
|
45
|
+
section = FeatureSection.new FakeFreemindBuilder.new, "Feature: A test", "test.feature"
|
46
|
+
section.should be_a FeatureFileSection
|
47
|
+
end
|
48
|
+
|
49
|
+
it "implements the 'finish' method" do
|
50
|
+
fakebuilder = FakeFreemindBuilder.new
|
51
|
+
section = FeatureSection.new fakebuilder, "Feature: A test", "test.feature"
|
52
|
+
section.add "A line"
|
53
|
+
section.finish
|
54
|
+
fakebuilder.lines.should have(1).line
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "BackgroundSection" do
|
60
|
+
|
61
|
+
it "should be a FeatureFileSection" do
|
62
|
+
section = BackgroundSection.new FakeFreemindBuilder.new, "Feature: A test"
|
63
|
+
section.should be_a FeatureFileSection
|
64
|
+
end
|
65
|
+
|
66
|
+
it "implements the 'finish' method" do
|
67
|
+
fakebuilder = FakeFreemindBuilder.new
|
68
|
+
section = BackgroundSection.new fakebuilder, "Feature: A test"
|
69
|
+
section.add "A line"
|
70
|
+
section.finish
|
71
|
+
fakebuilder.lines.should have(1).line
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "ScenarioSection" do
|
77
|
+
|
78
|
+
it "should be a FeatureFileSection" do
|
79
|
+
section = ScenarioSection.new FakeFreemindBuilder.new, "Feature: A test"
|
80
|
+
section.should be_a FeatureFileSection
|
81
|
+
end
|
82
|
+
|
83
|
+
it "implements the 'finish' method" do
|
84
|
+
fakebuilder = FakeFreemindBuilder.new
|
85
|
+
section = ScenarioSection.new fakebuilder, "Feature: A test"
|
86
|
+
section.add "A line"
|
87
|
+
section.finish
|
88
|
+
fakebuilder.lines.should have(1).line
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'cukehead/feature_node'
|
4
|
+
|
5
|
+
module Cukehead
|
6
|
+
|
7
|
+
describe "FeatureNodeTags" do
|
8
|
+
|
9
|
+
it "extracts tags from text" do
|
10
|
+
@fntags = FeatureNodeTags.new
|
11
|
+
text = "tags: @tag1 @tag2"
|
12
|
+
@fntags.from_text text
|
13
|
+
@fntags.should_not be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns tags as a string padded for output" do
|
17
|
+
@fntags = FeatureNodeTags.new
|
18
|
+
text = "tags: @tag1 @tag2"
|
19
|
+
@fntags.from_text text
|
20
|
+
@fntags.to_text(' ').should eql " @tag1 @tag2\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
describe "FeatureNodeChild" do
|
27
|
+
|
28
|
+
before do
|
29
|
+
@xml = $testing_freemind_data
|
30
|
+
end
|
31
|
+
|
32
|
+
it "populates itself from a FreeMind XML document node that is a child of a feature node" do
|
33
|
+
doc = REXML::Document.new @xml
|
34
|
+
node = REXML::XPath.first doc, '//node[attribute::TEXT="Scenario: Sites List"]'
|
35
|
+
feature_node_child = FeatureNodeChild.new node
|
36
|
+
feature_node_child.should_not be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns a text representation of itself padded for output to a Cucumber feature file" do
|
40
|
+
doc = REXML::Document.new @xml
|
41
|
+
node = REXML::XPath.first doc, '//node[attribute::TEXT="Scenario: Sites List"]'
|
42
|
+
feature_node_child = FeatureNodeChild.new node
|
43
|
+
feature_node_child.to_text(' ').should match /^\ \ Scenario:.*/m
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
describe "FeatureNode" do
|
50
|
+
|
51
|
+
before do
|
52
|
+
@xml = <<xxx
|
53
|
+
<map>
|
54
|
+
<node TEXT='Cucumber features:'>
|
55
|
+
<node TEXT='Feature: Test feature'>
|
56
|
+
<node TEXT='As a test'/>
|
57
|
+
<node TEXT='I want to pass'/>
|
58
|
+
</node>
|
59
|
+
</node>
|
60
|
+
</map>
|
61
|
+
xxx
|
62
|
+
|
63
|
+
@xml_with_filename = <<xxx
|
64
|
+
<map>
|
65
|
+
<node TEXT='Cucumber features:'>
|
66
|
+
<node TEXT='Feature: Test feature'>
|
67
|
+
<node TEXT='[file: my_filename.feature]'/>
|
68
|
+
</node>
|
69
|
+
</node>
|
70
|
+
</map>
|
71
|
+
xxx
|
72
|
+
|
73
|
+
doc = REXML::Document.new @xml
|
74
|
+
node = REXML::XPath.first doc, '//node[attribute::TEXT="Feature: Test feature"]'
|
75
|
+
@feature_node = FeatureNode.new(node)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "populates itself from a XML document node describing a Cucumber feature" do
|
79
|
+
doc = REXML::Document.new @xml
|
80
|
+
node = REXML::XPath.first doc, '//node[attribute::TEXT="Feature: Test feature"]'
|
81
|
+
feat = FeatureNode.new(node)
|
82
|
+
feat.should_not be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "returns the file name for the feature as specified in the document" do
|
86
|
+
doc = REXML::Document.new @xml_with_filename
|
87
|
+
node = REXML::XPath.first doc, '//node[attribute::TEXT="Feature: Test feature"]'
|
88
|
+
feat = FeatureNode.new(node)
|
89
|
+
feat.filename.should eql 'my_filename.feature'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "creates a file name if none was specified based on the feature title" do
|
93
|
+
doc = REXML::Document.new @xml
|
94
|
+
node = REXML::XPath.first doc, '//node[attribute::TEXT="Feature: Test feature"]'
|
95
|
+
feat = FeatureNode.new(node)
|
96
|
+
feat.filename.should eql 'test_feature.feature'
|
97
|
+
end
|
98
|
+
|
99
|
+
it "has a method to return a file name from text in the mind map specifying the file name" do
|
100
|
+
@feature_node.filename_from('').should eql ''
|
101
|
+
@feature_node.filename_from('[file: filename.feature]').should eql 'filename.feature'
|
102
|
+
@feature_node.filename_from('[file: "filename.feature"]').should eql 'filename.feature'
|
103
|
+
@feature_node.filename_from('[file:filename.feature]').should eql 'filename.feature'
|
104
|
+
@feature_node.filename_from('[file:"filename.feature"]').should eql 'filename.feature'
|
105
|
+
@feature_node.filename_from('[ File: " filename.feature " ] ').should eql 'filename.feature'
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
it "returns itself in Cucumber feature file format as a single string of text" do
|
110
|
+
@feature_node.to_text.should eql "Feature: Test feature\n As a test\n I want to pass\n\n"
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'cukehead/feature_part'
|
3
|
+
|
4
|
+
module Cukehead
|
5
|
+
|
6
|
+
describe "FeaturePart" do
|
7
|
+
before do
|
8
|
+
@part = FeaturePart.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should have a 'title' attribute" do
|
12
|
+
s = "Feature: Test feature"
|
13
|
+
@part.title = s
|
14
|
+
@part.title.should == s
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should let you add lines and have a 'lines' attribute reader" do
|
18
|
+
a = ["In order describe a feature", "As a feature object", "I want to have lines of text"]
|
19
|
+
a.each {|line| @part.add_line(line)}
|
20
|
+
@part.lines.should == a
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have a 'tags' attribute" do
|
24
|
+
a = ["@test"]
|
25
|
+
@part.tags = a
|
26
|
+
@part.tags.should == a
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should take the title as a parameter when creating a new instance" do
|
30
|
+
s = "A feature part"
|
31
|
+
part = FeaturePart.new s
|
32
|
+
part.title.should == s
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'cukehead/feature_reader'
|
3
|
+
|
4
|
+
module Cukehead
|
5
|
+
|
6
|
+
describe "FeatureReader" do
|
7
|
+
|
8
|
+
before do
|
9
|
+
#@filename1 = File.expand_path(File.join(File.dirname(__FILE__), "..", "tmp/test-1.feature"))
|
10
|
+
@filename1 = File.join($testing_tmp, "test-1.feature")
|
11
|
+
@filetext1 = "Feature: A test"
|
12
|
+
#$stderr.puts "DEBUG: @filename1='#{@filename1}'"
|
13
|
+
FileUtils.mkdir($testing_tmp) unless File.directory? $testing_tmp
|
14
|
+
File.open(@filename1, 'w') do |f|
|
15
|
+
f.write(@filetext1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "extracts feature sections from the text of a Cucumber feature file" do
|
20
|
+
reader = FeatureReader.new
|
21
|
+
reader.extract_features @filename1, @filetext1
|
22
|
+
xml = reader.freemind_xml
|
23
|
+
xml.should match /.*Cucumber features:.*Feature: A test.*/
|
24
|
+
end
|
25
|
+
|
26
|
+
it "Optionally takes a string containing XML to pass to the FreemindBuilder" do
|
27
|
+
xml = "<map><node TEXT='A Mind Map'/></map>"
|
28
|
+
reader = FeatureReader.new(xml)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'cukehead/feature_writer'
|
3
|
+
|
4
|
+
module Cukehead
|
5
|
+
|
6
|
+
describe "FeatureWriter" do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@features = {
|
10
|
+
"test1.feature" => "Feature: Test 1",
|
11
|
+
"test2.feature" => "Feature: Test 2"
|
12
|
+
}
|
13
|
+
@writer = FeatureWriter.new
|
14
|
+
@outdir = File.join($testing_tmp, 'feature_writer_test', 'features')
|
15
|
+
FileUtils.remove_dir(@outdir) if File.directory? @outdir
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it "writes to a subdirectory named 'features' in the current directory by default" do
|
20
|
+
@writer.output_path.should eql File.join(Dir.getwd, 'features')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
it "has an output directory attribute that can be set" do
|
25
|
+
@writer.output_path = @outdir
|
26
|
+
@writer.output_path.should eql @outdir
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
it "takes a hash of filename => featuretext and writes feature files" do
|
31
|
+
@writer.output_path = @outdir
|
32
|
+
@writer.write_features(@features)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
it "does not overwrite existing files by default" do
|
37
|
+
fn = File.join(@outdir, 'test1.feature')
|
38
|
+
FileUtils.mkdir_p @outdir
|
39
|
+
File.open(fn, 'w') {|f| f.write('###')}
|
40
|
+
File.exists?(fn).should be_true
|
41
|
+
@writer.output_path = @outdir
|
42
|
+
@writer.write_features(@features)
|
43
|
+
@writer.errors.should have(1).items
|
44
|
+
File.open(fn, 'r') {|f|
|
45
|
+
s = f.readline
|
46
|
+
s.should eql "###"
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
it "has an overwrite attribute that can be set" do
|
52
|
+
@writer.overwrite = true
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
it "overwrites existing files if the overwrite attrubute is set to true" do
|
57
|
+
fn = File.join(@outdir, 'test1.feature')
|
58
|
+
FileUtils.mkdir_p @outdir
|
59
|
+
File.open(fn, 'w') {|f| f.write('###')}
|
60
|
+
File.exists?(fn).should be_true
|
61
|
+
@writer.output_path = @outdir
|
62
|
+
@writer.overwrite = true
|
63
|
+
@writer.write_features(@features)
|
64
|
+
@writer.errors.should have(0).items
|
65
|
+
File.open(fn, 'r') {|f|
|
66
|
+
s = f.readline
|
67
|
+
s.should eql "Feature: Test 1"
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'cukehead/feature_part'
|
3
|
+
require 'cukehead/freemind_builder'
|
4
|
+
|
5
|
+
module Cukehead
|
6
|
+
|
7
|
+
describe "FreemindBuilder" do
|
8
|
+
before do
|
9
|
+
@builder = FreemindBuilder.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should specify a XML node for Cucumber features" do
|
13
|
+
node = @builder.send :cucumber_features_node
|
14
|
+
node.should be_a REXML::Element
|
15
|
+
node.to_s.should match /.*Cucumber features:.*/
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should use an existing node labelled 'Cucumber features:' if there is one" do
|
19
|
+
mm = "<map version='0.7.1'><node TEXT='mind map'><node TEXT='A child node'><node TEXT='Cucumber features:'></node></node></node></map>"
|
20
|
+
b = FreemindBuilder.new mm
|
21
|
+
node = b.send :cucumber_features_node
|
22
|
+
node.should be_a REXML::Element
|
23
|
+
xml = b.xml
|
24
|
+
doc = REXML::Document.new(xml)
|
25
|
+
doc.should_not be_nil
|
26
|
+
node = REXML::XPath.first(doc, '//node[attribute::TEXT="A child node"]')
|
27
|
+
node.should_not be_nil
|
28
|
+
child = node.elements.first
|
29
|
+
child.to_s.should match /.*Cucumber features:.*/
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should save the path to the features directory" do
|
33
|
+
filename = '/tmp/features/some.feature'
|
34
|
+
@builder.send :add_features_path, filename
|
35
|
+
result = @builder.send :features_path_text
|
36
|
+
result.should eql "[path: /tmp/features]"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should create new XML node element with text, color, and folded attributes" do
|
40
|
+
text = "Test node"
|
41
|
+
color = "blue"
|
42
|
+
folded = true
|
43
|
+
node = @builder.send :new_node_element, text, color, folded
|
44
|
+
node.should be_a REXML::Element
|
45
|
+
node.to_s.should eql "<node FOLDED='true' TEXT='Test node' COLOR='blue'/>"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should add a feature and specify the name of the file it is from" do
|
49
|
+
feature = FeaturePart.new
|
50
|
+
feature.title = "Feature: Test feature"
|
51
|
+
filename = "test.feature"
|
52
|
+
@builder.add_feature feature, filename
|
53
|
+
@builder.xml.should match /.*Test feature.*/
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should include lines and tags attributes in the XML output" do
|
57
|
+
feature = FeaturePart.new "Feature: Test feature"
|
58
|
+
feature.add_line "As a test"
|
59
|
+
feature.add_line "I want to add some lines of text"
|
60
|
+
feature.add_line "In order to make sure I can"
|
61
|
+
feature.tags << "@test"
|
62
|
+
@builder.add_feature feature, "test.feature"
|
63
|
+
@builder.xml.should match /.*Test feature.*\@test.*As a test.*/
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should add a Background part to the current feature" do
|
67
|
+
feature = FeaturePart.new "Feature: Test feature"
|
68
|
+
@builder.add_feature feature, "test.feature"
|
69
|
+
bg = FeaturePart.new "Background:"
|
70
|
+
bg.add_line "Given this thingy"
|
71
|
+
bg.add_line "And that other thingy"
|
72
|
+
bg.tags << "@test"
|
73
|
+
@builder.add_background bg
|
74
|
+
@builder.xml.should match /.*Test feature.*Background:.*\@test.*thingy.*/
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should add a Scenario section to the current feature" do
|
78
|
+
feature = FeaturePart.new "Feature: Test feature"
|
79
|
+
@builder.add_feature feature, "test.feature"
|
80
|
+
sc = FeaturePart.new "Scenario: Test a scenario"
|
81
|
+
sc.add_line "Given I am a scenario part"
|
82
|
+
sc.add_line "When I am added to a FreemindBuilder"
|
83
|
+
sc.add_line "Then I should see myself in the output."
|
84
|
+
sc.tags << "@test"
|
85
|
+
@builder.add_scenario sc
|
86
|
+
@builder.xml.should match /.*Test feature.*Scenario:.*\@test.*in the output.*/
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|