manamana 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +12 -2
- data/README.md +28 -1
- data/bin/mana +33 -2
- data/lib/manamana.rb +1 -0
- data/lib/manamana/compiler.rb +4 -3
- data/lib/manamana/paths.rb +7 -0
- data/lib/manamana/rdsl/lexer.rb +5 -5
- data/lib/manamana/rdsl/nodes.rb +24 -9
- data/lib/manamana/rdsl/parser.rb +6 -6
- data/lib/manamana/runner.rb +2 -3
- data/lib/manamana/version.rb +1 -1
- data/manamana.gemspec +1 -0
- data/src/rdsl/lexer.rl +5 -5
- data/src/rdsl/parser.y +6 -6
- data/test/lib/manamana/rdsl/lexer_test.rb +48 -42
- data/test/lib/manamana/rdsl/parser_test.rb +58 -58
- data/test/lib/manamana/rdsl/requirements_node_test.rb +6 -6
- metadata +23 -5
- data/.rvmrc +0 -16
data/.gitignore
CHANGED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
manamana
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-1.9.3-p392
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -9,13 +9,21 @@ GIT
|
|
9
9
|
PATH
|
10
10
|
remote: .
|
11
11
|
specs:
|
12
|
-
manamana (0.0.
|
12
|
+
manamana (0.0.3)
|
13
13
|
racc (= 1.4.9)
|
14
|
+
thor (~> 0.18.0)
|
14
15
|
|
15
16
|
GEM
|
16
17
|
remote: https://rubygems.org/
|
17
18
|
specs:
|
18
19
|
coderay (1.0.9)
|
20
|
+
columnize (0.3.6)
|
21
|
+
debugger (1.5.0)
|
22
|
+
columnize (>= 0.3.1)
|
23
|
+
debugger-linecache (~> 1.2.0)
|
24
|
+
debugger-ruby_core_source (~> 1.2.0)
|
25
|
+
debugger-linecache (1.2.0)
|
26
|
+
debugger-ruby_core_source (1.2.0)
|
19
27
|
guard (1.6.2)
|
20
28
|
listen (>= 0.6.0)
|
21
29
|
lumberjack (>= 1.0.2)
|
@@ -41,18 +49,20 @@ GEM
|
|
41
49
|
ruby_gntp (0.3.4)
|
42
50
|
slop (3.4.3)
|
43
51
|
terminal-table (1.4.5)
|
44
|
-
thor (0.
|
52
|
+
thor (0.18.1)
|
45
53
|
|
46
54
|
PLATFORMS
|
47
55
|
ruby
|
48
56
|
|
49
57
|
DEPENDENCIES
|
58
|
+
debugger
|
50
59
|
guard
|
51
60
|
guard-minitest
|
52
61
|
guard-rake
|
53
62
|
manamana!
|
54
63
|
minitest
|
55
64
|
minitest-colorize!
|
65
|
+
pry
|
56
66
|
racc
|
57
67
|
rb-fsevent (~> 0.9)
|
58
68
|
ruby_gntp
|
data/README.md
CHANGED
@@ -119,7 +119,8 @@ Run `mana start` to execute the tests and validate the requirements:
|
|
119
119
|
```
|
120
120
|
$ mana start
|
121
121
|
Run options: --seed 51346
|
122
|
-
|
122
|
+
|
123
|
+
## Running tests
|
123
124
|
|
124
125
|
Create Tickets
|
125
126
|
==============
|
@@ -148,3 +149,29 @@ Finished tests in 0.004842s, 1445.6836 tests/s, 826.1049 assertions/s.
|
|
148
149
|
|
149
150
|
7 tests, 4 assertions, 0 failures, 0 errors, 0 skips
|
150
151
|
```
|
152
|
+
|
153
|
+
## Development guide
|
154
|
+
If you want to help in developing ManaMana, fork this project at [https://github.com/ManaManaFramework/manamana](https://github.com/ManaManaFramework/manamana), then clone it locally. A few requirements before proceeding:
|
155
|
+
|
156
|
+
* RVM
|
157
|
+
* Homebrew on Mac OS X
|
158
|
+
* git
|
159
|
+
* growl on Mac OS X
|
160
|
+
|
161
|
+
Once the above have been installed, go to the manamana project directory and install the required gems:
|
162
|
+
|
163
|
+
```
|
164
|
+
bundle install
|
165
|
+
```
|
166
|
+
|
167
|
+
Afterwards, install ragel. For Mac OS X, use Homebrew:
|
168
|
+
|
169
|
+
```
|
170
|
+
brew install ragel
|
171
|
+
```
|
172
|
+
|
173
|
+
Now you can start developing! Open the project folder with your favorit text editor, then, on your terminal window, run guard from the project directory:
|
174
|
+
|
175
|
+
```
|
176
|
+
guard
|
177
|
+
```
|
data/bin/mana
CHANGED
@@ -1,7 +1,38 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'bundler/setup'
|
3
3
|
require 'manamana'
|
4
|
+
require 'thor'
|
4
5
|
|
5
6
|
include ManaMana
|
6
|
-
|
7
|
-
|
7
|
+
|
8
|
+
class ManaManaCLI < Thor
|
9
|
+
|
10
|
+
desc "exec", "Executes the requirements and associated test cases."
|
11
|
+
def exec
|
12
|
+
Compiler.new.start
|
13
|
+
Runner.new.start
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "create PROJECT_NAME", "Initializes a ManaMana directory named PROJECT_NAME"
|
17
|
+
def create(project_name)
|
18
|
+
[
|
19
|
+
project_name,
|
20
|
+
File.join(project_name, ManaMana::REQUIREMENTS_PATH),
|
21
|
+
File.join(project_name, ManaMana::TEST_CASES_PATH),
|
22
|
+
File.join(project_name, ManaMana::LIB_PATH),
|
23
|
+
File.join(project_name, ManaMana::STEPDEFS_PATH),
|
24
|
+
File.join(project_name, ManaMana::HELPERS_PATH)
|
25
|
+
].each do |rel_path|
|
26
|
+
abs_path = File.join(Dir.pwd, rel_path)
|
27
|
+
|
28
|
+
if Dir.exists? abs_path
|
29
|
+
puts "Exists #{rel_path}"
|
30
|
+
else
|
31
|
+
puts "Create #{rel_path}"
|
32
|
+
Dir.mkdir abs_path
|
33
|
+
end #if
|
34
|
+
end # each
|
35
|
+
end # def
|
36
|
+
end # class
|
37
|
+
|
38
|
+
ManaManaCLI.start(ARGV)
|
data/lib/manamana.rb
CHANGED
data/lib/manamana/compiler.rb
CHANGED
@@ -2,9 +2,10 @@ module ManaMana
|
|
2
2
|
|
3
3
|
class Compiler
|
4
4
|
def start(options = {})
|
5
|
-
options[:requirements_path] = File.join(Dir.pwd,
|
6
|
-
options[:test_cases_path] = File.join(Dir.pwd,
|
7
|
-
options[:
|
5
|
+
options[:requirements_path] = File.join(Dir.pwd, ManaMana::REQUIREMENTS_PATH)
|
6
|
+
options[:test_cases_path] = File.join(Dir.pwd, ManaMana::TEST_CASES_PATH)
|
7
|
+
options[:stepdefs_path] = File.join(Dir.pwd, ManaMana::STEPDEFS_PATH)
|
8
|
+
options[:helpers_path] = File.join(Dir.pwd, ManaMana::HELPERS_PATH)
|
8
9
|
options[:output_path] = File.join(Dir.pwd, '__spec__.rb')
|
9
10
|
@options = options
|
10
11
|
|
data/lib/manamana/rdsl/lexer.rb
CHANGED
@@ -205,7 +205,7 @@ self.lexer_en_main = 21;
|
|
205
205
|
|
206
206
|
def emit_group_name(token_array, data, ts, te)
|
207
207
|
value = data[ts...te].pack("c*").split(/=+/)[0].strip
|
208
|
-
token_array << [:GROUP, value]
|
208
|
+
token_array << [:GROUP, { value: value, offset: ts }]
|
209
209
|
end
|
210
210
|
|
211
211
|
def emit_row(data, target_array, ts, te)
|
@@ -214,20 +214,20 @@ self.lexer_en_main = 21;
|
|
214
214
|
# ignore borders
|
215
215
|
return if /^\-+/ =~ cells
|
216
216
|
|
217
|
-
target_array << [:ROW,
|
217
|
+
target_array << [:ROW, { offset: ts }]
|
218
218
|
cells.split('|').each do |cell|
|
219
|
-
target_array << [:CELL, cell.strip]
|
219
|
+
target_array << [:CELL, { value: cell.strip }]
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
223
|
def emit_requirement(token_array, data, ts, te)
|
224
224
|
value = data[ts...te].pack("c*").gsub(/^\* /, '').split.join(' ')
|
225
|
-
token_array << [:REQUIREMENT, value]
|
225
|
+
token_array << [:REQUIREMENT, { value: value, offset: ts }]
|
226
226
|
end
|
227
227
|
|
228
228
|
def emit_text(token_array, data, ts, te)
|
229
229
|
value = data[ts...te].pack("c*").strip.split.join(' ')
|
230
|
-
token_array << [:TEXT, value]
|
230
|
+
token_array << [:TEXT, { value: value, offset: ts }]
|
231
231
|
end
|
232
232
|
|
233
233
|
def tokenize(data)
|
data/lib/manamana/rdsl/nodes.rb
CHANGED
@@ -5,15 +5,28 @@ module ManaMana
|
|
5
5
|
class Node
|
6
6
|
attr_reader :children, :name
|
7
7
|
|
8
|
-
def initialize(
|
8
|
+
def initialize(options={}, children=[])
|
9
9
|
@children = children
|
10
|
-
@name =
|
10
|
+
@name = options[:value] || ''
|
11
11
|
end
|
12
12
|
|
13
13
|
def ==(other_node)
|
14
14
|
name == other_node.name && @children == other_node.children
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
class NodeWithOffset < Node
|
19
|
+
attr_reader :offset
|
20
|
+
|
21
|
+
def initialize(options={}, children=[])
|
22
|
+
@offset = options[:offset] || nil
|
23
|
+
super options, children
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(other_node)
|
27
|
+
super(other_node) && @offset == other_node.offset
|
28
|
+
end
|
29
|
+
end
|
17
30
|
|
18
31
|
class RootNode < Node
|
19
32
|
def all_requirements
|
@@ -25,7 +38,7 @@ module ManaMana
|
|
25
38
|
end
|
26
39
|
end
|
27
40
|
|
28
|
-
class GroupNode <
|
41
|
+
class GroupNode < NodeWithOffset
|
29
42
|
def all_requirements
|
30
43
|
requirements.map{ |r| r.expand }.flatten
|
31
44
|
end
|
@@ -35,12 +48,14 @@ module ManaMana
|
|
35
48
|
end
|
36
49
|
end
|
37
50
|
|
38
|
-
class RequirementNode <
|
51
|
+
class RequirementNode < NodeWithOffset
|
39
52
|
def examples
|
40
|
-
#
|
41
|
-
# RowNode.new(
|
42
|
-
# RowNode.new(
|
53
|
+
# RowNodes initialized this way:
|
54
|
+
# RowNode.new({ value: ['Role', 'Can or Cannot Create'], offset: XX }),
|
55
|
+
# RowNode.new({ value: ['PM', 'Can Create' ], offset: XX }),
|
56
|
+
# RowNode.new({ value: ['User', 'Cannot Create' ], offset: XX })
|
43
57
|
|
58
|
+
# ...will be returned by this method this way:
|
44
59
|
# [
|
45
60
|
# { '<Role>' => 'PM', '<Can or Cannot Create>' => 'Can Create' },
|
46
61
|
# { '<Role>' => 'User', '<Can or Cannot Create>' => 'Cannot Create' }
|
@@ -86,9 +101,9 @@ module ManaMana
|
|
86
101
|
end
|
87
102
|
|
88
103
|
|
89
|
-
class RowNode <
|
104
|
+
class RowNode < NodeWithOffset
|
90
105
|
def cells
|
91
|
-
|
106
|
+
name
|
92
107
|
end
|
93
108
|
end
|
94
109
|
|
data/lib/manamana/rdsl/parser.rb
CHANGED
@@ -150,7 +150,7 @@ module_eval(<<'.,.,', 'parser.y', 10)
|
|
150
150
|
|
151
151
|
module_eval(<<'.,.,', 'parser.y', 11)
|
152
152
|
def _reduce_2(val, _values, result)
|
153
|
-
result = RootNode.new(
|
153
|
+
result = RootNode.new({}, val[0])
|
154
154
|
result
|
155
155
|
end
|
156
156
|
.,.,
|
@@ -269,35 +269,35 @@ module_eval(<<'.,.,', 'parser.y', 39)
|
|
269
269
|
|
270
270
|
module_eval(<<'.,.,', 'parser.y', 43)
|
271
271
|
def _reduce_19(val, _values, result)
|
272
|
-
result = [ ExamplesNode.new(
|
272
|
+
result = [ ExamplesNode.new({}, val[0]) ]
|
273
273
|
result
|
274
274
|
end
|
275
275
|
.,.,
|
276
276
|
|
277
277
|
module_eval(<<'.,.,', 'parser.y', 47)
|
278
278
|
def _reduce_20(val, _values, result)
|
279
|
-
result = [ RowNode.new(
|
279
|
+
result = [ RowNode.new({ value: val[1], offset: val[0][:offset] }) ]
|
280
280
|
result
|
281
281
|
end
|
282
282
|
.,.,
|
283
283
|
|
284
284
|
module_eval(<<'.,.,', 'parser.y', 48)
|
285
285
|
def _reduce_21(val, _values, result)
|
286
|
-
result = [ RowNode.new(
|
286
|
+
result = [ RowNode.new({ value: val[1], offset: val[0][:offset] }) ] + val[2]
|
287
287
|
result
|
288
288
|
end
|
289
289
|
.,.,
|
290
290
|
|
291
291
|
module_eval(<<'.,.,', 'parser.y', 52)
|
292
292
|
def _reduce_22(val, _values, result)
|
293
|
-
result = [ val[0] ]
|
293
|
+
result = [ val[0][:value] ]
|
294
294
|
result
|
295
295
|
end
|
296
296
|
.,.,
|
297
297
|
|
298
298
|
module_eval(<<'.,.,', 'parser.y', 53)
|
299
299
|
def _reduce_23(val, _values, result)
|
300
|
-
result = [ val[0] ] + val[1]
|
300
|
+
result = [ val[0][:value] ] + val[1]
|
301
301
|
result
|
302
302
|
end
|
303
303
|
.,.,
|
data/lib/manamana/runner.rb
CHANGED
@@ -9,7 +9,7 @@ module ManaMana
|
|
9
9
|
|
10
10
|
if File.directory?(path)
|
11
11
|
recursive_require(path)
|
12
|
-
|
12
|
+
elsif File.extname(path) == '.rb'
|
13
13
|
require path
|
14
14
|
end
|
15
15
|
end
|
@@ -17,9 +17,8 @@ module ManaMana
|
|
17
17
|
|
18
18
|
def start
|
19
19
|
require 'minitest/autorun'
|
20
|
-
require 'minitest/colorize'
|
21
20
|
|
22
|
-
recursive_require File.join(Dir.pwd,
|
21
|
+
recursive_require File.join(Dir.pwd, LIB_PATH)
|
23
22
|
require File.join(Dir.pwd, '__spec__.rb')
|
24
23
|
end
|
25
24
|
end
|
data/lib/manamana/version.rb
CHANGED
data/manamana.gemspec
CHANGED
data/src/rdsl/lexer.rl
CHANGED
@@ -43,7 +43,7 @@ module ManaMana
|
|
43
43
|
|
44
44
|
def emit_group_name(token_array, data, ts, te)
|
45
45
|
value = data[ts...te].pack("c*").split(/=+/)[0].strip
|
46
|
-
token_array << [:GROUP, value]
|
46
|
+
token_array << [:GROUP, { value: value, offset: ts }]
|
47
47
|
end
|
48
48
|
|
49
49
|
def emit_row(data, target_array, ts, te)
|
@@ -52,20 +52,20 @@ module ManaMana
|
|
52
52
|
# ignore borders
|
53
53
|
return if /^\-+/ =~ cells
|
54
54
|
|
55
|
-
target_array << [:ROW,
|
55
|
+
target_array << [:ROW, { offset: ts }]
|
56
56
|
cells.split('|').each do |cell|
|
57
|
-
target_array << [:CELL, cell.strip]
|
57
|
+
target_array << [:CELL, { value: cell.strip }]
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
def emit_requirement(token_array, data, ts, te)
|
62
62
|
value = data[ts...te].pack("c*").gsub(/^\* /, '').split.join(' ')
|
63
|
-
token_array << [:REQUIREMENT, value]
|
63
|
+
token_array << [:REQUIREMENT, { value: value, offset: ts }]
|
64
64
|
end
|
65
65
|
|
66
66
|
def emit_text(token_array, data, ts, te)
|
67
67
|
value = data[ts...te].pack("c*").strip.split.join(' ')
|
68
|
-
token_array << [:TEXT, value]
|
68
|
+
token_array << [:TEXT, { value: value, offset: ts }]
|
69
69
|
end
|
70
70
|
|
71
71
|
def tokenize(data)
|
data/src/rdsl/parser.y
CHANGED
@@ -9,7 +9,7 @@ class ManaMana::RDSL::Parser
|
|
9
9
|
rule
|
10
10
|
Root:
|
11
11
|
/* empty array */ { result = RootNode.new }
|
12
|
-
| Groups { result = RootNode.new(
|
12
|
+
| Groups { result = RootNode.new({}, val[0]) }
|
13
13
|
;
|
14
14
|
|
15
15
|
Groups:
|
@@ -41,17 +41,17 @@ class ManaMana::RDSL::Parser
|
|
41
41
|
;
|
42
42
|
|
43
43
|
Table:
|
44
|
-
Rows { result = [ ExamplesNode.new(
|
44
|
+
Rows { result = [ ExamplesNode.new({}, val[0]) ] }
|
45
45
|
;
|
46
46
|
|
47
47
|
Rows:
|
48
|
-
ROW Cells { result = [ RowNode.new(
|
49
|
-
| ROW Cells Rows { result = [ RowNode.new(
|
48
|
+
ROW Cells { result = [ RowNode.new({ value: val[1], offset: val[0][:offset] }) ] }
|
49
|
+
| ROW Cells Rows { result = [ RowNode.new({ value: val[1], offset: val[0][:offset] }) ] + val[2] }
|
50
50
|
;
|
51
51
|
|
52
52
|
Cells:
|
53
|
-
CELL { result = [ val[0] ] }
|
54
|
-
| CELL Cells { result = [ val[0] ] + val[1] }
|
53
|
+
CELL { result = [ val[0][:value] ] }
|
54
|
+
| CELL Cells { result = [ val[0][:value] ] + val[1] }
|
55
55
|
;
|
56
56
|
|
57
57
|
end
|
@@ -16,7 +16,7 @@ module ManaMana
|
|
16
16
|
Create a Project
|
17
17
|
================
|
18
18
|
EOF
|
19
|
-
tokens = [ [:GROUP, 'Create a Project'] ]
|
19
|
+
tokens = [ [:GROUP, { value: 'Create a Project', offset: 17 }] ]
|
20
20
|
output.must_equal tokens
|
21
21
|
end
|
22
22
|
|
@@ -25,50 +25,56 @@ module ManaMana
|
|
25
25
|
Arbitrary text
|
26
26
|
of the unusual kind
|
27
27
|
EOF
|
28
|
-
tokens = [ [:TEXT, 'Arbitrary text of the unusual kind'] ]
|
28
|
+
tokens = [ [:TEXT, { value: 'Arbitrary text of the unusual kind', offset: 17 }] ]
|
29
29
|
output.must_equal tokens
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
it "must tokenize a requirement" do
|
33
33
|
output = tokenize <<-EOF
|
34
34
|
* A project without a name is invalid
|
35
35
|
EOF
|
36
|
-
tokens = [ [:REQUIREMENT, 'A project without a name is invalid'] ]
|
36
|
+
tokens = [ [:REQUIREMENT, { value: 'A project without a name is invalid', offset: 17 }] ]
|
37
37
|
output.must_equal tokens
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "must tokenize a requirement followed by arbitrary text" do
|
41
41
|
output = tokenize <<-EOF
|
42
42
|
* A project without a name is invalid
|
43
|
-
|
43
|
+
|
44
44
|
Example:
|
45
45
|
Arbitrary text
|
46
46
|
EOF
|
47
|
-
tokens = [
|
47
|
+
tokens = [
|
48
|
+
[:REQUIREMENT, { value: 'A project without a name is invalid', offset: 17 }],
|
49
|
+
[:TEXT, { value: 'Example: Arbitrary text', offset: 81 }]
|
50
|
+
]
|
48
51
|
output.must_equal tokens
|
49
52
|
end
|
50
|
-
|
53
|
+
|
51
54
|
it "must tokenize a multi-line requirement" do
|
52
55
|
output = tokenize <<-EOF
|
53
56
|
* A project without a
|
54
57
|
name is invalid
|
55
58
|
EOF
|
56
|
-
tokens = [ [:REQUIREMENT, 'A project without a name is invalid'] ]
|
59
|
+
tokens = [ [:REQUIREMENT, { value: 'A project without a name is invalid', offset: 17 }] ]
|
57
60
|
output.must_equal tokens
|
58
61
|
end
|
59
|
-
|
62
|
+
|
60
63
|
it "must tokenize a multi-line requirement followed by arbitrary text" do
|
61
64
|
output = tokenize <<-EOF
|
62
65
|
* A project without
|
63
66
|
a name is invalid
|
64
|
-
|
67
|
+
|
65
68
|
Example:
|
66
69
|
Arbitrary text
|
67
70
|
EOF
|
68
|
-
tokens = [
|
71
|
+
tokens = [
|
72
|
+
[:REQUIREMENT, { value: 'A project without a name is invalid', offset: 17 }],
|
73
|
+
[:TEXT, { value: 'Example: Arbitrary text', offset: 100 }]
|
74
|
+
]
|
69
75
|
output.must_equal tokens
|
70
76
|
end
|
71
|
-
|
77
|
+
|
72
78
|
it "must tokenize tables" do
|
73
79
|
output = tokenize <<-EOF
|
74
80
|
| Name | Description |
|
@@ -76,13 +82,13 @@ module ManaMana
|
|
76
82
|
| Project B | Second Project |
|
77
83
|
EOF
|
78
84
|
tokens = [
|
79
|
-
[:ROW,
|
80
|
-
[:ROW,
|
81
|
-
[:ROW,
|
85
|
+
[:ROW, { offset: 18 }], [:CELL, { value: 'Name' }], [:CELL, { value: 'Description' }],
|
86
|
+
[:ROW, { offset: 70 }], [:CELL, { value: 'Project A' }], [:CELL, { value: 'First Project' }],
|
87
|
+
[:ROW, { offset: 122 }], [:CELL, { value: 'Project B' }], [:CELL, { value: 'Second Project' }]
|
82
88
|
]
|
83
89
|
output.must_equal tokens
|
84
90
|
end
|
85
|
-
|
91
|
+
|
86
92
|
it "must ignore table borders" do
|
87
93
|
output = tokenize <<-EOF
|
88
94
|
| Name | Description |
|
@@ -91,71 +97,71 @@ module ManaMana
|
|
91
97
|
| Project B | Second Project |
|
92
98
|
EOF
|
93
99
|
tokens = [
|
94
|
-
[:ROW,
|
95
|
-
[:ROW,
|
96
|
-
[:ROW,
|
100
|
+
[:ROW, { offset: 18 }], [:CELL, { value: 'Name' }], [:CELL, { value: 'Description' }],
|
101
|
+
[:ROW, { offset: 122 }], [:CELL, { value: 'Project A' }], [:CELL, { value: 'First Project' }],
|
102
|
+
[:ROW, { offset: 174 }], [:CELL, { value: 'Project B' }], [:CELL, { value: 'Second Project' }]
|
97
103
|
]
|
98
104
|
output.must_equal tokens
|
99
105
|
end
|
100
|
-
|
106
|
+
|
101
107
|
it "must tokenize requirements with placeholders" do
|
102
108
|
output = tokenize <<-EOF
|
103
109
|
* Given <Role>
|
104
110
|
<Something>
|
105
111
|
EOF
|
106
|
-
tokens = [ [:REQUIREMENT, 'Given <Role> <Something>'] ]
|
112
|
+
tokens = [ [:REQUIREMENT, { value: 'Given <Role> <Something>', offset: 17 }] ]
|
107
113
|
output.must_equal tokens
|
108
114
|
end
|
109
|
-
|
115
|
+
|
110
116
|
it "must tokenize a full requirements file" do
|
111
117
|
output = tokenize <<-EOF
|
112
118
|
Create a Project
|
113
119
|
================
|
114
|
-
|
120
|
+
|
115
121
|
* Given a user has a role of <Role> in the system
|
116
122
|
Then he <Can or Cannot Create> projects
|
117
|
-
|
123
|
+
|
118
124
|
Examples:
|
119
125
|
| Role | Can or Cannot Create |
|
120
126
|
| Admin | Can Create |
|
121
127
|
| User | Cannot Create |
|
122
|
-
|
128
|
+
|
123
129
|
Notes:
|
124
130
|
The quick brown fox jumps over the lazy
|
125
131
|
dog. The quick brown fox jumps.
|
126
132
|
EOF
|
127
133
|
tokens = [
|
128
|
-
[:GROUP, 'Create a Project'],
|
129
|
-
[:REQUIREMENT, 'Given a user has a role of <Role> in the system Then he <Can or Cannot Create> projects'],
|
130
|
-
[:TEXT, 'Examples:'],
|
131
|
-
[:ROW,
|
132
|
-
[:ROW,
|
133
|
-
[:ROW,
|
134
|
-
[:TEXT, 'Notes: The quick brown fox jumps over the lazy dog. The quick brown fox jumps.']
|
134
|
+
[:GROUP, { value: 'Create a Project', offset: 15 }],
|
135
|
+
[:REQUIREMENT, { value: 'Given a user has a role of <Role> in the system Then he <Can or Cannot Create> projects', offset: 86 }],
|
136
|
+
[:TEXT, { value: 'Examples:', offset: 217 }],
|
137
|
+
[:ROW, { offset: 246 }], [:CELL, { value: 'Role' }], [:CELL, { value: 'Can or Cannot Create' }],
|
138
|
+
[:ROW, { offset: 298 }], [:CELL, { value: 'Admin' }], [:CELL, { value: 'Can Create' }],
|
139
|
+
[:ROW, { offset: 350 }], [:CELL, { value: 'User' }], [:CELL, { value: 'Cannot Create' }],
|
140
|
+
[:TEXT, { value: 'Notes: The quick brown fox jumps over the lazy dog. The quick brown fox jumps.', offset: 407 }]
|
135
141
|
]
|
136
142
|
output.must_equal tokens
|
137
143
|
end
|
138
|
-
|
144
|
+
|
139
145
|
it "must tokenize a requirements file with arbitrary text right under the group name" do
|
140
146
|
output = tokenize <<-EOF
|
141
147
|
User Login
|
142
148
|
==========
|
143
149
|
(Derived from: http://www.allaboutagile.com/user-story-example/)
|
144
|
-
|
150
|
+
|
145
151
|
As a registered user, I want to log in,
|
146
152
|
so I can access subscriber content.
|
147
|
-
|
153
|
+
|
148
154
|
Success:
|
149
|
-
|
155
|
+
|
150
156
|
* When I check 'Remember Me' and log in succesfully,
|
151
157
|
I won't have to login again next time
|
152
158
|
EOF
|
153
159
|
tokens = [
|
154
|
-
[:GROUP, 'User Login'],
|
155
|
-
[:TEXT, '(Derived from: http://www.allaboutagile.com/user-story-example/)'],
|
156
|
-
[:TEXT, 'As a registered user, I want to log in, so I can access subscriber content.'],
|
157
|
-
[:TEXT, 'Success:'],
|
158
|
-
[:REQUIREMENT, 'When I check \'Remember Me\' and log in succesfully, I won\'t have to login again next time']
|
160
|
+
[:GROUP, { value: 'User Login', offset: 19 }],
|
161
|
+
[:TEXT, { value: '(Derived from: http://www.allaboutagile.com/user-story-example/)', offset: 79 }],
|
162
|
+
[:TEXT, { value: 'As a registered user, I want to log in, so I can access subscriber content.', offset: 170 }],
|
163
|
+
[:TEXT, { value: 'Success:', offset: 291 }],
|
164
|
+
[:REQUIREMENT, { value: 'When I check \'Remember Me\' and log in succesfully, I won\'t have to login again next time', offset: 328 }]
|
159
165
|
]
|
160
166
|
output.must_equal tokens
|
161
167
|
end
|
@@ -18,161 +18,161 @@ module ManaMana
|
|
18
18
|
Create a Project
|
19
19
|
================
|
20
20
|
EOF
|
21
|
-
nodes = RootNode.new(
|
22
|
-
GroupNode.new('Create a Project')
|
21
|
+
nodes = RootNode.new({}, [
|
22
|
+
GroupNode.new({ value: 'Create a Project', offset: 17 })
|
23
23
|
])
|
24
24
|
output.must_equal nodes
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it "must parse multiple empty groups" do
|
28
28
|
output = parse <<-EOF
|
29
29
|
Create a Project
|
30
30
|
================
|
31
|
-
|
31
|
+
|
32
32
|
Create a User
|
33
33
|
=============
|
34
34
|
EOF
|
35
|
-
nodes = RootNode.new(
|
36
|
-
GroupNode.new('Create a Project'),
|
37
|
-
GroupNode.new('Create a User')
|
35
|
+
nodes = RootNode.new({}, [
|
36
|
+
GroupNode.new({ value: 'Create a Project', offset: 17 }),
|
37
|
+
GroupNode.new({ value: 'Create a User', offset: 92 })
|
38
38
|
])
|
39
39
|
output.must_equal nodes
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "must parse requirements" do
|
43
43
|
output = parse <<-EOF
|
44
44
|
Create a Project
|
45
45
|
================
|
46
|
-
|
46
|
+
|
47
47
|
* Given a user with role <Role>
|
48
48
|
EOF
|
49
|
-
nodes = RootNode.new(
|
50
|
-
GroupNode.new('Create a Project', [
|
51
|
-
RequirementNode.new('Given a user with role <Role>')
|
49
|
+
nodes = RootNode.new({}, [
|
50
|
+
GroupNode.new({ value: 'Create a Project', offset: 17 }, [
|
51
|
+
RequirementNode.new({ value: 'Given a user with role <Role>', offset: 94 })
|
52
52
|
])
|
53
53
|
])
|
54
54
|
output.must_equal nodes
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
it "must parse a multi-line requirement" do
|
58
58
|
output = parse <<-EOF
|
59
59
|
Create a Project
|
60
60
|
================
|
61
|
-
|
61
|
+
|
62
62
|
* Given a
|
63
63
|
user with
|
64
64
|
role <Role>
|
65
65
|
EOF
|
66
|
-
nodes = RootNode.new(
|
67
|
-
GroupNode.new('Create a Project', [
|
68
|
-
RequirementNode.new("Given a user with role <Role>")
|
66
|
+
nodes = RootNode.new({}, [
|
67
|
+
GroupNode.new({ value: 'Create a Project', offset: 17 }, [
|
68
|
+
RequirementNode.new({ value: "Given a user with role <Role>", offset: 94 })
|
69
69
|
])
|
70
70
|
])
|
71
71
|
output.must_equal nodes
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
it "must parse multiple non-empty groups" do
|
75
75
|
output = parse <<-EOF
|
76
76
|
Create a Project
|
77
77
|
================
|
78
|
-
|
78
|
+
|
79
79
|
* Projects without names are invalid
|
80
|
-
|
80
|
+
|
81
81
|
Create a User
|
82
82
|
=============
|
83
|
-
|
83
|
+
|
84
84
|
* Users with names are valid
|
85
85
|
EOF
|
86
|
-
nodes = RootNode.new(
|
87
|
-
GroupNode.new('Create a Project', [
|
88
|
-
RequirementNode.new('Projects without names are invalid')
|
86
|
+
nodes = RootNode.new({}, [
|
87
|
+
GroupNode.new({ value: 'Create a Project', offset: 17 }, [
|
88
|
+
RequirementNode.new({ value: 'Projects without names are invalid', offset: 94 })
|
89
89
|
]),
|
90
|
-
GroupNode.new('Create a User', [
|
91
|
-
RequirementNode.new('Users with names are valid')
|
90
|
+
GroupNode.new({ value: 'Create a User', offset: 155 }, [
|
91
|
+
RequirementNode.new({ value: 'Users with names are valid', offset: 226 })
|
92
92
|
])
|
93
93
|
])
|
94
94
|
output.must_equal nodes
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
it "must parse tables" do
|
98
98
|
output = parse <<-EOF
|
99
99
|
Create a Project
|
100
100
|
================
|
101
|
-
|
101
|
+
|
102
102
|
* Given a
|
103
103
|
user with
|
104
104
|
role <Role>
|
105
|
-
|
105
|
+
|
106
106
|
Examples:
|
107
107
|
| Role | Remarks |
|
108
108
|
| PM | ARRR |
|
109
109
|
| User | RAAA |
|
110
110
|
EOF
|
111
|
-
nodes = RootNode.new(
|
112
|
-
GroupNode.new('Create a Project', [
|
113
|
-
RequirementNode.new("Given a user with role <Role>", [
|
114
|
-
ExamplesNode.new(
|
115
|
-
RowNode.new(
|
116
|
-
RowNode.new(
|
117
|
-
RowNode.new(
|
111
|
+
nodes = RootNode.new({}, [
|
112
|
+
GroupNode.new({ value: 'Create a Project', offset: 17 }, [
|
113
|
+
RequirementNode.new({ value: "Given a user with role <Role>", offset: 92 }, [
|
114
|
+
ExamplesNode.new({}, [
|
115
|
+
RowNode.new({ value: ['Role', 'Remarks'], offset: 218 }),
|
116
|
+
RowNode.new({ value: ['PM', 'ARRR'], offset: 257 }),
|
117
|
+
RowNode.new({ value: ['User', 'RAAA'], offset: 296 })
|
118
118
|
])
|
119
119
|
])
|
120
120
|
])
|
121
121
|
])
|
122
122
|
output.must_equal nodes
|
123
123
|
end
|
124
|
-
|
124
|
+
|
125
125
|
it "must parse multiple requirements" do
|
126
126
|
output = parse <<-EOF
|
127
127
|
Project Management
|
128
128
|
==================
|
129
|
-
|
129
|
+
|
130
130
|
* A <Role> in the system <Can or Cannot Create> projects
|
131
|
-
|
131
|
+
|
132
132
|
| Role | Can or Cannot Create |
|
133
133
|
|------|----------------------|
|
134
134
|
| PM | Can Create |
|
135
135
|
| User | Cannot Create |
|
136
|
-
|
136
|
+
|
137
137
|
* An empty project is invalid
|
138
138
|
EOF
|
139
|
-
nodes = RootNode.new(
|
140
|
-
GroupNode.new('Project Management', [
|
141
|
-
RequirementNode.new("A <Role> in the system <Can or Cannot Create> projects", [
|
142
|
-
ExamplesNode.new(
|
143
|
-
RowNode.new(
|
144
|
-
RowNode.new(
|
145
|
-
RowNode.new(
|
139
|
+
nodes = RootNode.new({}, [
|
140
|
+
GroupNode.new({ value: 'Project Management', offset: 17 }, [
|
141
|
+
RequirementNode.new({ value: "A <Role> in the system <Can or Cannot Create> projects", offset: 96 }, [
|
142
|
+
ExamplesNode.new({}, [
|
143
|
+
RowNode.new({ value: ['Role', 'Can or Cannot Create'], offset: 181 }),
|
144
|
+
RowNode.new({ value: ['PM', 'Can Create'], offset: 287 }),
|
145
|
+
RowNode.new({ value: ['User', 'Cannot Create'], offset: 340 })
|
146
146
|
])
|
147
147
|
]),
|
148
|
-
RequirementNode.new("An empty project is invalid", [])
|
148
|
+
RequirementNode.new({ value: "An empty project is invalid", offset: 396 }, [])
|
149
149
|
])
|
150
150
|
])
|
151
151
|
output.must_equal nodes
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
it "must parse groups followed by arbitrary text" do
|
155
155
|
output = parse <<-EOF
|
156
156
|
User Login
|
157
157
|
==========
|
158
|
-
|
158
|
+
|
159
159
|
(Derived from: http://www.allaboutagile.com/user-story-example/)
|
160
|
-
|
160
|
+
|
161
161
|
As a registered user, I want to log in,
|
162
162
|
so I can access subscriber content.
|
163
|
-
|
163
|
+
|
164
164
|
Success:
|
165
|
-
|
165
|
+
|
166
166
|
* When I check 'Remember Me' and log in succesfully,
|
167
167
|
I won't have to login again next time
|
168
|
-
|
168
|
+
|
169
169
|
* When I uncheck 'Remember Me' and log in successfully,
|
170
170
|
I should be asked to login next time
|
171
171
|
EOF
|
172
|
-
nodes = RootNode.new(
|
173
|
-
GroupNode.new('User Login', [
|
174
|
-
RequirementNode.new('When I check \'Remember Me\' and log in succesfully, I won\'t have to login again next time'),
|
175
|
-
RequirementNode.new('When I uncheck \'Remember Me\' and log in successfully, I should be asked to login next time')
|
172
|
+
nodes = RootNode.new({}, [
|
173
|
+
GroupNode.new({ value: 'User Login', offset: 19 }, [
|
174
|
+
RequirementNode.new({ value: 'When I check \'Remember Me\' and log in succesfully, I won\'t have to login again next time', offset: 335 }),
|
175
|
+
RequirementNode.new({ value: 'When I uncheck \'Remember Me\' and log in successfully, I should be asked to login next time', offset: 477 })
|
176
176
|
])
|
177
177
|
])
|
178
178
|
output.must_equal nodes
|
@@ -8,11 +8,11 @@ module ManaMana
|
|
8
8
|
describe RequirementNode do
|
9
9
|
|
10
10
|
it "must expand examples" do
|
11
|
-
nodes = RequirementNode.new("A <Role> in the system <Can or Cannot Create> projects", [
|
12
|
-
ExamplesNode.new(
|
13
|
-
RowNode.new(
|
14
|
-
RowNode.new(
|
15
|
-
RowNode.new(
|
11
|
+
nodes = RequirementNode.new({ value: "A <Role> in the system <Can or Cannot Create> projects" }, [
|
12
|
+
ExamplesNode.new({}, [
|
13
|
+
RowNode.new({ value: ['Role', 'Can or Cannot Create'] }),
|
14
|
+
RowNode.new({ value: ['PM', 'Can Create'] }),
|
15
|
+
RowNode.new({ value: ['User', 'Cannot Create'] })
|
16
16
|
])
|
17
17
|
])
|
18
18
|
array = [
|
@@ -23,7 +23,7 @@ module ManaMana
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it "must return its name when expand is called and no examples exist" do
|
26
|
-
nodes = RequirementNode.new("A PM in the system can create projects")
|
26
|
+
nodes = RequirementNode.new({ value: "A PM in the system can create projects" })
|
27
27
|
array = ['A PM in the system can create projects']
|
28
28
|
nodes.expand.must_equal array
|
29
29
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: manamana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-05-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: racc
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - '='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 1.4.9
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: thor
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.18.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.18.0
|
30
46
|
description: Capture project requirements better
|
31
47
|
email:
|
32
48
|
- mmaglana@gmail.com
|
@@ -36,7 +52,8 @@ extensions: []
|
|
36
52
|
extra_rdoc_files: []
|
37
53
|
files:
|
38
54
|
- .gitignore
|
39
|
-
- .
|
55
|
+
- .ruby-gemset
|
56
|
+
- .ruby-version
|
40
57
|
- Gemfile
|
41
58
|
- Gemfile.lock
|
42
59
|
- Guardfile
|
@@ -46,6 +63,7 @@ files:
|
|
46
63
|
- bin/mana
|
47
64
|
- lib/manamana.rb
|
48
65
|
- lib/manamana/compiler.rb
|
66
|
+
- lib/manamana/paths.rb
|
49
67
|
- lib/manamana/rdsl/lexer.rb
|
50
68
|
- lib/manamana/rdsl/nodes.rb
|
51
69
|
- lib/manamana/rdsl/parser.rb
|
@@ -82,7 +100,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
100
|
version: '0'
|
83
101
|
segments:
|
84
102
|
- 0
|
85
|
-
hash:
|
103
|
+
hash: -3438006992594828178
|
86
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
105
|
none: false
|
88
106
|
requirements:
|
@@ -91,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
109
|
version: '0'
|
92
110
|
segments:
|
93
111
|
- 0
|
94
|
-
hash:
|
112
|
+
hash: -3438006992594828178
|
95
113
|
requirements: []
|
96
114
|
rubyforge_project:
|
97
115
|
rubygems_version: 1.8.25
|
data/.rvmrc
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
ruby_string="ruby-1.9.3"
|
4
|
-
gemset_name="manamana"
|
5
|
-
|
6
|
-
if rvm list strings | grep -q "${ruby_string}" ; then
|
7
|
-
|
8
|
-
# Load or create the specified gemset
|
9
|
-
rvm use "${ruby_string}@${gemset_name}" --create
|
10
|
-
|
11
|
-
else
|
12
|
-
|
13
|
-
# Notify the user to install the desired interpreter before proceeding.
|
14
|
-
echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory."
|
15
|
-
|
16
|
-
fi
|