manamana 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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