manamana 0.0.1 → 0.0.2

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,171 @@
1
+ require_relative '../../../test_helper'
2
+ require 'manamana/rdsl/lexer'
3
+
4
+ module ManaMana
5
+
6
+ module RDSL
7
+
8
+ describe Lexer do
9
+
10
+ it "must be defined" do
11
+ Lexer.wont_be_nil
12
+ end
13
+
14
+ it "must tokenize the group name" do
15
+ output = tokenize <<-EOF
16
+ Create a Project
17
+ ================
18
+ EOF
19
+ tokens = [ [:GROUP, 'Create a Project'] ]
20
+ output.must_equal tokens
21
+ end
22
+
23
+ it "must tokenize strings" do
24
+ output = tokenize <<-EOF
25
+ Arbitrary text
26
+ of the unusual kind
27
+ EOF
28
+ tokens = [ [:TEXT, 'Arbitrary text of the unusual kind'] ]
29
+ output.must_equal tokens
30
+ end
31
+
32
+ it "must tokenize a requirement" do
33
+ output = tokenize <<-EOF
34
+ * A project without a name is invalid
35
+ EOF
36
+ tokens = [ [:REQUIREMENT, 'A project without a name is invalid'] ]
37
+ output.must_equal tokens
38
+ end
39
+
40
+ it "must tokenize a requirement followed by arbitrary text" do
41
+ output = tokenize <<-EOF
42
+ * A project without a name is invalid
43
+
44
+ Example:
45
+ Arbitrary text
46
+ EOF
47
+ tokens = [ [:REQUIREMENT, 'A project without a name is invalid'], [:TEXT, 'Example: Arbitrary text'] ]
48
+ output.must_equal tokens
49
+ end
50
+
51
+ it "must tokenize a multi-line requirement" do
52
+ output = tokenize <<-EOF
53
+ * A project without a
54
+ name is invalid
55
+ EOF
56
+ tokens = [ [:REQUIREMENT, 'A project without a name is invalid'] ]
57
+ output.must_equal tokens
58
+ end
59
+
60
+ it "must tokenize a multi-line requirement followed by arbitrary text" do
61
+ output = tokenize <<-EOF
62
+ * A project without
63
+ a name is invalid
64
+
65
+ Example:
66
+ Arbitrary text
67
+ EOF
68
+ tokens = [ [:REQUIREMENT, 'A project without a name is invalid'], [:TEXT, 'Example: Arbitrary text'] ]
69
+ output.must_equal tokens
70
+ end
71
+
72
+ it "must tokenize tables" do
73
+ output = tokenize <<-EOF
74
+ | Name | Description |
75
+ | Project A | First Project |
76
+ | Project B | Second Project |
77
+ EOF
78
+ tokens = [
79
+ [:ROW, 'Row'], [:CELL, 'Name'], [:CELL, 'Description'],
80
+ [:ROW, 'Row'], [:CELL, 'Project A'], [:CELL, 'First Project'],
81
+ [:ROW, 'Row'], [:CELL, 'Project B'], [:CELL, 'Second Project']
82
+ ]
83
+ output.must_equal tokens
84
+ end
85
+
86
+ it "must ignore table borders" do
87
+ output = tokenize <<-EOF
88
+ | Name | Description |
89
+ |-----------|-------------------|
90
+ | Project A | First Project |
91
+ | Project B | Second Project |
92
+ EOF
93
+ tokens = [
94
+ [:ROW, 'Row'], [:CELL, 'Name'], [:CELL, 'Description'],
95
+ [:ROW, 'Row'], [:CELL, 'Project A'], [:CELL, 'First Project'],
96
+ [:ROW, 'Row'], [:CELL, 'Project B'], [:CELL, 'Second Project']
97
+ ]
98
+ output.must_equal tokens
99
+ end
100
+
101
+ it "must tokenize requirements with placeholders" do
102
+ output = tokenize <<-EOF
103
+ * Given <Role>
104
+ <Something>
105
+ EOF
106
+ tokens = [ [:REQUIREMENT, 'Given <Role> <Something>'] ]
107
+ output.must_equal tokens
108
+ end
109
+
110
+ it "must tokenize a full requirements file" do
111
+ output = tokenize <<-EOF
112
+ Create a Project
113
+ ================
114
+
115
+ * Given a user has a role of <Role> in the system
116
+ Then he <Can or Cannot Create> projects
117
+
118
+ Examples:
119
+ | Role | Can or Cannot Create |
120
+ | Admin | Can Create |
121
+ | User | Cannot Create |
122
+
123
+ Notes:
124
+ The quick brown fox jumps over the lazy
125
+ dog. The quick brown fox jumps.
126
+ EOF
127
+ 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, 'Row'], [:CELL, 'Role'], [:CELL, 'Can or Cannot Create'],
132
+ [:ROW, 'Row'], [:CELL, 'Admin'], [:CELL, 'Can Create'],
133
+ [:ROW, 'Row'], [:CELL, 'User'], [:CELL, 'Cannot Create'],
134
+ [:TEXT, 'Notes: The quick brown fox jumps over the lazy dog. The quick brown fox jumps.']
135
+ ]
136
+ output.must_equal tokens
137
+ end
138
+
139
+ it "must tokenize a requirements file with arbitrary text right under the group name" do
140
+ output = tokenize <<-EOF
141
+ User Login
142
+ ==========
143
+ (Derived from: http://www.allaboutagile.com/user-story-example/)
144
+
145
+ As a registered user, I want to log in,
146
+ so I can access subscriber content.
147
+
148
+ Success:
149
+
150
+ * When I check 'Remember Me' and log in succesfully,
151
+ I won't have to login again next time
152
+ EOF
153
+ 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']
159
+ ]
160
+ output.must_equal tokens
161
+ end
162
+
163
+ def tokenize(data)
164
+ Lexer.new.tokenize(data)
165
+ end
166
+
167
+ end # describe Lexer
168
+
169
+ end # module RDSL
170
+
171
+ end # module ManaMana
@@ -0,0 +1,189 @@
1
+ require_relative '../../../test_helper'
2
+ require 'manamana/rdsl/parser'
3
+
4
+ module ManaMana
5
+
6
+ module RDSL
7
+
8
+ describe Parser do
9
+
10
+ it "must parse an empty file" do
11
+ output = parse ""
12
+ nodes = RootNode.new
13
+ output.must_equal nodes
14
+ end
15
+
16
+ it "must parse an empty group" do
17
+ output = parse <<-EOF
18
+ Create a Project
19
+ ================
20
+ EOF
21
+ nodes = RootNode.new('', [
22
+ GroupNode.new('Create a Project')
23
+ ])
24
+ output.must_equal nodes
25
+ end
26
+
27
+ it "must parse multiple empty groups" do
28
+ output = parse <<-EOF
29
+ Create a Project
30
+ ================
31
+
32
+ Create a User
33
+ =============
34
+ EOF
35
+ nodes = RootNode.new('', [
36
+ GroupNode.new('Create a Project'),
37
+ GroupNode.new('Create a User')
38
+ ])
39
+ output.must_equal nodes
40
+ end
41
+
42
+ it "must parse requirements" do
43
+ output = parse <<-EOF
44
+ Create a Project
45
+ ================
46
+
47
+ * Given a user with role <Role>
48
+ EOF
49
+ nodes = RootNode.new('', [
50
+ GroupNode.new('Create a Project', [
51
+ RequirementNode.new('Given a user with role <Role>')
52
+ ])
53
+ ])
54
+ output.must_equal nodes
55
+ end
56
+
57
+ it "must parse a multi-line requirement" do
58
+ output = parse <<-EOF
59
+ Create a Project
60
+ ================
61
+
62
+ * Given a
63
+ user with
64
+ role <Role>
65
+ EOF
66
+ nodes = RootNode.new('', [
67
+ GroupNode.new('Create a Project', [
68
+ RequirementNode.new("Given a user with role <Role>")
69
+ ])
70
+ ])
71
+ output.must_equal nodes
72
+ end
73
+
74
+ it "must parse multiple non-empty groups" do
75
+ output = parse <<-EOF
76
+ Create a Project
77
+ ================
78
+
79
+ * Projects without names are invalid
80
+
81
+ Create a User
82
+ =============
83
+
84
+ * Users with names are valid
85
+ EOF
86
+ nodes = RootNode.new('', [
87
+ GroupNode.new('Create a Project', [
88
+ RequirementNode.new('Projects without names are invalid')
89
+ ]),
90
+ GroupNode.new('Create a User', [
91
+ RequirementNode.new('Users with names are valid')
92
+ ])
93
+ ])
94
+ output.must_equal nodes
95
+ end
96
+
97
+ it "must parse tables" do
98
+ output = parse <<-EOF
99
+ Create a Project
100
+ ================
101
+
102
+ * Given a
103
+ user with
104
+ role <Role>
105
+
106
+ Examples:
107
+ | Role | Remarks |
108
+ | PM | ARRR |
109
+ | User | RAAA |
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('', ['Role', 'Remarks']),
116
+ RowNode.new('', ['PM', 'ARRR']),
117
+ RowNode.new('', ['User', 'RAAA'])
118
+ ])
119
+ ])
120
+ ])
121
+ ])
122
+ output.must_equal nodes
123
+ end
124
+
125
+ it "must parse multiple requirements" do
126
+ output = parse <<-EOF
127
+ Project Management
128
+ ==================
129
+
130
+ * A <Role> in the system <Can or Cannot Create> projects
131
+
132
+ | Role | Can or Cannot Create |
133
+ |------|----------------------|
134
+ | PM | Can Create |
135
+ | User | Cannot Create |
136
+
137
+ * An empty project is invalid
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('', ['Role', 'Can or Cannot Create']),
144
+ RowNode.new('', ['PM', 'Can Create']),
145
+ RowNode.new('', ['User', 'Cannot Create'])
146
+ ])
147
+ ]),
148
+ RequirementNode.new("An empty project is invalid", [])
149
+ ])
150
+ ])
151
+ output.must_equal nodes
152
+ end
153
+
154
+ it "must parse groups followed by arbitrary text" do
155
+ output = parse <<-EOF
156
+ User Login
157
+ ==========
158
+
159
+ (Derived from: http://www.allaboutagile.com/user-story-example/)
160
+
161
+ As a registered user, I want to log in,
162
+ so I can access subscriber content.
163
+
164
+ Success:
165
+
166
+ * When I check 'Remember Me' and log in succesfully,
167
+ I won't have to login again next time
168
+
169
+ * When I uncheck 'Remember Me' and log in successfully,
170
+ I should be asked to login next time
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')
176
+ ])
177
+ ])
178
+ output.must_equal nodes
179
+ end
180
+
181
+ def parse(file, show_tokens = false)
182
+ Parser.new.parse(file, show_tokens)
183
+ end
184
+
185
+ end
186
+
187
+ end
188
+
189
+ end
@@ -0,0 +1,36 @@
1
+ require_relative '../../../test_helper'
2
+ require 'manamana/rdsl/nodes'
3
+
4
+ module ManaMana
5
+
6
+ module RDSL
7
+
8
+ describe RequirementNode do
9
+
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('', ['Role', 'Can or Cannot Create']),
14
+ RowNode.new('', ['PM', 'Can Create']),
15
+ RowNode.new('', ['User', 'Cannot Create'])
16
+ ])
17
+ ])
18
+ array = [
19
+ 'A PM in the system Can Create projects',
20
+ 'A User in the system Cannot Create projects'
21
+ ]
22
+ nodes.expand.must_equal array
23
+ end
24
+
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")
27
+ array = ['A PM in the system can create projects']
28
+ nodes.expand.must_equal array
29
+ end
30
+
31
+
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,72 @@
1
+ require_relative '../../../test_helper'
2
+ require 'manamana/tdsl/lexer'
3
+
4
+ module ManaMana
5
+
6
+ module TDSL
7
+
8
+ describe Lexer do
9
+
10
+ section_labels = [ 'Variables', 'Preconditions', 'Cleanup', 'Script' ]
11
+
12
+ section_labels.each do |section_label|
13
+ it "must tokenize the #{ section_label } keyword" do
14
+ output = tokenize <<-EOF
15
+ #{ section_label }:
16
+ EOF
17
+ tokens = [ [section_label.upcase.to_sym, section_label] ]
18
+ output.must_equal tokens
19
+ end
20
+ end
21
+
22
+ it "must tokenize the test case name" do
23
+ output = tokenize <<-EOF
24
+ Test Case:
25
+ A user who is a (.+) can create tickets in it
26
+ EOF
27
+ tokens = [ [:TEST_CASE, 'A user who is a (.+) can create tickets in it'] ]
28
+ output.must_equal tokens
29
+ end
30
+
31
+ it "must tokenize a Variables section" do
32
+ output = tokenize <<-EOF
33
+ Variables:
34
+ * My Name = $1
35
+ * A long variable name
36
+ = 'something'
37
+ * Role = role_id
38
+ EOF
39
+ tokens = [
40
+ [:VARIABLES, "Variables"],
41
+ [:LINE, "My Name = $1"],
42
+ [:LINE, "A long variable name = 'something'"],
43
+ [:LINE, "Role = role_id"]
44
+ ]
45
+ output.must_equal tokens
46
+ end
47
+
48
+ it "must tokenize lines with multiple whitespace" do
49
+ output = tokenize <<-EOF
50
+ * Ensure that the username <My Username> exists
51
+ * Ensure that the database
52
+ is cleaned up of previous
53
+ testing data
54
+ * Ensure that the app is running
55
+ EOF
56
+ tokens = [
57
+ [:LINE, "Ensure that the username <My Username> exists"],
58
+ [:LINE, "Ensure that the database is cleaned up of previous testing data"],
59
+ [:LINE, "Ensure that the app is running"]
60
+ ]
61
+ output.must_equal tokens
62
+ end
63
+
64
+ def tokenize(data)
65
+ Lexer.new.tokenize(data)
66
+ end
67
+
68
+ end # describe Lexer
69
+
70
+ end # module TDSL
71
+
72
+ end # module ManaMana
@@ -0,0 +1,171 @@
1
+ require_relative '../../../test_helper'
2
+ require 'manamana/tdsl/parser'
3
+
4
+ module ManaMana
5
+
6
+ module TDSL
7
+
8
+ describe Parser do
9
+
10
+ it "must parse an empty file" do
11
+ output = parse ""
12
+ nodes = RootNode.new
13
+ output.must_equal nodes
14
+ end
15
+
16
+ it "must parse an empty test case" do
17
+ output = parse <<-EOF
18
+ Test Case:
19
+ A user who is a (.+) can create tickets in it
20
+ EOF
21
+ nodes = RootNode.new('', [
22
+ TestCaseNode.new('A user who is a (.+) can create tickets in it')
23
+ ])
24
+ output.must_equal nodes
25
+ end
26
+
27
+ it "must parse multiple empty test cases" do
28
+ output = parse <<-EOF
29
+ Test Case:
30
+ A user who is a (.+) can create tickets in it
31
+
32
+ Test Case:
33
+ A user who is a (.+) cannot create tickets in it
34
+ EOF
35
+ nodes = RootNode.new('', [
36
+ TestCaseNode.new('A user who is a (.+) can create tickets in it'),
37
+ TestCaseNode.new('A user who is a (.+) cannot create tickets in it')
38
+ ])
39
+ output.must_equal nodes
40
+ end
41
+
42
+ it "must parse the variables section" do
43
+ file = <<-EOF
44
+ Test Case:
45
+ A user who is a Manager can create tickets in it
46
+
47
+ Variables:
48
+ * My Username = $1
49
+ * My Password = my_password
50
+ EOF
51
+ output = parse file
52
+ nodes = RootNode.new('', [
53
+ TestCaseNode.new('A user who is a Manager can create tickets in it', {
54
+ :variables => VariablesNode.new('', [
55
+ AssignmentNode.new('My Username = $1'),
56
+ AssignmentNode.new('My Password = my_password')
57
+ ])
58
+ })
59
+ ])
60
+ output.must_equal nodes
61
+ end
62
+
63
+ it "must parse the preconditions section" do
64
+ file = <<-EOF
65
+ Test Case:
66
+ A user who is a Manager can create tickets in it
67
+
68
+ Preconditions:
69
+ * Ensure a user with username Bob exists
70
+ * This is another step that
71
+ wraps to the next line
72
+ EOF
73
+ output = parse file
74
+ nodes = RootNode.new('', [
75
+ TestCaseNode.new('A user who is a Manager can create tickets in it', {
76
+ :preconditions => PreconditionsNode.new('', [
77
+ StepNode.new('Ensure a user with username Bob exists'),
78
+ StepNode.new('This is another step that wraps to the next line')
79
+ ])
80
+ })
81
+ ])
82
+ output.must_equal nodes
83
+ end
84
+
85
+ it "must parse the cleanup section" do
86
+ file = <<-EOF
87
+ Test Case:
88
+ A user who is a Manager can create tickets in it
89
+
90
+ Cleanup:
91
+ * Delete <My Username> at exit
92
+ EOF
93
+ output = parse file
94
+ nodes = RootNode.new('', [
95
+ TestCaseNode.new('A user who is a Manager can create tickets in it', {
96
+ :cleanup => CleanupNode.new('', [
97
+ StepNode.new('Delete <My Username> at exit')
98
+ ])
99
+ })
100
+ ])
101
+ output.must_equal nodes
102
+ end
103
+
104
+ it "must parse the script section" do
105
+ file = <<-EOF
106
+ Test Case:
107
+ A user who is a Manager can create tickets in it
108
+
109
+ Script:
110
+ * Click the Log Out button
111
+ EOF
112
+ output = parse file
113
+ nodes = RootNode.new('', [
114
+ TestCaseNode.new('A user who is a Manager can create tickets in it', {
115
+ :script => ScriptNode.new('', [
116
+ StepNode.new('Click the Log Out button')
117
+ ])
118
+ })
119
+ ])
120
+ output.must_equal nodes
121
+ end
122
+
123
+ it "must parse multiple non-empty test cases" do
124
+ file = <<-EOF
125
+ Test Case:
126
+ A user who is a Manager can create tickets in it
127
+
128
+ Script:
129
+ * Click the Log Out button
130
+
131
+ Test Case:
132
+ A user who is a (.+) cannot create tickets
133
+
134
+ Variables:
135
+ * My Username = 'Bob'
136
+
137
+ Script:
138
+ * Click the Log Out button
139
+ * Fill in the Username field with <My Username>
140
+ EOF
141
+ output = parse file
142
+ nodes = RootNode.new('', [
143
+ TestCaseNode.new('A user who is a Manager can create tickets in it', {
144
+ :script => ScriptNode.new('', [
145
+ StepNode.new('Click the Log Out button')
146
+ ])
147
+ }),
148
+
149
+ TestCaseNode.new('A user who is a (.+) cannot create tickets', {
150
+ :variables => VariablesNode.new('', [
151
+ AssignmentNode.new('My Username = \'Bob\'')
152
+ ]),
153
+ :script => ScriptNode.new('', [
154
+ StepNode.new('Click the Log Out button'),
155
+ StepNode.new('Fill in the Username field with <My Username>')
156
+ ])
157
+ })
158
+ ])
159
+
160
+ output.must_equal nodes
161
+ end
162
+
163
+ def parse(file, show_tokens = false)
164
+ Parser.new.parse(file, show_tokens)
165
+ end
166
+
167
+ end
168
+
169
+ end
170
+
171
+ end