drudge 0.4.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,71 @@
1
+ require 'spec_helper'
2
+ require 'drudge/parsers/tokenizer'
3
+
4
+ class Drudge
5
+
6
+ module Parsers
7
+ describe Tokenizer do
8
+
9
+ describe ".tokenize" do
10
+
11
+ it "converts an array of command line arguments into an array of sexps" do
12
+ tokens = Tokenizer.tokenize(%w[hello world])
13
+
14
+ expect(tokens).to be_kind_of(Enumerable)
15
+
16
+ tokens.each do |type, arg, meta|
17
+ expect(type).to eq :val
18
+ expect(arg).to be_kind_of(String)
19
+ expect(meta).to include(:loc)
20
+ end
21
+ end
22
+
23
+ it "converts an ordinary argument 'arg' into the sexp [:val, 'arg']" do
24
+ tokens = Tokenizer.tokenize(%w[hello world])
25
+
26
+ expect(tokens).to eq [[:val, 'hello', {loc: [0, 0, 5]}],
27
+ [:val, 'world', {loc: [1, 0, 5]}]]
28
+ end
29
+ end
30
+
31
+ describe ".untokenize" do
32
+ let(:sexps) { [[:val, 'hello', {loc: [0, 0, 5]}],
33
+ [:val, 'dear', {loc: [1, 0, 4]}],
34
+ [:val, 'world', {loc: [2, 0, 5]}]] }
35
+
36
+ it "converts an array of s-exps into a string" do
37
+ expect(Tokenizer.untokenize(sexps)).to eq "hello dear world"
38
+ end
39
+ end
40
+
41
+ describe ".underline_token" do
42
+ let(:sexps) { [[:val, 'hello', {loc: [0, 0, 5]}],
43
+ [:val, 'dear', {loc: [1, 0, 4]}],
44
+ [:val, 'world', {loc: [2, 0, 5]}]] }
45
+
46
+ it "underlines first token" do
47
+ expect(Tokenizer.underline_token(sexps, sexps[0])).to eq "~~~~~"
48
+ end
49
+
50
+ it "underlines the second token" do
51
+ expect(Tokenizer.underline_token(sexps, sexps[1])).to eq " ~~~~"
52
+ end
53
+
54
+ it "underlines the third token" do
55
+ expect(Tokenizer.underline_token(sexps, sexps[2])).to eq " ~~~~~"
56
+ end
57
+
58
+ it "underlines the end of string when token is nil" do
59
+ expect(Tokenizer.underline_token(sexps, nil)).to eq " ^"
60
+ end
61
+
62
+ it "can be told which underline char to use" do
63
+ expect(Tokenizer.underline_token(sexps, sexps[0], underline_char: "-")).to eq "-----"
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ end
70
+ end
71
+
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ require 'drudge/parsers'
4
+ require 'drudge/errors'
5
+
6
+ class Drudge
7
+
8
+ describe Parsers do
9
+ include Parsers
10
+
11
+ describe "#parser" do
12
+ it "takes a block and extends it with ArgumentParser" do
13
+ p = parser { |input| EOS }
14
+
15
+ expect(p).to be_kind_of(Parsers::ArgumentParser)
16
+ end
17
+ end
18
+
19
+ describe "basic parsers" do
20
+ describe ".value" do
21
+ context "without arguments" do
22
+ subject { value }
23
+
24
+ it { should parse([[:val, "test"]]).as("test") }
25
+ it { should_not parse([[:foo, "bar"]]) }
26
+ it { should_not parse([]) }
27
+ it { should_not parse(nil) }
28
+ end
29
+
30
+ context "with a string argument 'something'" do
31
+ subject { value("something") }
32
+
33
+ it { should parse([[:val, "something"]]).as("something") }
34
+ it { should_not parse([[:val, "something else"]]) }
35
+ it { should_not parse([[:foo, "bar"]]) }
36
+ end
37
+
38
+ context "with a regexp argument /^ab.+/" do
39
+ subject { value(/^ab.+/) }
40
+
41
+ it { should parse([[:val, "abc"]]).as("abc") }
42
+ it { should parse([[:val, "abd"]]).as("abd") }
43
+ it { should_not parse([[:val, "cabc"]]) }
44
+ it { should_not parse([[:val, "something else"]]) }
45
+ it { should_not parse([[:foo, "bar"]]) }
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "command & argument parsers" do
51
+
52
+ describe ".arg" do
53
+
54
+ context "with a single argument" do
55
+ context "arg parser for the arg named 'test'" do
56
+ subject { arg(:test) }
57
+
58
+ it { should tokenize_and_parse(%w[anything]).as([:arg, "anything"]) }
59
+
60
+ it "should include the expected paraemeter name in the error message" do
61
+ expect(subject.call([])).to eq(Failure("expected a value for <test>", []))
62
+ end
63
+ end
64
+
65
+ context "arg sequence" do
66
+ subject { arg(:first) > arg(:second) }
67
+
68
+ it { should tokenize_and_parse(%w[arg1 arg2]).as([[:arg, "arg1"], [:arg, "arg2"]]) }
69
+ it { should_not tokenize_and_parse(%w[arg1]) }
70
+ it { should_not tokenize_and_parse(%w[]) }
71
+ end
72
+
73
+ context "arg sequence with :eos" do
74
+ let(:p) { arg(:first) > arg(:second) > eos }
75
+ subject { p }
76
+
77
+ it { should tokenize_and_parse(%w[arg1 arg2]).as([[:arg, "arg1"], [:arg, "arg2"]]) }
78
+ it { should_not tokenize_and_parse(%w[arg1 arg2 arg3]) }
79
+ end
80
+ end
81
+
82
+ context "with a provided parser" do
83
+ subject { arg(:test, value("TEST")) }
84
+ describe "arg parser that acceptes only 'TEST'" do
85
+
86
+ it { should tokenize_and_parse(%w[TEST]).as([:arg, "TEST"]) }
87
+
88
+ it { should_not tokenize_and_parse(%w[anything]) }
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ describe ".command" do
96
+ context "command parser for command 'hello'" do
97
+ subject { command("hello") }
98
+
99
+ it { should tokenize_and_parse(%w[hello]).as([:arg, "hello"]) }
100
+ it { should_not tokenize_and_parse(%w[HELLO]) }
101
+ end
102
+ end
103
+
104
+ describe "collated arguments" do
105
+ let(:p) { command("hello") > arg(:first) > arg(:second) <= eos }
106
+ subject { p.collated_arguments }
107
+
108
+ it { should tokenize_and_parse(%w[hello first second]).as({args: %w[hello first second]}) }
109
+ end
110
+
111
+
112
+ end
113
+
114
+
115
+ describe Parsers::ArgumentParser do
116
+ include Parsers::ParseResults
117
+
118
+ context "a parser built with #parser" do
119
+ subject do
120
+ parser do |input|
121
+ if input[0][0] == :val && input[0][1] == "hello"
122
+ Success(Single(input[0][1]), input.drop(1))
123
+ else
124
+ Failure("f", input)
125
+ end
126
+ end
127
+ end
128
+
129
+ describe "#parse" do
130
+ it "tokenizes an array of [command line] args and parses it at once" do
131
+
132
+ expect(subject.parse(%w[hello world])).to eq(Success(Single("hello"), [[:val, "world", {:loc=>[1, 0, 5]}]]))
133
+ end
134
+ end
135
+
136
+ describe "#parse!" do
137
+ it "is like #parse, but returns just the result when successful" do
138
+ expect(subject.parse!(%w[hello world])).to eq("hello")
139
+ end
140
+
141
+ it "upon failed parse, it raises a CommandArgumentError" do
142
+ expect { subject.parse!(%w[world hello])}.to raise_error(ParseError)
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ end
149
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ Dir["./spec/support/**/*.rb"].each {|f| require f}
@@ -0,0 +1,16 @@
1
+ # captures the STDOUT output produced by the provided block
2
+ def capture
3
+ original_stdout = $stdout
4
+ $stdout = fake = StringIO.new
5
+ begin
6
+ yield
7
+ ensure
8
+ $stdout = original_stdout
9
+ end
10
+ fake.string
11
+ end
12
+
13
+
14
+ def expect_capture(&block)
15
+ expect(capture &block)
16
+ end
@@ -0,0 +1,13 @@
1
+ require 'drudge/command'
2
+
3
+ def dummy_cmd(name, args = [])
4
+ Drudge::Command.new(name, args, -> { puts name } )
5
+ end
6
+
7
+ def splash_param(name)
8
+ Drudge::Param.any(name, splatt: true)
9
+ end
10
+
11
+ def optional_param(name)
12
+ Drudge::Param.any(name, optional: true)
13
+ end
@@ -0,0 +1,42 @@
1
+ require 'drudge/parsers/tokenizer'
2
+
3
+ RSpec::Matchers.define :parse do |input|
4
+ match do |parser|
5
+ res = parser.call(input)
6
+
7
+ res.success? and
8
+ res.remaining != input and
9
+ (res.result == @expected_output or not @expected_output)
10
+ end
11
+
12
+ chain :as do |expected_output|
13
+ @expected_output = expected_output
14
+ end
15
+ end
16
+
17
+ RSpec::Matchers.define :tokenize_and_parse do |input|
18
+ chain :as do |expected_output|
19
+ @expected_output = expected_output
20
+ end
21
+
22
+ match do |parser|
23
+ res = do_parse(parser, input)
24
+
25
+ res.success? and
26
+ (res.result == @expected_output or not @expected_output)
27
+ end
28
+
29
+ failure_message_for_should do |parser|
30
+ res = do_parse(parser, input)
31
+
32
+ if @expected_output and res.success?
33
+ "expected that \"#{parser}\"'s result would be #{@expected_output}, was '#{res.result}'"
34
+ else
35
+ "expected that #{parser} should tokenize and parse '#{input}'"
36
+ end
37
+ end
38
+
39
+ def do_parse(parser, input)
40
+ parser.call(Drudge::Parsers::Tokenizer.tokenize(input))
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,219 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: drudge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Ognen Ivanovski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '2.14'
62
+ - - <
63
+ - !ruby/object:Gem::Version
64
+ version: '3.0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '2.14'
72
+ - - <
73
+ - !ruby/object:Gem::Version
74
+ version: '3.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: cucumber
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: aruba
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: 0.4.6
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: 0.4.6
103
+ - !ruby/object:Gem::Dependency
104
+ name: yard
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 0.8.6.1
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: 0.8.6.1
117
+ - !ruby/object:Gem::Dependency
118
+ name: gem-release
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ description: |-
132
+ A library for building command-line
133
+ automation tools with the aim of transferring you (conceptionally) from the command line
134
+ interface into Ruby and then letting you use build your tool in a familiar
135
+ environement.
136
+ email:
137
+ - ognen.ivanovski@me.com
138
+ executables: []
139
+ extensions: []
140
+ extra_rdoc_files: []
141
+ files:
142
+ - .gitignore
143
+ - Gemfile
144
+ - Gemfile.lock
145
+ - LICENSE.txt
146
+ - README.md
147
+ - Rakefile
148
+ - drudge.gemspec
149
+ - features/optional-arguments.feature
150
+ - features/simple-commands.feature
151
+ - features/step_definitions/scripts_steps.rb
152
+ - features/support/env.rb
153
+ - features/variable-length-argument-lists.feature
154
+ - lib/drudge.rb
155
+ - lib/drudge/class_dsl.rb
156
+ - lib/drudge/command.rb
157
+ - lib/drudge/dispatch.rb
158
+ - lib/drudge/errors.rb
159
+ - lib/drudge/ext.rb
160
+ - lib/drudge/kit.rb
161
+ - lib/drudge/parsers.rb
162
+ - lib/drudge/parsers/parse_results.rb
163
+ - lib/drudge/parsers/primitives.rb
164
+ - lib/drudge/parsers/tokenizer.rb
165
+ - lib/drudge/version.rb
166
+ - spec/drudge/class_dsl_spec.rb
167
+ - spec/drudge/command_spec.rb
168
+ - spec/drudge/kit_spec.rb
169
+ - spec/drudge/parsers/parse_results_spec.rb
170
+ - spec/drudge/parsers/primitives_spec.rb
171
+ - spec/drudge/parsers/tokenizer_spec.rb
172
+ - spec/drudge/parsers_spec.rb
173
+ - spec/spec_helper.rb
174
+ - spec/support/capture.rb
175
+ - spec/support/fixtures.rb
176
+ - spec/support/parser_matchers.rb
177
+ homepage: https://github.com/ognen/drudge
178
+ licenses:
179
+ - MIT
180
+ metadata: {}
181
+ post_install_message:
182
+ rdoc_options: []
183
+ require_paths:
184
+ - lib
185
+ required_ruby_version: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - '>='
188
+ - !ruby/object:Gem::Version
189
+ version: 2.0.0
190
+ required_rubygems_version: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ requirements: []
196
+ rubyforge_project:
197
+ rubygems_version: 2.0.14
198
+ signing_key:
199
+ specification_version: 4
200
+ summary: A gem that enables you to write command line automation tools using Ruby
201
+ 2.0.
202
+ test_files:
203
+ - features/optional-arguments.feature
204
+ - features/simple-commands.feature
205
+ - features/step_definitions/scripts_steps.rb
206
+ - features/support/env.rb
207
+ - features/variable-length-argument-lists.feature
208
+ - spec/drudge/class_dsl_spec.rb
209
+ - spec/drudge/command_spec.rb
210
+ - spec/drudge/kit_spec.rb
211
+ - spec/drudge/parsers/parse_results_spec.rb
212
+ - spec/drudge/parsers/primitives_spec.rb
213
+ - spec/drudge/parsers/tokenizer_spec.rb
214
+ - spec/drudge/parsers_spec.rb
215
+ - spec/spec_helper.rb
216
+ - spec/support/capture.rb
217
+ - spec/support/fixtures.rb
218
+ - spec/support/parser_matchers.rb
219
+ has_rdoc: