rake_options 0.1.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.
@@ -0,0 +1,242 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "RakeOptions Integration Tests" do
6
+ describe "Full CLI parsing workflow" do
7
+ let(:config) do
8
+ {
9
+ "with-mysql-lib" => "--with-mysql-lib $path",
10
+ "enable-feature" => "--enable-feature $name",
11
+ "port" => "--port $number"
12
+ }
13
+ end
14
+
15
+ it "parses multiple CLI arguments in one invocation" do
16
+ stub_const("ARGV", ["--with-mysql-lib", "/usr/local/lib", "--enable-feature", "caching", "--port", "3000"])
17
+
18
+ result = RakeOptions.command_line_args(config, notation: :cli)
19
+
20
+ expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
21
+ expect(result["enable-feature"]).to eq("caching")
22
+ expect(result["port"]).to eq("3000")
23
+ end
24
+
25
+ it "handles partial arguments gracefully" do
26
+ stub_const("ARGV", ["--with-mysql-lib", "/usr/local/lib"])
27
+
28
+ result = RakeOptions.command_line_args(config, notation: :cli)
29
+
30
+ expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
31
+ expect(result["enable-feature"]).to be_nil
32
+ expect(result["port"]).to be_nil
33
+ end
34
+
35
+ it "supports quoted values with spaces" do
36
+ stub_const("ARGV", ["--with-mysql-lib", '"/path/with spaces/lib"'])
37
+
38
+ result = RakeOptions.command_line_args(config, notation: :cli)
39
+
40
+ expect(result["with-mysql-lib"]).to eq("/path/with spaces/lib")
41
+ end
42
+
43
+ it "allows symbol key access" do
44
+ stub_const("ARGV", ["--with-mysql-lib", "/usr/local/lib"])
45
+
46
+ result = RakeOptions.command_line_args(config, notation: :cli)
47
+
48
+ expect(result[:with_mysql_lib]).to eq("/usr/local/lib")
49
+ expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
50
+ end
51
+ end
52
+
53
+ describe "Full bracket parsing workflow" do
54
+ let(:config) do
55
+ {
56
+ "environment" => "[environment=$env]",
57
+ "region" => "[region=$reg]",
58
+ "instance-type" => "[instance-type=$type]"
59
+ }
60
+ end
61
+
62
+ it "parses multiple bracket arguments" do
63
+ stub_const("ARGV", ["[environment=production]", "[region=us-west-2]", "[instance-type=t2.micro]"])
64
+
65
+ result = RakeOptions.command_line_args(config, notation: :bracket)
66
+
67
+ expect(result["environment"]).to eq("production")
68
+ expect(result["region"]).to eq("us-west-2")
69
+ expect(result["instance-type"]).to eq("t2.micro")
70
+ end
71
+
72
+ it "handles quoted bracket values" do
73
+ stub_const("ARGV", ['[environment="staging environment"]'])
74
+
75
+ result = RakeOptions.command_line_args(config, notation: :bracket)
76
+
77
+ expect(result["environment"]).to eq("staging environment")
78
+ end
79
+
80
+ it "supports symbol key access with dashes/underscores" do
81
+ stub_const("ARGV", ["[instance-type=t2.micro]"])
82
+
83
+ result = RakeOptions.command_line_args(config, notation: :bracket)
84
+
85
+ expect(result[:instance_type]).to eq("t2.micro")
86
+ expect(result["instance-type"]).to eq("t2.micro")
87
+ end
88
+ end
89
+
90
+ describe "Help display integration" do
91
+ let(:config) do
92
+ {
93
+ "option1" => "--option1 $value",
94
+ "option2" => "--option2 $value"
95
+ }
96
+ end
97
+
98
+ context "with custom README" do
99
+ before do
100
+ RakeOptions.initialize_readme("Custom Help Documentation\n\nUsage: rake task [options]")
101
+ end
102
+
103
+ it "displays custom README and exits" do
104
+ stub_const("ARGV", ["--help"])
105
+
106
+ expect { RakeOptions.command_line_args(config) }
107
+ .to output(/Custom Help Documentation/).to_stdout
108
+ .and raise_error(SystemExit) { |error| expect(error.status).to eq(0) }
109
+ end
110
+ end
111
+
112
+ context "with auto-generated help" do
113
+ before do
114
+ RakeOptions.readme_content = nil
115
+ end
116
+
117
+ it "displays auto-generated help and exits" do
118
+ stub_const("ARGV", ["--help"])
119
+
120
+ expect { RakeOptions.command_line_args(config) }
121
+ .to output(/Available Options/).to_stdout
122
+ .and raise_error(SystemExit) { |error| expect(error.status).to eq(0) }
123
+ end
124
+
125
+ it "includes all configured options in help" do
126
+ stub_const("ARGV", ["--help"])
127
+
128
+ expect { RakeOptions.command_line_args(config) }
129
+ .to output(/--option1/).to_stdout
130
+ .and raise_error(SystemExit)
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "Mixed scenarios" do
136
+ let(:config) do
137
+ {
138
+ "database" => "--config $file --env $environment",
139
+ "verbose" => "--verbose $level"
140
+ }
141
+ end
142
+
143
+ it "handles templates with multiple variables" do
144
+ stub_const("ARGV", ["--config", "database.yml", "--env", "production", "--verbose", "debug"])
145
+
146
+ result = RakeOptions.command_line_args(config, notation: :cli)
147
+
148
+ expect(result["database"]).to be_a(Hash)
149
+ expect(result["database"]["file"]).to eq("database.yml")
150
+ expect(result["database"]["environment"]).to eq("production")
151
+ expect(result["verbose"]).to eq("debug")
152
+ end
153
+
154
+ it "handles empty ARGV" do
155
+ stub_const("ARGV", [])
156
+
157
+ result = RakeOptions.command_line_args(config, notation: :cli)
158
+
159
+ expect(result["database"]).to be_nil
160
+ expect(result["verbose"]).to be_nil
161
+ end
162
+
163
+ it "ignores unrecognized arguments" do
164
+ stub_const("ARGV", ["--unknown-flag", "value", "--verbose", "info"])
165
+
166
+ result = RakeOptions.command_line_args(config, notation: :cli)
167
+
168
+ expect(result["verbose"]).to eq("info")
169
+ expect(result["database"]).to be_nil
170
+ end
171
+ end
172
+
173
+ describe "Error scenarios" do
174
+ let(:config) do
175
+ {
176
+ "option" => "--option $value"
177
+ }
178
+ end
179
+
180
+ it "raises InvalidNotationError for unsupported notation" do
181
+ stub_const("ARGV", ["--option", "value"])
182
+
183
+ expect { RakeOptions.command_line_args(config, notation: :invalid) }
184
+ .to raise_error(RakeOptions::InvalidNotationError, /Invalid notation/)
185
+ end
186
+
187
+ it "provides clear error message with supported notations" do
188
+ stub_const("ARGV", ["--option", "value"])
189
+
190
+ expect { RakeOptions.command_line_args(config, notation: :xml) }
191
+ .to raise_error(RakeOptions::InvalidNotationError, /:cli, :bracket/)
192
+ end
193
+ end
194
+
195
+ describe "Real-world usage scenarios" do
196
+ context "deployment task" do
197
+ let(:deploy_config) do
198
+ {
199
+ "environment" => "--env $environment",
200
+ "region" => "--region $region",
201
+ "version" => "--version $ver",
202
+ "dry-run" => "--dry-run $flag"
203
+ }
204
+ end
205
+
206
+ it "handles typical deployment command" do
207
+ stub_const("ARGV", ["--env", "production", "--region", "us-east-1", "--version", "v1.2.3"])
208
+
209
+ result = RakeOptions.command_line_args(deploy_config)
210
+
211
+ expect(result[:environment]).to eq("production")
212
+ expect(result[:region]).to eq("us-east-1")
213
+ expect(result[:version]).to eq("v1.2.3")
214
+ expect(result[:dry_run]).to be_nil
215
+ end
216
+ end
217
+
218
+ context "build task" do
219
+ let(:build_config) do
220
+ {
221
+ "with-mysql" => "--with-mysql-lib $path",
222
+ "with-ssl" => "--with-ssl-lib $path",
223
+ "prefix" => "--prefix $path"
224
+ }
225
+ end
226
+
227
+ it "handles build configuration" do
228
+ stub_const("ARGV", [
229
+ "--with-mysql-lib", "/usr/local/mysql/lib",
230
+ "--with-ssl-lib", "/usr/local/ssl/lib",
231
+ "--prefix", "/opt/myapp"
232
+ ])
233
+
234
+ result = RakeOptions.command_line_args(build_config)
235
+
236
+ expect(result["with-mysql"]).to eq("/usr/local/mysql/lib")
237
+ expect(result["with-ssl"]).to eq("/usr/local/ssl/lib")
238
+ expect(result["prefix"]).to eq("/opt/myapp")
239
+ end
240
+ end
241
+ end
242
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "rake_options/argument_parser"
5
+
6
+ RSpec.describe RakeOptions::ArgumentParser do
7
+ let(:config) do
8
+ {
9
+ "option1" => "--option1 $value"
10
+ }
11
+ end
12
+
13
+ describe "#initialize" do
14
+ context "with valid notation" do
15
+ it "accepts :cli notation" do
16
+ expect { described_class.new(config, :cli) }.not_to raise_error
17
+ end
18
+
19
+ it "accepts :bracket notation" do
20
+ expect { described_class.new(config, :bracket) }.not_to raise_error
21
+ end
22
+ end
23
+
24
+ context "with invalid notation" do
25
+ it "raises InvalidNotationError" do
26
+ expect { described_class.new(config, :invalid) }.to raise_error(RakeOptions::InvalidNotationError)
27
+ end
28
+
29
+ it "provides helpful error message" do
30
+ expect { described_class.new(config, :invalid) }.to raise_error(
31
+ RakeOptions::InvalidNotationError,
32
+ /Invalid notation ':invalid'. Supported notations: :cli, :bracket/
33
+ )
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#parse" do
39
+ context "with CLI notation" do
40
+ let(:parser) { described_class.new(config, :cli) }
41
+
42
+ it "uses CLIParser" do
43
+ expect(RakeOptions::CLIParser).to receive(:new).with(config).and_call_original
44
+ parser.parse
45
+ end
46
+ end
47
+
48
+ context "with bracket notation" do
49
+ let(:parser) { described_class.new(config, :bracket) }
50
+
51
+ it "uses BracketParser" do
52
+ expect(RakeOptions::BracketParser).to receive(:new).with(config).and_call_original
53
+ parser.parse
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#select_parser" do
59
+ it "returns CLIParser for :cli notation" do
60
+ parser = described_class.new(config, :cli)
61
+ selected = parser.send(:select_parser)
62
+ expect(selected).to be_a(RakeOptions::CLIParser)
63
+ end
64
+
65
+ it "returns BracketParser for :bracket notation" do
66
+ parser = described_class.new(config, :bracket)
67
+ selected = parser.send(:select_parser)
68
+ expect(selected).to be_a(RakeOptions::BracketParser)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "rake_options/bracket_parser"
5
+
6
+ RSpec.describe RakeOptions::BracketParser do
7
+ describe "#parse" do
8
+ context "with simple key=value" do
9
+ let(:config) do
10
+ {
11
+ "environment" => "[environment=$env]",
12
+ "region" => "[region=$region]"
13
+ }
14
+ end
15
+ let(:parser) { described_class.new(config) }
16
+
17
+ it "parses [key=value] format" do
18
+ argv = ["[environment=production]", "[region=us-west-2]"]
19
+ result = parser.parse(argv)
20
+
21
+ expect(result["environment"]).to eq("production")
22
+ expect(result["region"]).to eq("us-west-2")
23
+ end
24
+
25
+ it "returns nil for missing arguments" do
26
+ argv = ["[environment=production]"]
27
+ result = parser.parse(argv)
28
+
29
+ expect(result["environment"]).to eq("production")
30
+ expect(result["region"]).to be_nil
31
+ end
32
+ end
33
+
34
+ context "with quoted values" do
35
+ let(:config) do
36
+ {
37
+ "message" => "[message=$text]"
38
+ }
39
+ end
40
+ let(:parser) { described_class.new(config) }
41
+
42
+ it "parses [key=\"value with spaces\"] format" do
43
+ argv = ['[message="Hello World"]']
44
+ result = parser.parse(argv)
45
+
46
+ expect(result["message"]).to eq("Hello World")
47
+ end
48
+ end
49
+
50
+ context "with multiple bracket arguments" do
51
+ let(:config) do
52
+ {
53
+ "env" => "[env=$environment]",
54
+ "region" => "[region=$reg]",
55
+ "instance" => "[instance=$type]"
56
+ }
57
+ end
58
+ let(:parser) { described_class.new(config) }
59
+
60
+ it "parses multiple bracket arguments" do
61
+ argv = ["[env=prod]", "[region=us-east-1]", "[instance=t2.micro]"]
62
+ result = parser.parse(argv)
63
+
64
+ expect(result["env"]).to eq("prod")
65
+ expect(result["region"]).to eq("us-east-1")
66
+ expect(result["instance"]).to eq("t2.micro")
67
+ end
68
+ end
69
+
70
+ context "with malformed brackets" do
71
+ let(:config) do
72
+ {
73
+ "valid" => "[valid=$val]"
74
+ }
75
+ end
76
+ let(:parser) { described_class.new(config) }
77
+
78
+ it "ignores malformed bracket arguments" do
79
+ argv = ["[valid=test]", "invalid=value", "[missing-bracket"]
80
+ result = parser.parse(argv)
81
+
82
+ expect(result["valid"]).to eq("test")
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "rake_options/cli_parser"
5
+
6
+ RSpec.describe RakeOptions::CLIParser do
7
+ describe "#parse" do
8
+ context "with single flag" do
9
+ let(:config) do
10
+ {
11
+ "with-mysql-lib" => "--with-mysql-lib $path"
12
+ }
13
+ end
14
+ let(:parser) { described_class.new(config) }
15
+
16
+ it "parses single flag with value" do
17
+ argv = ["--with-mysql-lib", "/usr/local/mysql/lib"]
18
+ result = parser.parse(argv)
19
+
20
+ expect(result["with-mysql-lib"]).to eq("/usr/local/mysql/lib")
21
+ end
22
+
23
+ it "returns nil for missing argument" do
24
+ argv = []
25
+ result = parser.parse(argv)
26
+
27
+ expect(result["with-mysql-lib"]).to be_nil
28
+ end
29
+ end
30
+
31
+ context "with multiple flags" do
32
+ let(:config) do
33
+ {
34
+ "with-mysql-lib" => "--with-mysql-lib $path",
35
+ "enable-feature" => "--enable-feature $name"
36
+ }
37
+ end
38
+ let(:parser) { described_class.new(config) }
39
+
40
+ it "parses multiple flags in one invocation" do
41
+ argv = ["--with-mysql-lib", "/usr/local/lib", "--enable-feature", "caching"]
42
+ result = parser.parse(argv)
43
+
44
+ expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
45
+ expect(result["enable-feature"]).to eq("caching")
46
+ end
47
+
48
+ it "handles partial arguments" do
49
+ argv = ["--with-mysql-lib", "/usr/local/lib"]
50
+ result = parser.parse(argv)
51
+
52
+ expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
53
+ expect(result["enable-feature"]).to be_nil
54
+ end
55
+ end
56
+
57
+ context "with quoted values" do
58
+ let(:config) do
59
+ {
60
+ "message" => "--message $text"
61
+ }
62
+ end
63
+ let(:parser) { described_class.new(config) }
64
+
65
+ it "handles quoted values with spaces" do
66
+ argv = ["--message", '"Hello World"']
67
+ result = parser.parse(argv)
68
+
69
+ expect(result["message"]).to eq("Hello World")
70
+ end
71
+ end
72
+
73
+ context "with unknown flags" do
74
+ let(:config) do
75
+ {
76
+ "known-flag" => "--known-flag $value"
77
+ }
78
+ end
79
+ let(:parser) { described_class.new(config) }
80
+
81
+ it "ignores unknown flags without raising errors" do
82
+ argv = ["--unknown-flag", "value", "--known-flag", "test"]
83
+
84
+ expect { parser.parse(argv) }.not_to raise_error
85
+ result = parser.parse(argv)
86
+ expect(result["known-flag"]).to eq("test")
87
+ end
88
+ end
89
+
90
+ context "with multiple variables in template" do
91
+ let(:config) do
92
+ {
93
+ "database" => "--config $file --env $environment"
94
+ }
95
+ end
96
+ let(:parser) { described_class.new(config) }
97
+
98
+ it "extracts multiple variables" do
99
+ argv = ["--config", "database.yml", "--env", "production"]
100
+ result = parser.parse(argv)
101
+
102
+ expect(result["database"]).to be_a(Hash)
103
+ expect(result["database"]["file"]).to eq("database.yml")
104
+ expect(result["database"]["environment"]).to eq("production")
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "rake_options/help_generator"
5
+
6
+ RSpec.describe RakeOptions::HelpGenerator do
7
+ describe "#display_and_exit" do
8
+ let(:config) do
9
+ {
10
+ "with-mysql-lib" => "--with-mysql-lib $path",
11
+ "enable-feature" => "--enable-feature $name"
12
+ }
13
+ end
14
+
15
+ context "with custom README" do
16
+ let(:readme) { "Custom Help Text\n\nUsage instructions here" }
17
+ let(:generator) { described_class.new(config, readme) }
18
+
19
+ it "displays custom README content" do
20
+ expect { generator.display_and_exit }.to output(/Custom Help Text/).to_stdout.and raise_error(SystemExit)
21
+ end
22
+ end
23
+
24
+ context "without custom README" do
25
+ let(:generator) { described_class.new(config) }
26
+
27
+ it "auto-generates help from config" do
28
+ expect { generator.display_and_exit }.to output(/Available Options/).to_stdout.and raise_error(SystemExit)
29
+ end
30
+
31
+ it "includes all configured options" do
32
+ expect { generator.display_and_exit }.to output(/--with-mysql-lib/).to_stdout.and raise_error(SystemExit)
33
+ end
34
+ end
35
+
36
+ context "exit behavior" do
37
+ let(:generator) { described_class.new(config) }
38
+
39
+ it "exits with status 0" do
40
+ expect { generator.display_and_exit }.to raise_error(SystemExit) do |error|
41
+ expect(error.status).to eq(0)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ describe "#generate_help_text" do
48
+ let(:config) do
49
+ {
50
+ "option1" => "--option1 $value",
51
+ "option2" => "--option2 $value"
52
+ }
53
+ end
54
+
55
+ context "with custom README" do
56
+ let(:readme) { "My Custom Help" }
57
+ let(:generator) { described_class.new(config, readme) }
58
+
59
+ it "returns custom README" do
60
+ help_text = generator.send(:generate_help_text)
61
+ expect(help_text).to eq("My Custom Help")
62
+ end
63
+ end
64
+
65
+ context "without custom README" do
66
+ let(:generator) { described_class.new(config) }
67
+
68
+ it "generates help from config" do
69
+ help_text = generator.send(:generate_help_text)
70
+ expect(help_text).to include("Available Options")
71
+ expect(help_text).to include("--option1")
72
+ expect(help_text).to include("--option2")
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "#format_option" do
78
+ let(:generator) { described_class.new({}) }
79
+
80
+ it "formats option with key and template" do
81
+ formatted = generator.send(:format_option, "my-option", "--my-option $value")
82
+ expect(formatted).to include("--my-option $value")
83
+ expect(formatted).to include("my-option")
84
+ end
85
+ end
86
+ end