escort 0.2.1 → 0.3.0
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.
- checksums.yaml +8 -8
- data/.irbrc +2 -0
- data/.travis.yml +1 -1
- data/README.md +272 -3
- data/TODO.md +118 -71
- data/examples/.my_apprc +24 -0
- data/examples/basic_config_file +16 -0
- data/examples/basic_conflicts +1 -1
- data/examples/basic_with_everything +30 -0
- data/examples/suite_complex +65 -0
- data/examples/{command → suite_simple} +0 -0
- data/examples/suite_with_sub_commands +94 -0
- data/lib/escort.rb +6 -4
- data/lib/escort/action_command/base.rb +7 -5
- data/lib/escort/app.rb +2 -8
- data/lib/escort/auto_options.rb +5 -3
- data/lib/escort/formatter/cursor_position.rb +29 -0
- data/lib/escort/formatter/default_help_formatter.rb +37 -32
- data/lib/escort/formatter/option.rb +1 -1
- data/lib/escort/formatter/stream_output_formatter.rb +88 -0
- data/lib/escort/formatter/{borderless_table.rb → string_grid.rb} +21 -19
- data/lib/escort/formatter/string_splitter.rb +24 -4
- data/lib/escort/setup/configuration/loader.rb +8 -2
- data/lib/escort/setup/configuration/locator/chaining.rb +29 -0
- data/lib/escort/setup/configuration/locator/executing_script_directory.rb +15 -0
- data/lib/escort/setup/configuration/locator/specified_directory.rb +21 -0
- data/lib/escort/setup/configuration/reader.rb +4 -2
- data/lib/escort/setup/configuration/writer.rb +6 -2
- data/lib/escort/setup/dsl/command.rb +7 -8
- data/lib/escort/setup/dsl/global.rb +3 -51
- data/lib/escort/version.rb +1 -1
- data/spec/integration/basic_config_file_spec.rb +82 -0
- data/spec/integration/suite_simple_spec.rb +45 -0
- data/spec/integration/suite_sub_command_spec.rb +51 -0
- data/spec/lib/escort/action_command/base_spec.rb +200 -0
- data/spec/lib/escort/formatter/option_spec.rb +2 -2
- data/spec/lib/escort/formatter/stream_output_formatter_spec.rb +214 -0
- data/spec/lib/escort/formatter/string_grid_spec.rb +59 -0
- data/spec/lib/escort/setup/configuration/generator_spec.rb +101 -0
- data/spec/lib/escort/setup/configuration/loader_spec.rb +79 -0
- data/spec/lib/escort/setup/configuration/locator/chaining_spec.rb +81 -0
- data/spec/lib/escort/setup/configuration/locator/descending_to_home_spec.rb +57 -0
- data/spec/lib/escort/setup/configuration/locator/executing_script_directory_spec.rb +29 -0
- data/spec/lib/escort/setup/configuration/locator/specified_directory_spec.rb +33 -0
- data/spec/lib/escort/setup/configuration/merge_tool_spec.rb +41 -0
- data/spec/lib/escort/setup/configuration/reader_spec.rb +41 -0
- data/spec/lib/escort/setup/configuration/writer_spec.rb +75 -0
- data/spec/spec_helper.rb +2 -1
- metadata +44 -24
- data/examples/attic/1_1_basic.rb +0 -15
- data/examples/attic/1_2_basic_requires_arguments.rb +0 -15
- data/examples/attic/2_2_command.rb +0 -18
- data/examples/attic/2_2_command_requires_arguments.rb +0 -20
- data/examples/attic/2_3_nested_commands.rb +0 -26
- data/examples/attic/3_validations.rb +0 -31
- data/examples/attic/4_1_config_file.rb +0 -42
- data/examples/attic/argument_handling/basic.rb +0 -12
- data/examples/attic/argument_handling/basic_command.rb +0 -18
- data/examples/attic/argument_handling/no_arguments.rb +0 -14
- data/examples/attic/argument_handling/no_arguments_command.rb +0 -20
- data/examples/attic/command_aliases/app.rb +0 -31
- data/examples/attic/config_file/.apprc2 +0 -16
- data/examples/attic/config_file/app.rb +0 -78
- data/examples/attic/config_file/sub_commands.rb +0 -35
- data/examples/attic/default_command/app.rb +0 -20
- data/examples/attic/sub_commands/app.rb +0 -18
- data/examples/attic/validation_basic/app.rb +0 -31
- data/lib/escort/formatter/terminal_formatter.rb +0 -58
- data/lib/escort/setup/dsl/validations.rb +0 -25
data/lib/escort/version.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
describe "Escort basic app with config file defined", :integration => true do
|
2
|
+
include FakeFS::SpecHelpers
|
3
|
+
|
4
|
+
subject { Escort::App.create(option_string, &app_configuration) }
|
5
|
+
|
6
|
+
let(:path) {File.join(File.expand_path('~'), '.test_apprc')}
|
7
|
+
let(:app_configuration) do
|
8
|
+
lambda do |app|
|
9
|
+
app.config_file ".test_apprc", :autocreate => autocreate
|
10
|
+
|
11
|
+
app.options do |opts|
|
12
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
|
13
|
+
end
|
14
|
+
|
15
|
+
app.action do |options, arguments|
|
16
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when config file is autocreatable" do
|
22
|
+
context "and config file does not yet exist" do
|
23
|
+
before do
|
24
|
+
begin
|
25
|
+
subject
|
26
|
+
rescue SystemExit => e
|
27
|
+
end
|
28
|
+
end
|
29
|
+
let(:autocreate) {true}
|
30
|
+
let(:option_string) { "" }
|
31
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
32
|
+
it("should have created a config file in default location") { File.should exist path }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "and config file already exists" do
|
36
|
+
before do
|
37
|
+
FileUtils.mkdir_p(File.dirname path)
|
38
|
+
File.open(path, 'w') {|f| f.write(JSON.pretty_generate({:global => {:commands => {}, :options => {:option1 => 'hello'}}, :user => {}})) }
|
39
|
+
|
40
|
+
begin
|
41
|
+
subject
|
42
|
+
rescue SystemExit => e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
let(:autocreate) {true}
|
46
|
+
let(:option_string) { "" }
|
47
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
48
|
+
it("should have picked up the existing config file") { result[:command_options][:option1].should == 'hello' }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when config file is not autocreatable" do
|
53
|
+
context "and config file already exists" do
|
54
|
+
let(:autocreate) {false}
|
55
|
+
let(:option_string) { "" }
|
56
|
+
before do
|
57
|
+
FileUtils.mkdir_p(File.dirname path)
|
58
|
+
File.open(path, 'w') {|f| f.write(JSON.pretty_generate({:global => {:commands => {}, :options => {:option1 => 'hello'}}, :user => {}})) }
|
59
|
+
|
60
|
+
begin
|
61
|
+
subject
|
62
|
+
rescue SystemExit => e
|
63
|
+
end
|
64
|
+
end
|
65
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
66
|
+
it("should have picked up the existing config file") { result[:command_options][:option1].should == 'hello' }
|
67
|
+
end
|
68
|
+
|
69
|
+
context "and config file does not yet exist" do
|
70
|
+
let(:autocreate) {false}
|
71
|
+
let(:option_string) { "" }
|
72
|
+
before do
|
73
|
+
begin
|
74
|
+
subject
|
75
|
+
rescue SystemExit => e
|
76
|
+
end
|
77
|
+
end
|
78
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
79
|
+
it("should not have created a config file in default location") { File.should_not exist path }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe "Escort suite app with one level of commands", :integration => true do
|
2
|
+
subject { Escort::App.create(option_string, &app_configuration) }
|
3
|
+
|
4
|
+
let(:app_configuration) do
|
5
|
+
lambda do |app|
|
6
|
+
app.options do |opts|
|
7
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
|
8
|
+
end
|
9
|
+
|
10
|
+
app.command :command1, :aliases => [:c1] do |command|
|
11
|
+
command.options do |opts|
|
12
|
+
opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string
|
13
|
+
end
|
14
|
+
|
15
|
+
command.action do |options, arguments|
|
16
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
app.action do |options, arguments|
|
21
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when calling command with option and global option" do
|
27
|
+
let(:option_string) { "-o hello command1 --option2 world" }
|
28
|
+
|
29
|
+
before do
|
30
|
+
begin
|
31
|
+
subject
|
32
|
+
rescue SystemExit => e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
36
|
+
it("should have the right command name") { result[:command_name].should == :command1 }
|
37
|
+
it("should have have global option set") { result[:options][:global][:options][:option1].should == 'hello' }
|
38
|
+
it("should have have command option set") { result[:command_options][:option2].should == 'world' }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when using command alias" do
|
42
|
+
let(:option_string) { "-o hello c1 --option2 world" }
|
43
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
describe "Escort suite app with sub commands", :integration => true do
|
2
|
+
subject { Escort::App.create(option_string, &app_configuration) }
|
3
|
+
|
4
|
+
let(:app_configuration) do
|
5
|
+
lambda do |app|
|
6
|
+
app.options do |opts|
|
7
|
+
opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
|
8
|
+
end
|
9
|
+
|
10
|
+
app.command :command1, :aliases => [:c1] do |command|
|
11
|
+
command.options do |opts|
|
12
|
+
opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string
|
13
|
+
end
|
14
|
+
|
15
|
+
command.command :sub_command1 do |command|
|
16
|
+
command.options do |opts|
|
17
|
+
opts.opt :option3, "Option3", :short => :none, :long => '--option3', :type => :string
|
18
|
+
end
|
19
|
+
|
20
|
+
command.action do |options, arguments|
|
21
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
command.action do |options, arguments|
|
26
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
app.action do |options, arguments|
|
31
|
+
Escort::IntegrationTestCommand.new(options, arguments).execute(result)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when calling sub command with option and command option and global option" do
|
37
|
+
let(:option_string) { "-o hello command1 --option2=world sub_command1 --option3=foo" }
|
38
|
+
|
39
|
+
before do
|
40
|
+
begin
|
41
|
+
subject
|
42
|
+
rescue SystemExit => e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
|
46
|
+
it("should have the right command name") { result[:command_name].should == :sub_command1 }
|
47
|
+
it("should have have sub command option set") { result[:command_options][:option3].should == 'foo' }
|
48
|
+
it("should have have global option set") { result[:options][:global][:options][:option1].should == 'hello' }
|
49
|
+
it("should have have command option set") { result[:options][:global][:commands][:command1][:options][:option2].should == 'world' }
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
describe Escort::SetupAccessor do
|
2
|
+
let(:command) { Escort::TestCommand.new(options, arguments, config) }
|
3
|
+
let(:options) { {} }
|
4
|
+
let(:arguments) { [] }
|
5
|
+
let(:config) { {} }
|
6
|
+
|
7
|
+
describe "#command_context" do
|
8
|
+
subject {command.send(:command_context)}
|
9
|
+
|
10
|
+
context "when command context already set" do
|
11
|
+
before do
|
12
|
+
command.instance_variable_set(:"@command_context", [:hello])
|
13
|
+
end
|
14
|
+
|
15
|
+
it {subject.should == [:hello]}
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when command context not yet set" do
|
19
|
+
context "and options hash is empty" do
|
20
|
+
it {subject.should == []}
|
21
|
+
end
|
22
|
+
|
23
|
+
context "and options hash is of valid structure" do
|
24
|
+
context "and command is global" do
|
25
|
+
let(:options) { {:global => {:commands => {}}} }
|
26
|
+
it {subject.should == []}
|
27
|
+
end
|
28
|
+
|
29
|
+
context "and command is child of global" do
|
30
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}}}}} }
|
31
|
+
it {subject.should == [:command1]}
|
32
|
+
|
33
|
+
context "and no commands hash for sub command in options" do
|
34
|
+
let(:options) { {:global => {:commands => {:command1 => {}}}} }
|
35
|
+
it {subject.should == [:command1]}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "and command is grandchild of global" do
|
40
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {:sub_command1 => {:commands => {}}}}}}} }
|
41
|
+
it {subject.should == [:command1, :sub_command1]}
|
42
|
+
end
|
43
|
+
|
44
|
+
context "and command is great grandchild of global" do
|
45
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {:sub_command1 => {:commands => {:sub_sub_command1 => {:commands => {}}}}}}}}} }
|
46
|
+
it {subject.should == [:command1, :sub_command1, :sub_sub_command1]}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#command_name" do
|
53
|
+
subject {command.send(:command_name)}
|
54
|
+
|
55
|
+
context "when context is global" do
|
56
|
+
let(:options) { {:global => {:commands => {}}} }
|
57
|
+
it {subject.should == :global}
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when context is of size 1" do
|
61
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}}}}} }
|
62
|
+
it {subject.should == :command1}
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when context is of size 2" do
|
66
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {:sub_command1 => {:commands => {}}}}}}} }
|
67
|
+
it {subject.should == :sub_command1}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#command_options" do
|
72
|
+
subject {command.send(:command_options)}
|
73
|
+
|
74
|
+
context "when context is global" do
|
75
|
+
let(:options) { {:global => {:commands => {}, :options => {:hello => :world}}} }
|
76
|
+
it {subject.should == {:hello => :world}}
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when context is of size 1" do
|
80
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}, :options => {:hello => :world}}}}} }
|
81
|
+
it {subject.should == {:hello => :world}}
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when context is of size 2" do
|
85
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {:sub_command1 => {:commands => {}, :options => {:hello => :world}}}}}}} }
|
86
|
+
it {subject.should == {:hello => :world}}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#global_options" do
|
91
|
+
subject {command.send(:global_options)}
|
92
|
+
|
93
|
+
context "when context is global" do
|
94
|
+
let(:options) { {:global => {:commands => {}, :options => {:hello => :world}}} }
|
95
|
+
it {subject.should == {:hello => :world}}
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when context is of size 1" do
|
99
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}}}, :options => {:hello => :world}}} }
|
100
|
+
it {subject.should == {:hello => :world}}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "#parent_options" do
|
105
|
+
subject {command.send(:parent_options)}
|
106
|
+
|
107
|
+
context "when context is global" do
|
108
|
+
let(:options) { {:global => {:commands => {}, :options => {:hello => :world}}} }
|
109
|
+
it {subject.should == {}}
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when context is of size 1" do
|
113
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}}}, :options => {:hello => :world}}} }
|
114
|
+
it {subject.should == {:hello => :world}}
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when context is of size 2" do
|
118
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {:sub_command1 => {:commands => {}}}, :options => {:hello => :world}}}}} }
|
119
|
+
it {subject.should == {:hello => :world}}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "#grandparent_options" do
|
124
|
+
subject {command.send(:grandparent_options)}
|
125
|
+
|
126
|
+
context "when context is global" do
|
127
|
+
let(:options) { {:global => {:commands => {}, :options => {:hello => :world}}} }
|
128
|
+
it {subject.should == {}}
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when context is of size 1" do
|
132
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}}}, :options => {:hello => :world}}} }
|
133
|
+
it {subject.should == {}}
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when context is of size 2" do
|
137
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {:sub_command1 => {:commands => {}}}}}, :options => {:hello => :world}}} }
|
138
|
+
it {subject.should == {:hello => :world}}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#ancestor_options" do
|
143
|
+
subject {command.send(:ancestor_options, generation_number)}
|
144
|
+
|
145
|
+
context "when context is global" do
|
146
|
+
let(:options) { {:global => {:commands => {}, :options => {:hello => :world}}} }
|
147
|
+
|
148
|
+
context "and generation number is 0" do
|
149
|
+
let(:generation_number) {0}
|
150
|
+
it {subject.should == {:hello => :world}}
|
151
|
+
end
|
152
|
+
|
153
|
+
context "and generation number is 1" do
|
154
|
+
let(:generation_number) {1}
|
155
|
+
it {subject.should == {}}
|
156
|
+
end
|
157
|
+
|
158
|
+
context "and generation number is 2" do
|
159
|
+
let(:generation_number) {2}
|
160
|
+
it {subject.should == {}}
|
161
|
+
end
|
162
|
+
|
163
|
+
context "and generation number is 3" do
|
164
|
+
let(:generation_number) {3}
|
165
|
+
it {subject.should == {}}
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when context is of size 1" do
|
170
|
+
let(:options) { {:global => {:commands => {:command1 => {:commands => {}, :options => {:foo => :bar}}}, :options => {:hello => :world}}} }
|
171
|
+
|
172
|
+
context "and generation number is 0" do
|
173
|
+
let(:generation_number) {0}
|
174
|
+
it {subject.should == {:foo => :bar}}
|
175
|
+
end
|
176
|
+
|
177
|
+
context "and generation number is 1" do
|
178
|
+
let(:generation_number) {1}
|
179
|
+
it {subject.should == {:hello => :world}}
|
180
|
+
end
|
181
|
+
|
182
|
+
context "and generation number is 2" do
|
183
|
+
let(:generation_number) {2}
|
184
|
+
it {subject.should == {}}
|
185
|
+
end
|
186
|
+
|
187
|
+
context "and generation number is 3" do
|
188
|
+
let(:generation_number) {3}
|
189
|
+
it {subject.should == {}}
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
module Escort
|
196
|
+
class TestCommand < ::Escort::ActionCommand::Base
|
197
|
+
def execute
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -276,7 +276,7 @@ describe Escort::Formatter::Option do
|
|
276
276
|
end
|
277
277
|
end
|
278
278
|
end
|
279
|
-
it {subject.should ==
|
279
|
+
it {subject.should == []}
|
280
280
|
end
|
281
281
|
|
282
282
|
context "when validations is defined" do
|
@@ -294,7 +294,7 @@ describe Escort::Formatter::Option do
|
|
294
294
|
end
|
295
295
|
end
|
296
296
|
end
|
297
|
-
it {subject.should == "must be 'foo'
|
297
|
+
it {subject.should == ["must be 'foo'", "must not be 'bar'"]}
|
298
298
|
end
|
299
299
|
end
|
300
300
|
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
describe Escort::Formatter::StreamOutputFormatter do
|
2
|
+
let(:formatter) {Escort::Formatter::StreamOutputFormatter.new(stream, :max_output_width => output_width)}
|
3
|
+
let(:stream) { StringIO.new }
|
4
|
+
let(:output_width) { 10 }
|
5
|
+
let(:output) {stream.readlines}
|
6
|
+
|
7
|
+
describe "#print" do
|
8
|
+
subject {formatter.print(string)}
|
9
|
+
|
10
|
+
before { subject; stream.rewind }
|
11
|
+
|
12
|
+
context "when string is less than output_width" do
|
13
|
+
let(:string) {'12345'}
|
14
|
+
it("stream should have one line") {output.first.should == string}
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when string is greater than output width" do
|
18
|
+
let(:string) {'123456789abcd'}
|
19
|
+
it("stream should have two lines") {output.should == ["123456789a\n", "bcd"]}
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when string is has newlines in it" do
|
23
|
+
context "and both lines less than output width" do
|
24
|
+
let(:string) {"1234567\n89abcd"}
|
25
|
+
it("stream should have two lines") {output.should == ["1234567\n", "89abcd"]}
|
26
|
+
end
|
27
|
+
|
28
|
+
context "and first line greater than output width" do
|
29
|
+
let(:string) {"123456789abcd\nefg"}
|
30
|
+
it("stream should have three lines") {output.should == ["123456789a\n", "bcd\n", "efg"]}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#puts" do
|
36
|
+
subject {formatter.puts(string, options)}
|
37
|
+
let(:string) {'hello'}
|
38
|
+
let(:options) { {:newlines => newlines} }
|
39
|
+
let(:newlines) {1}
|
40
|
+
|
41
|
+
before { subject; stream.rewind }
|
42
|
+
|
43
|
+
context "when newlines" do
|
44
|
+
context "is zero" do
|
45
|
+
let(:newlines) {0}
|
46
|
+
let(:string) {"123456789abcd\nefg"}
|
47
|
+
it("stream should have three lines") {output.should == ["123456789a\n", "bcd\n", "efg"]}
|
48
|
+
end
|
49
|
+
|
50
|
+
context "not specified" do
|
51
|
+
subject {formatter.puts(string)}
|
52
|
+
let(:string) {"123"}
|
53
|
+
it("stream should have one newline") {output.should == ["123\n"]}
|
54
|
+
end
|
55
|
+
|
56
|
+
context "is two" do
|
57
|
+
let(:string) {"123"}
|
58
|
+
let(:newlines) {2}
|
59
|
+
it("stream should have two newlines") {output.should == ["123\n", "\n"]}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#newline" do
|
65
|
+
subject {formatter.newline(newline_count)}
|
66
|
+
let(:newline_count) {1}
|
67
|
+
|
68
|
+
before { subject; stream.rewind }
|
69
|
+
|
70
|
+
context "when newline count not specified" do
|
71
|
+
subject {formatter.newline}
|
72
|
+
it("stream should have one newline") {output.should == ["\n"]}
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when newline count is 2" do
|
76
|
+
let(:newline_count) {2}
|
77
|
+
it("stream should have two newlines") {output.should == ["\n", "\n"]}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#indent" do
|
82
|
+
subject {formatter.indent(indent_width, &indented_block)}
|
83
|
+
|
84
|
+
let(:indented_block) do
|
85
|
+
lambda {|f| f.print string}
|
86
|
+
end
|
87
|
+
|
88
|
+
before { subject; stream.rewind }
|
89
|
+
|
90
|
+
context "when indent is 0" do
|
91
|
+
let(:indent_width) {0}
|
92
|
+
|
93
|
+
context "and we print a string less than output_width" do
|
94
|
+
let(:string) {'12345'}
|
95
|
+
it("stream should have one line") {output.should == ['12345']}
|
96
|
+
end
|
97
|
+
|
98
|
+
context "and we print a string greater than output width" do
|
99
|
+
let(:string) {'123456789abcd'}
|
100
|
+
it("stream should have two lines") {output.should == ["123456789a\n", "bcd"]}
|
101
|
+
end
|
102
|
+
|
103
|
+
context "and we print a string that has newlines in it" do
|
104
|
+
context "and both lines are less than output width" do
|
105
|
+
let(:string) {"1234567\n89abcd"}
|
106
|
+
it("stream should have two lines") {output.should == ["1234567\n", "89abcd"]}
|
107
|
+
end
|
108
|
+
|
109
|
+
context "and first line is greater than output width" do
|
110
|
+
let(:string) {"123456789abcd\nefg"}
|
111
|
+
it("stream should have three lines") {output.should == ["123456789a\n", "bcd\n", "efg"]}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "when indent is 1" do
|
117
|
+
let(:indent_width) {1}
|
118
|
+
|
119
|
+
context "and we print a string less than output_width" do
|
120
|
+
let(:string) {'12345'}
|
121
|
+
it("stream should have one line") {output.should == [' 12345']}
|
122
|
+
end
|
123
|
+
|
124
|
+
context "and we print a string greater than output width" do
|
125
|
+
let(:string) {'123456789abcd'}
|
126
|
+
it("stream should have two lines") {output.should == [" 123456789\n", " abcd"]}
|
127
|
+
end
|
128
|
+
|
129
|
+
context "and we print a string that has newlines in it" do
|
130
|
+
context "and both lines are less than output width" do
|
131
|
+
let(:string) {"1234567\n89abcd"}
|
132
|
+
it("stream should have two lines") {output.should == [" 1234567\n", " 89abcd"]}
|
133
|
+
end
|
134
|
+
|
135
|
+
context "and first line is greater than output width" do
|
136
|
+
let(:string) {"123456789abcd\nefg"}
|
137
|
+
it("stream should have three lines") {output.should == [" 123456789\n", " abcd\n", " efg"]}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "when indent is 3" do
|
143
|
+
let(:indent_width) {3}
|
144
|
+
|
145
|
+
context "and we print a string less than output_width" do
|
146
|
+
let(:string) {'12345'}
|
147
|
+
it("stream should have one line") {output.should == [' 12345']}
|
148
|
+
end
|
149
|
+
|
150
|
+
context "and we print a string greater than output width" do
|
151
|
+
let(:string) {'123456789abcd'}
|
152
|
+
it("stream should have two lines") {output.should == [" 1234567\n", " 89abcd"]}
|
153
|
+
end
|
154
|
+
|
155
|
+
context "and we print a string that has newlines in it" do
|
156
|
+
context "and both lines are less than output width" do
|
157
|
+
let(:string) {"1234567\n89abcd"}
|
158
|
+
it("stream should have two lines") {output.should == [" 1234567\n", " 89abcd"]}
|
159
|
+
end
|
160
|
+
|
161
|
+
context "and first line is greater than output width" do
|
162
|
+
let(:string) {"123456789abcd\nefg"}
|
163
|
+
it("stream should have three lines") {output.should == [" 1234567\n", " 89abcd\n", " efg"]}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "output combinations" do
|
170
|
+
subject do
|
171
|
+
Escort::Formatter::StreamOutputFormatter.new(stream, :max_output_width => output_width) do |f|
|
172
|
+
f.print "the quick"
|
173
|
+
f.newline
|
174
|
+
f.print "brown fox"
|
175
|
+
f.print "jumped over the"
|
176
|
+
f.print "lazy dog"
|
177
|
+
f.newline
|
178
|
+
f.puts 'rainbow suspenders'
|
179
|
+
f.indent(3) do |f|
|
180
|
+
f.puts "blah blah blah blah"
|
181
|
+
f.newline(2)
|
182
|
+
f.indent(2) do |f|
|
183
|
+
f.puts "indent me good"
|
184
|
+
f.print "foo"
|
185
|
+
f.print "foo"
|
186
|
+
f.print "foo"
|
187
|
+
f.newline
|
188
|
+
f.puts "exit", :newlines => 4
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
let(:stream) { StringIO.new }
|
194
|
+
let(:output_width) { 10 }
|
195
|
+
|
196
|
+
let(:output) {stream.readlines}
|
197
|
+
|
198
|
+
before { subject; stream.rewind }
|
199
|
+
|
200
|
+
context "lines should not be greater than output width" do
|
201
|
+
it do
|
202
|
+
output.each do |line|
|
203
|
+
line.strip.length.should be <= output_width
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "stream should contain" do
|
209
|
+
it do
|
210
|
+
output.should == ["the quick\n", "brown foxj\n", "umped over\n", " thelazy d\n", "og\n", "rainbow su\n", "spenders\n", " blah bl\n", " ah blah\n", " blah\n", "\n", "\n", " inden\n", " t me \n", " good\n", " foofo\n", " ofoo\n", " exit\n", "\n", "\n", "\n"]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|