germinate 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/History.txt +26 -0
- data/README.rdoc +152 -0
- data/Rakefile +43 -0
- data/TODO +140 -0
- data/bin/germ +260 -0
- data/cucumber.yml +2 -0
- data/examples/basic.rb +123 -0
- data/examples/short.rb +19 -0
- data/features/author-formats-article.feature +111 -0
- data/features/author-lists-info.pending_feature +48 -0
- data/features/author-publishes-article-source.feature +5 -0
- data/features/author-publishes-article.feature +57 -0
- data/features/author-republishes-article.feature +5 -0
- data/features/author-selects-hunks.feature +26 -0
- data/features/author-sets-variables.feature +88 -0
- data/features/author-updates-article-source.feature +5 -0
- data/features/author-views-stuff.pending_feature +52 -0
- data/features/bin/quoter +6 -0
- data/features/bin/sorter +4 -0
- data/features/example_articles/bracketing.rb +27 -0
- data/features/example_articles/escaping.txt +13 -0
- data/features/example_articles/excerpt_output.rb +16 -0
- data/features/example_articles/hello.rb +9 -0
- data/features/example_articles/pipelines.txt +25 -0
- data/features/example_articles/regexen.rb +24 -0
- data/features/example_articles/sample_offsets.rb +18 -0
- data/features/example_articles/specials.rb +19 -0
- data/features/example_articles/stderr.rb +10 -0
- data/features/example_articles/wrapping.rb +8 -0
- data/features/example_output/bracketing.out +23 -0
- data/features/example_output/code_samples.txt +186 -0
- data/features/example_output/escaping.out +5 -0
- data/features/example_output/excerpt_output.out +6 -0
- data/features/example_output/hello.txt +1 -0
- data/features/example_output/pipelines.out +28 -0
- data/features/example_output/regexen.txt +22 -0
- data/features/example_output/sample_offsets.txt +15 -0
- data/features/example_output/specials.txt +40 -0
- data/features/example_output/stderr.out +3 -0
- data/features/example_output/wrapping.txt +3 -0
- data/features/step_definitions/germinate.rb +42 -0
- data/features/support/env.rb +20 -0
- data/germinate.gemspec +55 -0
- data/lib/germinate.rb +54 -0
- data/lib/germinate/application.rb +113 -0
- data/lib/germinate/article_editor.rb +20 -0
- data/lib/germinate/formatter.rb +119 -0
- data/lib/germinate/hunk.rb +183 -0
- data/lib/germinate/implicit_insertion.rb +9 -0
- data/lib/germinate/insertion.rb +29 -0
- data/lib/germinate/librarian.rb +293 -0
- data/lib/germinate/origin.rb +5 -0
- data/lib/germinate/pipeline.rb +13 -0
- data/lib/germinate/publisher.rb +57 -0
- data/lib/germinate/reader.rb +266 -0
- data/lib/germinate/selector.rb +136 -0
- data/lib/germinate/shared_style_attributes.rb +54 -0
- data/lib/germinate/shell_process.rb +94 -0
- data/lib/germinate/shell_publisher.rb +19 -0
- data/lib/germinate/simple_publisher.rb +7 -0
- data/lib/germinate/source_file.rb +41 -0
- data/lib/germinate/text_transforms.rb +119 -0
- data/lib/germinate/transform_process.rb +25 -0
- data/lib/germinate/variable.rb +23 -0
- data/sample.rb +14 -0
- data/spec/germinate/application_spec.rb +31 -0
- data/spec/germinate/article_editor_spec.rb +97 -0
- data/spec/germinate/code_hunk_spec.rb +73 -0
- data/spec/germinate/file_hunk_spec.rb +28 -0
- data/spec/germinate/formatter_spec.rb +160 -0
- data/spec/germinate/hunk_spec.rb +84 -0
- data/spec/germinate/implicit_insertion_spec.rb +33 -0
- data/spec/germinate/insertion_spec.rb +19 -0
- data/spec/germinate/librarian_spec.rb +555 -0
- data/spec/germinate/pipeline_spec.rb +34 -0
- data/spec/germinate/process_spec.rb +105 -0
- data/spec/germinate/publisher_spec.rb +130 -0
- data/spec/germinate/reader_spec.rb +385 -0
- data/spec/germinate/selector_spec.rb +121 -0
- data/spec/germinate/shell_publisher_spec.rb +61 -0
- data/spec/germinate/source_file_spec.rb +99 -0
- data/spec/germinate/text_hunk_spec.rb +98 -0
- data/spec/germinate/text_transforms_spec.rb +242 -0
- data/spec/germinate/transform_process_spec.rb +50 -0
- data/spec/germinate/variable_spec.rb +14 -0
- data/spec/germinate_spec.rb +8 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +16 -0
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/cucumber.rake +5 -0
- data/tasks/gem.rake +201 -0
- data/tasks/git.rake +40 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +34 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +292 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/tasks/zentest.rake +36 -0
- data/test/test_germinate.rb +0 -0
- metadata +228 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path(
|
2
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
3
|
+
|
4
|
+
module Germinate
|
5
|
+
describe CodeHunk do
|
6
|
+
before :each do
|
7
|
+
@it = CodeHunk.new(["foo", "bar"])
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should disable line joining" do
|
11
|
+
@it.should_not be_join_lines
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should enable blank stripping" do
|
15
|
+
@it.should be_strip_blanks
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should disable comment erasure" do
|
19
|
+
@it.should_not be_erase_comments
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should disable uncommenting" do
|
23
|
+
@it.should_not be_uncomment
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should disable stripping right-side whitespace" do
|
27
|
+
@it.should_not be_rstrip_lines
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should enable bracketing" do
|
31
|
+
@it.should be_bracket
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should enable pipeline processing" do
|
35
|
+
@it.should be_pipeline
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when visited by a formatter" do
|
39
|
+
before :each do
|
40
|
+
@formatter = stub("Formatter")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should call #formate_code! for self" do
|
44
|
+
@formatter.should_receive(:format_code!).with(@it, anything)
|
45
|
+
@it.format_with(@formatter)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "with a nested hunk" do
|
50
|
+
before :each do
|
51
|
+
@formatter = stub("Formatter")
|
52
|
+
@comment_prefix = ">>"
|
53
|
+
@nested_hunk = stub("Nested Hunk", :empty? => false)
|
54
|
+
contents = [
|
55
|
+
"foo",
|
56
|
+
"bar",
|
57
|
+
@nested_hunk,
|
58
|
+
"baz"
|
59
|
+
]
|
60
|
+
@it = CodeHunk.new(contents,
|
61
|
+
:comment_prefix => @comment_prefix)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should pass formatter on to nested hunks" do
|
65
|
+
@formatter.should_receive(:format_code!).with(["foo", "bar"], ">>").ordered
|
66
|
+
@nested_hunk.should_receive(:format_with).with(@formatter).ordered
|
67
|
+
@formatter.should_receive(:format_code!).with(["baz"], ">>").ordered
|
68
|
+
@it.format_with(@formatter)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(
|
2
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
3
|
+
|
4
|
+
module Germinate
|
5
|
+
describe FileHunk do
|
6
|
+
before :each do
|
7
|
+
@it = FileHunk.new(["foo", "bar"], {:source_path => "SOURCE_PATH"})
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should know its source path" do
|
11
|
+
@it.source_path.to_s.should == "SOURCE_PATH"
|
12
|
+
end
|
13
|
+
|
14
|
+
specify { @it.should be_whole_file }
|
15
|
+
|
16
|
+
context "when visited by a formatter" do
|
17
|
+
before :each do
|
18
|
+
@formatter = stub("Formatter")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should call #formate_code! for self" do
|
22
|
+
@formatter.should_receive(:format_code!).with(@it, anything)
|
23
|
+
@it.format_with(@formatter)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require File.expand_path(
|
2
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
3
|
+
|
4
|
+
module Germinate
|
5
|
+
describe Formatter do
|
6
|
+
before :each do
|
7
|
+
@output = StringIO.new
|
8
|
+
@it = Formatter.new(@output)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should start in the :initial state" do
|
12
|
+
@it.state.should == :initial
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def output_string
|
17
|
+
@output.rewind
|
18
|
+
@output.string
|
19
|
+
end
|
20
|
+
|
21
|
+
context "which has been started" do
|
22
|
+
before :each do
|
23
|
+
@it.start!
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be in the :code state" do
|
27
|
+
@it.state.should == :code
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should ignore initial lines" do
|
31
|
+
@it.add_line!("TEST")
|
32
|
+
output_string.should == ""
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
context "after the :TEXT: keyword" do
|
38
|
+
before :each do
|
39
|
+
@it.start!
|
40
|
+
@it.add_line!(":TEXT:\n")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be in the :paragraph state" do
|
44
|
+
@it.state.should == :paragraph
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should start outputting text" do
|
48
|
+
@it.add_line!("check 1 2 3\n")
|
49
|
+
@it.add_line!("\n")
|
50
|
+
output_string.should == "check 1 2 3\n"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "after the :TEXT: keyword followed by :CUT:" do
|
55
|
+
before :each do
|
56
|
+
@it.start!
|
57
|
+
@it.add_line!(":TEXT:\n")
|
58
|
+
@it.add_line!(":CUT:\n")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be in the :code state" do
|
62
|
+
@it.state.should == :code
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should stop outputting text" do
|
66
|
+
@it.add_line!("check 1 2 3\n")
|
67
|
+
output_string.should == ""
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "after a :TEXT: keyword prefixed with '#'" do
|
72
|
+
before :each do
|
73
|
+
@it.start!
|
74
|
+
@it.add_line!("# :TEXT:\n")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be in the :paragraph state" do
|
78
|
+
@it.state.should == :paragraph
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have a comment prefix of '#'" do
|
82
|
+
@it.comment_prefix.should == '#'
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should strip '#' prefixes from text" do
|
86
|
+
@it.add_line!("# Line 1\n")
|
87
|
+
@it.add_line!(" ## Line 2\n")
|
88
|
+
@it.add_line!("\n")
|
89
|
+
output_string.should == "Line 1 Line 2\n"
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should ignore uncommented lines" do
|
93
|
+
@it.add_line!("; Not a comment #")
|
94
|
+
output_string.should == ""
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should ignore blank lines" do
|
98
|
+
@it.add_line!(" \t\n")
|
99
|
+
output_string.should == ""
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should ignore commented blank lines" do
|
103
|
+
@it.add_line!("# \t\n")
|
104
|
+
output_string.should == ""
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "after a :TEXT: keyword prefixed with ';'" do
|
109
|
+
before :each do
|
110
|
+
@it.start!
|
111
|
+
@it.add_line!(" ; :TEXT:\n")
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should have a comment prefix of ';'" do
|
115
|
+
@it.comment_prefix.should == ';'
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should strip ';' prefixes from text" do
|
119
|
+
@it.add_line!("; Line 1\n")
|
120
|
+
@it.add_line!(" ;; Line 2\n")
|
121
|
+
@it.add_line!(";\n")
|
122
|
+
output_string.should == "Line 1 Line 2\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should ignore lines with '#' prefixes" do
|
126
|
+
@it.add_line!("# Line 1\n")
|
127
|
+
output_string.should == ""
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "in a text section " do
|
132
|
+
before :each do
|
133
|
+
@it.start!
|
134
|
+
@it.add_line!("# :TEXT:\n")
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should join adjacent lines" do
|
138
|
+
@it.add_line!("# foo\n")
|
139
|
+
@it.add_line!("# bar\n")
|
140
|
+
@it.add_line!("\n")
|
141
|
+
output_string.should == "foo bar\n"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "in a linebreak section" do
|
146
|
+
before :each do
|
147
|
+
@it.start!
|
148
|
+
@it.add_line!("# :TEXT:\n")
|
149
|
+
@it.add_line!("# P1\n")
|
150
|
+
@it.add_line!("\n")
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should finish the section with a double newline" do
|
154
|
+
@it.add_line!("# P2\n")
|
155
|
+
@it.add_line!("\n")
|
156
|
+
output_string.should == "P1\n\nP2\n"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.expand_path(
|
2
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
3
|
+
|
4
|
+
module Germinate
|
5
|
+
describe Hunk, "(attributes)" do
|
6
|
+
Germinate::SharedStyleAttributes.fattrs.each do |attribute|
|
7
|
+
it "should support the #{attribute} style attribute" do
|
8
|
+
@it = Germinate::Hunk.new([], attribute => "test")
|
9
|
+
@it.send(attribute).should == "test"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should pass the #{attribute} attribute on to duplicates" do
|
13
|
+
@it = Germinate::Hunk.new([], attribute => "test")
|
14
|
+
@it.dup.send(attribute).should == "test"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should pass the #{attribute} attribute on to clones" do
|
18
|
+
@it = Germinate::Hunk.new([], attribute => "test")
|
19
|
+
@it.clone.send(attribute).should == "test"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should pass the #{attribute} attribute on to slices" do
|
23
|
+
@it = Germinate::Hunk.new([], attribute => "test")
|
24
|
+
@it[0..-1].send(attribute).should == "test"
|
25
|
+
@it.slice(0..-1).send(attribute).should == "test"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should copy #{attribute} from given template" do
|
29
|
+
@template = Object.new
|
30
|
+
@template.extend SharedStyleAttributes
|
31
|
+
@template.send(attribute, "test")
|
32
|
+
@it = Germinate::Hunk.new([], @template)
|
33
|
+
@it.send(attribute).should == "test"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
describe Hunk do
|
40
|
+
before :each do
|
41
|
+
@it = Hunk.new
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not have a source path" do
|
45
|
+
@it.source_path.should be_nil
|
46
|
+
end
|
47
|
+
|
48
|
+
specify { @it.should_not be_whole_file }
|
49
|
+
|
50
|
+
context "with an insertion" do
|
51
|
+
before :each do
|
52
|
+
@nested_hunk = stub("Nested Hunk")
|
53
|
+
@insertion = stub("Insertion", :resolve => @nested_hunk)
|
54
|
+
@it << "line 1"
|
55
|
+
@it << @insertion
|
56
|
+
@it << "line 2"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be able to resolve the insertion" do
|
60
|
+
@it.resolve_insertions.should == [
|
61
|
+
"line 1",
|
62
|
+
@nested_hunk,
|
63
|
+
"line 2"
|
64
|
+
]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "with some content" do
|
69
|
+
before :each do
|
70
|
+
@it.push("foo", "bar", "foo", "baz")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should be able to find indexes of elements matching a regex" do
|
74
|
+
@it.index_matching(/ba/).should == 1
|
75
|
+
@it.index_matching(/fo/).should == 0
|
76
|
+
@it.index_matching(/fo/, 1).should == 2
|
77
|
+
@it.index_matching(/fo/, 2).should == 2
|
78
|
+
@it.index_matching(/fo/, 3).should be_nil
|
79
|
+
@it.index_matching(/za/, 3).should be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path(
|
2
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
3
|
+
|
4
|
+
module Germinate
|
5
|
+
describe ImplicitInsertion do
|
6
|
+
before :each do
|
7
|
+
@hunk = stub("Hunk").as_null_object
|
8
|
+
@library = stub("Library")
|
9
|
+
@selector = stub("Selector")
|
10
|
+
@it = Germinate::ImplicitInsertion.new(@selector, @library)
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when the librarian can find the selection" do
|
14
|
+
before :each do
|
15
|
+
@library.stub!(:[]).and_return(@hunk)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should resolve to the hunk the librarian returns" do
|
19
|
+
@it.resolve.should equal(@hunk)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when the librarian cannot find the selection" do
|
24
|
+
before :each do
|
25
|
+
@library.stub!(:[]).and_raise(IndexError.new)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should resolve to a null hunk" do
|
29
|
+
@it.resolve.should be_a_kind_of(NullHunk)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path(
|
2
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
3
|
+
|
4
|
+
module Germinate
|
5
|
+
describe Insertion, "given a library and a selector" do
|
6
|
+
before :each do
|
7
|
+
@hunk = stub("Hunk").as_null_object
|
8
|
+
@library = stub("Library", :[] => @hunk)
|
9
|
+
@selector = stub("Selector")
|
10
|
+
@it = Germinate::Insertion.new(@selector, @library, {})
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should use the library to resolve itself" do
|
14
|
+
@library.should_receive(:[]).
|
15
|
+
with(@selector, anything, anything).and_return(@hunk)
|
16
|
+
@it.resolve.should == @hunk
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,555 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'arrayfields'
|
3
|
+
|
4
|
+
require File.expand_path(
|
5
|
+
File.join(File.dirname(__FILE__), %w[.. .. lib germinate]))
|
6
|
+
|
7
|
+
|
8
|
+
module Germinate
|
9
|
+
describe Librarian do
|
10
|
+
before :each do
|
11
|
+
@it = Librarian.new
|
12
|
+
@it.source_path = "SOURCE_PATH"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should know its source path if given" do
|
16
|
+
@it.source_path.should == "SOURCE_PATH"
|
17
|
+
end
|
18
|
+
|
19
|
+
context "by default" do
|
20
|
+
it "should have access to the special _transform process" do
|
21
|
+
@it.process('_transform').should be_a_kind_of(TransformProcess)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not have a comment prefix" do
|
25
|
+
@it.comment_prefix.should == nil
|
26
|
+
@it.comment_prefix_known?.should be_false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should not have code brackets" do
|
30
|
+
@it.code_open_bracket.should be_nil
|
31
|
+
@it.code_close_bracket.should be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Germinate::SharedStyleAttributes.fattrs.each do |attribute|
|
36
|
+
it "should pass the #{attribute} attribute on to text hunks" do
|
37
|
+
@it.send(attribute, "#{attribute}_test")
|
38
|
+
@it.add_text!("first", "hello")
|
39
|
+
@it.section("first").send(attribute).should == "#{attribute}_test"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should pass the #{attribute} attribute on to code hunks" do
|
43
|
+
@it.send(attribute, "#{attribute}_test")
|
44
|
+
@it.add_code!("first", "hello")
|
45
|
+
@it.sample("first").send(attribute).should == "#{attribute}_test"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "given a comment prefix" do
|
50
|
+
before :each do
|
51
|
+
@it.comment_prefix = "||"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should remember the comment prefix" do
|
55
|
+
@it.comment_prefix.should == "||"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should know it has a comment prefix" do
|
59
|
+
@it.comment_prefix_known?.should be_true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "given code brackets" do
|
64
|
+
before :each do
|
65
|
+
@it.code_open_bracket = "{"
|
66
|
+
@it.code_close_bracket = "}"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should remember the open bracket" do
|
70
|
+
@it.code_open_bracket.should == "{"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should remember the close bracket" do
|
74
|
+
@it.code_close_bracket.should == "}"
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
context "given custom code attributes" do
|
80
|
+
before :each do
|
81
|
+
@it.set_code_attributes!(
|
82
|
+
"sample1",
|
83
|
+
:code_open_bracket => "<<",
|
84
|
+
:code_close_bracket => ">>")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should create the sample (if needed) and assign the attributes" do
|
88
|
+
@it.sample("sample1").code_open_bracket.should == "<<"
|
89
|
+
@it.sample("sample1").code_close_bracket.should == ">>"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "given an insertion in my_section with selector @my_selector" do
|
94
|
+
before :each do
|
95
|
+
@it.disable_all_transforms!
|
96
|
+
@it.add_code!("my_sample", "line 1\n")
|
97
|
+
@it.add_insertion!("my_section", "@my_sample", { :comment_prefix => "@" })
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should add an Insertion to the named section" do
|
101
|
+
@it.section("my_section").last.should be_a_kind_of(Insertion)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should give the insertion the selector @my_selector" do
|
105
|
+
@it.section("my_section").last.selector.to_s.should == "@my_sample"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should give the insertion a reference to the library" do
|
109
|
+
@it.section("my_section").last.library.should == @it
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should apply any passed attributes to the insertion" do
|
113
|
+
@it.section("my_section").last.comment_prefix.should == "@"
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should include the insertion in the $TEXT hunk" do
|
117
|
+
@it['$TEXT'].first.should be_a_kind_of(Insertion)
|
118
|
+
@it['$TEXT'].first.selector.should == "@my_sample"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "given a process to file" do
|
123
|
+
before :each do
|
124
|
+
@it.add_process!("myproc", "cowsay")
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should make the process available as a ShellProcess object" do
|
128
|
+
@it.process("myproc").should be_a_kind_of(Germinate::ShellProcess)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should store the process name" do
|
132
|
+
@it.process("myproc").name.should == "myproc"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should store the process command" do
|
136
|
+
@it.process("myproc").command.should == "cowsay"
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should include the process when listing known processes" do
|
140
|
+
@it.process_names.should include("myproc")
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should give the process a reference to the librarians variables" do
|
144
|
+
@it.process("myproc").variables.should equal(@it.variables)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "given a code sample and some processes" do
|
149
|
+
before :each do
|
150
|
+
@output_a = Hunk.new(["line 1a", "line 2a"])
|
151
|
+
@output_b = Hunk.new(["line 1b", "line 2b"])
|
152
|
+
@process_a = stub("ShellProcess A",
|
153
|
+
:call => @output_a,
|
154
|
+
:name => "foo",
|
155
|
+
:command => "aaa")
|
156
|
+
@process_b = stub("ShellProcess B",
|
157
|
+
:call => @output_b,
|
158
|
+
:name => "bar",
|
159
|
+
:command => "bbb")
|
160
|
+
Germinate::ShellProcess.stub!(:new).
|
161
|
+
with("foo", "aaa", {}).
|
162
|
+
and_return(@process_a)
|
163
|
+
Germinate::ShellProcess.stub!(:new).
|
164
|
+
with("bar", "bbb", {}).
|
165
|
+
and_return(@process_b)
|
166
|
+
|
167
|
+
@it.add_code!("A", "line 1")
|
168
|
+
@it.add_code!("A", "line 2")
|
169
|
+
@it.add_process!("foo", "aaa")
|
170
|
+
@it.add_process!("bar", "bbb")
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when the processes are included in a selection" do
|
174
|
+
before :each do
|
175
|
+
@selector = "@A|foo|bar"
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should call the processes on the selected text" do
|
179
|
+
@process_a.should_receive(:call).with(["line 1\n", "line 2\n"]).
|
180
|
+
and_return(@output_a)
|
181
|
+
@process_b.should_receive(:call).with(@output_a).
|
182
|
+
and_return(@output_b)
|
183
|
+
|
184
|
+
@it[@selector].should == ["line 1b", "line 2b"]
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "when asked to make a pipeline of the two processes" do
|
189
|
+
before :each do
|
190
|
+
@pipeline = @it.make_pipeline("bar|foo")
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should return a Pipeline object" do
|
194
|
+
@pipeline.should be_a_kind_of(Germinate::Pipeline)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should return a two-process pipeline" do
|
198
|
+
@pipeline.should have(2).processes
|
199
|
+
end
|
200
|
+
|
201
|
+
it "should include the named processes in the pipeline" do
|
202
|
+
@pipeline.processes[0].name.should == "bar"
|
203
|
+
@pipeline.processes[0].command.should == "bbb"
|
204
|
+
@pipeline.processes[1].name.should == "foo"
|
205
|
+
@pipeline.processes[1].command.should == "aaa"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "when asked to make an empty pipeline" do
|
210
|
+
before :each do
|
211
|
+
@pipeline = @it.make_pipeline("")
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should return an empty pipeline" do
|
215
|
+
@pipeline.should have(0).processes
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "given a new publisher" do
|
221
|
+
before :each do
|
222
|
+
@publisher_name = "MyPub"
|
223
|
+
@publisher_type = "shell"
|
224
|
+
@publisher_options = {'foo' => 'bar'}
|
225
|
+
@publisher = stub("Publisher")
|
226
|
+
Germinate::Publisher.stub!(:make).and_return(@publisher)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should construct a new publisher object" do
|
230
|
+
Germinate::Publisher.should_receive(:make).
|
231
|
+
with(@publisher_name, @publisher_type, @it, @publisher_options).
|
232
|
+
and_return(@publisher)
|
233
|
+
@it.add_publisher!(@publisher_name, @publisher_type, @publisher_options)
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should make the new publisher available by name" do
|
237
|
+
@it.add_publisher!(@publisher_name, @publisher_type, @publisher_options)
|
238
|
+
@it.publisher(@publisher_name).should equal(@publisher)
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should raise an error when an unknown publisher is requested" do
|
242
|
+
@it.add_publisher!(@publisher_name, @publisher_type, @publisher_options)
|
243
|
+
lambda do
|
244
|
+
@it.publisher("foo")
|
245
|
+
end.should raise_error(IndexError)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context "given a variable directive" do
|
250
|
+
before :each do
|
251
|
+
@line = " :SET: FOO, 123"
|
252
|
+
@it.set_variable!(@line, 111, "FOO", "123")
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should add a variable with the given name and value" do
|
256
|
+
@it.variables["FOO"].should == "123"
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should set the variables line to the given value" do
|
260
|
+
@it.variables["FOO"].line.should equal(@line)
|
261
|
+
end
|
262
|
+
|
263
|
+
it "should set the variables line_number to the given value" do
|
264
|
+
@it.variables["FOO"].origin.line_number.should == 111
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should set the variables source path to its own source path" do
|
268
|
+
@it.variables["FOO"].origin.source_path.to_s.should == "SOURCE_PATH"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
context "given a variable setting when the variable already has a value" do
|
273
|
+
before :each do
|
274
|
+
@it.set_variable!(" :SET: FOO, 123", 1, "FOO", "123")
|
275
|
+
@it.set_variable!(" :SET: FOO, 456", 1, "FOO", "456")
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should replace the old variable value with the new one" do
|
279
|
+
@it.variables["FOO"].should == "456"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context "setting a new variable" do
|
284
|
+
before :each do
|
285
|
+
@it.add_text!("a", " # some text")
|
286
|
+
@it.comment_prefix = " # "
|
287
|
+
@it.variables["FOO"] = 123
|
288
|
+
end
|
289
|
+
|
290
|
+
it "should add a new line" do
|
291
|
+
@it.lines.last.should == " # :SET: 'FOO', '123'\n"
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should set the variable to reference the new line" do
|
295
|
+
@it.variables["FOO"].line.should equal(@it.lines.last)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should set the line number for the new line" do
|
299
|
+
@it.variables["FOO"].origin.line_number.should == 2
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should set the variable's source file to its own" do
|
303
|
+
@it.variables["FOO"].origin.source_path.should == "SOURCE_PATH"
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should set the variable's value as a string" do
|
307
|
+
@it.variables["FOO"].should == "123"
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should set the updatad flag" do
|
311
|
+
@it.should be_updated
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context "setting an existing variable" do
|
316
|
+
before :each do
|
317
|
+
@it.comment_prefix = " # "
|
318
|
+
@it.variables["FOO"] = 123
|
319
|
+
@it.add_text!("a", " # some text")
|
320
|
+
@it.updated = false
|
321
|
+
@it.variables["FOO"] = 456
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should not add a new line" do
|
325
|
+
@it.should have(2).lines
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should point to an already existing line" do
|
329
|
+
@it.variables["FOO"].line.should equal(@it.lines.first)
|
330
|
+
end
|
331
|
+
|
332
|
+
it "should keep variable line number" do
|
333
|
+
@it.variables["FOO"].origin.line_number.should == 1
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should keep variable source path" do
|
337
|
+
@it.variables["FOO"].origin.source_path.should == "SOURCE_PATH"
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should update the variable's value" do
|
341
|
+
@it.variables["FOO"].should == "456"
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should set the updatad flag" do
|
345
|
+
@it.should be_updated
|
346
|
+
end
|
347
|
+
|
348
|
+
it "should update the source line with a new directive" do
|
349
|
+
@it.lines.first.should == " # :SET: 'FOO', '456'\n"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "storing changes" do
|
354
|
+
before :each do
|
355
|
+
@it.add_text!("A", "Line 1")
|
356
|
+
@it.add_text!("B", "Line 2")
|
357
|
+
@source_file = stub("Source File")
|
358
|
+
@it.source_file = @source_file
|
359
|
+
end
|
360
|
+
|
361
|
+
it "should send all lines to the source file object to be written" do
|
362
|
+
@source_file.should_receive(:write!).with(["Line 1\n", "Line 2\n"])
|
363
|
+
@it.store_changes!
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
context "given an assortment of lines" do
|
368
|
+
before :each do
|
369
|
+
@it.add_front_matter!("FM 1")
|
370
|
+
@it.add_front_matter!("FM 2")
|
371
|
+
@it.add_control!("CONTROL 1")
|
372
|
+
@it.add_text!("SECTION1", "TEXT 1")
|
373
|
+
@it.add_text!("SECTION1", "TEXT 2")
|
374
|
+
@it.add_control!("CONTROL 2")
|
375
|
+
@it.add_code!("SECTION1", "CODE 1")
|
376
|
+
@it.add_control!("CONTROL 3")
|
377
|
+
@it.add_text!("SECTION2", "TEXT 3")
|
378
|
+
@it.add_text!("SECTION2", "TEXT 4")
|
379
|
+
@it.add_code!("SECTION2", "CODE 2")
|
380
|
+
@it.add_code!("SECTION2", "CODE 2l2")
|
381
|
+
@it.add_code!("SECTION2", "CODE 2l3")
|
382
|
+
@it.add_code!("SECTION2", "CODE 2l4")
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should be able to retrieve all the lines in order" do
|
386
|
+
@it.lines.should == [
|
387
|
+
"FM 1\n",
|
388
|
+
"FM 2\n",
|
389
|
+
"CONTROL 1\n",
|
390
|
+
"TEXT 1\n",
|
391
|
+
"TEXT 2\n",
|
392
|
+
"CONTROL 2\n",
|
393
|
+
"CODE 1\n",
|
394
|
+
"CONTROL 3\n",
|
395
|
+
"TEXT 3\n",
|
396
|
+
"TEXT 4\n",
|
397
|
+
"CODE 2\n",
|
398
|
+
"CODE 2l2\n",
|
399
|
+
"CODE 2l3\n",
|
400
|
+
"CODE 2l4\n",
|
401
|
+
]
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should be able to retrieve text lines" do
|
405
|
+
@it.text_lines.should == [
|
406
|
+
"TEXT 1\n",
|
407
|
+
"TEXT 2\n",
|
408
|
+
"TEXT 3\n",
|
409
|
+
"TEXT 4\n"
|
410
|
+
]
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should be able to retrieve code lines" do
|
414
|
+
@it.code_lines.should == [
|
415
|
+
"CODE 1\n",
|
416
|
+
"CODE 2\n",
|
417
|
+
"CODE 2l2\n",
|
418
|
+
"CODE 2l3\n",
|
419
|
+
"CODE 2l4\n",
|
420
|
+
]
|
421
|
+
end
|
422
|
+
|
423
|
+
it "should be able to retrieve front matter" do
|
424
|
+
@it.front_matter_lines.should == [
|
425
|
+
"FM 1\n",
|
426
|
+
"FM 2\n",
|
427
|
+
]
|
428
|
+
end
|
429
|
+
|
430
|
+
it "should be able to retrieve text by section" do
|
431
|
+
@it.section("SECTION1").should == [
|
432
|
+
"TEXT 1\n",
|
433
|
+
"TEXT 2\n"
|
434
|
+
]
|
435
|
+
@it.section("SECTION2").should == [
|
436
|
+
"TEXT 3\n",
|
437
|
+
"TEXT 4\n"
|
438
|
+
]
|
439
|
+
end
|
440
|
+
|
441
|
+
it "should be able to retrieve code by sample name" do
|
442
|
+
@it.sample("SECTION1").should == [
|
443
|
+
"CODE 1\n"
|
444
|
+
]
|
445
|
+
@it.sample("SECTION2").should == [
|
446
|
+
"CODE 2\n",
|
447
|
+
"CODE 2l2\n",
|
448
|
+
"CODE 2l3\n",
|
449
|
+
"CODE 2l4\n",
|
450
|
+
]
|
451
|
+
end
|
452
|
+
|
453
|
+
it "should be able to return a list of section names" do
|
454
|
+
@it.section_names.should == [
|
455
|
+
"SECTION1",
|
456
|
+
"SECTION2"
|
457
|
+
]
|
458
|
+
end
|
459
|
+
|
460
|
+
it "should be able to return a list of sample names" do
|
461
|
+
@it.sample_names.should == [
|
462
|
+
"SECTION1",
|
463
|
+
"SECTION2"
|
464
|
+
]
|
465
|
+
end
|
466
|
+
|
467
|
+
it "should be able to tell if a section exists" do
|
468
|
+
@it.should have_section("SECTION1")
|
469
|
+
@it.should_not have_section("SECTION5")
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should be able to tell if a sample exists" do
|
473
|
+
@it.should have_sample("SECTION1")
|
474
|
+
@it.should_not have_sample("SECTION5")
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should be able to retrieve lines using a selector" do
|
478
|
+
@it[Selector.new("@SECTION1", nil)].should == ["CODE 1\n"]
|
479
|
+
@it["@SECTION1"].should == ["CODE 1\n"]
|
480
|
+
end
|
481
|
+
|
482
|
+
context "given the $SOURCE selector with no subscripts" do
|
483
|
+
before :each do
|
484
|
+
@hunk = @it["$SOURCE"]
|
485
|
+
end
|
486
|
+
|
487
|
+
it "should return a FileHunk" do
|
488
|
+
@hunk.should be_a_kind_of(FileHunk)
|
489
|
+
end
|
490
|
+
|
491
|
+
it "should return a FileHunk with the source file path set" do
|
492
|
+
@hunk.source_path.should == "SOURCE_PATH"
|
493
|
+
end
|
494
|
+
|
495
|
+
end
|
496
|
+
|
497
|
+
SELECTOR_EXAMPLES = [
|
498
|
+
# Selector Expected Excerpt Expected Type
|
499
|
+
[ "@SECTION1", ["CODE 1\n"], CodeHunk ],
|
500
|
+
[ "@SECTION2:1", ["CODE 2\n"], CodeHunk ],
|
501
|
+
[ "@SECTION2:2..3", ["CODE 2l2\n", "CODE 2l3\n"], CodeHunk ],
|
502
|
+
[ "@SECTION2:2,2", ["CODE 2l2\n", "CODE 2l3\n"], CodeHunk ],
|
503
|
+
[ "@SECTION2:/l2/../l3/", ["CODE 2l2\n", "CODE 2l3\n"], CodeHunk ],
|
504
|
+
[ "@SECTION2:/l2/.../l3/", ["CODE 2l2\n"], CodeHunk ],
|
505
|
+
[ "@SECTION2:/2/,3", [
|
506
|
+
"CODE 2\n",
|
507
|
+
"CODE 2l2\n",
|
508
|
+
"CODE 2l3\n"], CodeHunk ],
|
509
|
+
[ "@SECTION2:/l2/..-1", [
|
510
|
+
"CODE 2l2\n",
|
511
|
+
"CODE 2l3\n",
|
512
|
+
"CODE 2l4\n"], CodeHunk ],
|
513
|
+
[ "$CODE", [
|
514
|
+
"CODE 1\n",
|
515
|
+
"CODE 2\n",
|
516
|
+
"CODE 2l2\n",
|
517
|
+
"CODE 2l3\n",
|
518
|
+
"CODE 2l4\n", ], CodeHunk
|
519
|
+
],
|
520
|
+
[ "$SOURCE", [
|
521
|
+
"FM 1\n",
|
522
|
+
"FM 2\n",
|
523
|
+
"CONTROL 1\n",
|
524
|
+
"TEXT 1\n",
|
525
|
+
"TEXT 2\n",
|
526
|
+
"CONTROL 2\n",
|
527
|
+
"CODE 1\n",
|
528
|
+
"CONTROL 3\n",
|
529
|
+
"TEXT 3\n",
|
530
|
+
"TEXT 4\n",
|
531
|
+
"CODE 2\n",
|
532
|
+
"CODE 2l2\n",
|
533
|
+
"CODE 2l3\n",
|
534
|
+
"CODE 2l4\n",
|
535
|
+
], FileHunk
|
536
|
+
],
|
537
|
+
[ "$TEXT", [
|
538
|
+
"TEXT 1 TEXT 2 TEXT 3 TEXT 4" ], TextHunk
|
539
|
+
],
|
540
|
+
|
541
|
+
]
|
542
|
+
|
543
|
+
SELECTOR_EXAMPLES.each do |example|
|
544
|
+
example.fields = [:selector, :hunk, :type]
|
545
|
+
it "should be able to locate #{example[:selector]}" do
|
546
|
+
@it[example[:selector]].should == example[:hunk]
|
547
|
+
end
|
548
|
+
|
549
|
+
it "should return #{example[:selector]} as #{example[:type]}" do
|
550
|
+
@it[example[:selector]].should be_a_kind_of(example[:type])
|
551
|
+
end
|
552
|
+
end
|
553
|
+
end
|
554
|
+
end
|
555
|
+
end
|