lucid-tdl 1.0.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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +21 -0
- data/lib/lucid-tdl/ast.rb +102 -0
- data/lib/lucid-tdl/parser/lexer.rb +130 -0
- data/lib/lucid-tdl/parser/lucid-tdl.rex +40 -0
- data/lib/lucid-tdl/parser/lucid-tdl.y +107 -0
- data/lib/lucid-tdl/parser/parser.rb +485 -0
- data/lib/lucid-tdl/version.rb +3 -0
- data/lib/lucid-tdl.rb +11 -0
- data/lucid-tdl.gemspec +19 -0
- data/test/lucid-tdl/parser/ast_test.rb +125 -0
- data/test/lucid-tdl/parser/full_parsing_test.rb +74 -0
- data/test/lucid-tdl/parser/lexer_test.rb +70 -0
- data/test/lucid-tdl/parser/parser_test.rb +179 -0
- data/test/test_helper.rb +4 -0
- metadata +68 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module LucidTDL
|
4
|
+
describe 'Full Test Specification Parsing' do
|
5
|
+
before do
|
6
|
+
@scenario = """Feature: Ability to use Lucid TDL
|
7
|
+
As a test specification writer
|
8
|
+
I need a test description language
|
9
|
+
so that I can structure tests
|
10
|
+
|
11
|
+
Background:
|
12
|
+
Given a generic context
|
13
|
+
And one that happens for all scenarios
|
14
|
+
|
15
|
+
Scenario: A basic test
|
16
|
+
When an action takes place
|
17
|
+
Then an observable occurs
|
18
|
+
|
19
|
+
@selenium @wip
|
20
|
+
Scenario: Another basic test
|
21
|
+
When another action takes place
|
22
|
+
Then another observable occurs
|
23
|
+
"""
|
24
|
+
|
25
|
+
parser = LucidTDL::Parser.new
|
26
|
+
@result = parser.parse(@scenario)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "generates a tree hierarchy" do
|
30
|
+
@result.must_be_kind_of AST::Feature
|
31
|
+
@result.line.must_equal 1
|
32
|
+
|
33
|
+
@result.description.must_equal [
|
34
|
+
"As a test specification writer",
|
35
|
+
"I need a test description language",
|
36
|
+
"so that I can structure tests"]
|
37
|
+
|
38
|
+
background = @result.background
|
39
|
+
background.must_be_kind_of AST::Background
|
40
|
+
background.line.must_equal 6
|
41
|
+
background.steps.first.keyword.must_equal 'Given'
|
42
|
+
background.steps.first.name.must_equal 'a generic context'
|
43
|
+
background.steps.first.line.must_equal 7
|
44
|
+
background.steps.last.keyword.must_equal 'And'
|
45
|
+
background.steps.last.name.must_equal 'one that happens for all scenarios'
|
46
|
+
background.steps.last.line.must_equal 8
|
47
|
+
|
48
|
+
first_scenario = @result.scenarios.first
|
49
|
+
first_scenario.must_be_kind_of AST::Scenario
|
50
|
+
first_scenario.line.must_equal 10
|
51
|
+
first_scenario.name.must_equal 'A basic test'
|
52
|
+
first_scenario.steps.first.keyword.must_equal 'When'
|
53
|
+
first_scenario.steps.first.name.must_equal 'an action takes place'
|
54
|
+
first_scenario.steps.first.line.must_equal 11
|
55
|
+
first_scenario.steps.last.keyword.must_equal 'Then'
|
56
|
+
first_scenario.steps.last.name.must_equal 'an observable occurs'
|
57
|
+
first_scenario.steps.last.line.must_equal 12
|
58
|
+
|
59
|
+
last_scenario = @result.scenarios.last
|
60
|
+
last_scenario.must_be_kind_of AST::Scenario
|
61
|
+
last_scenario.line.must_equal 15
|
62
|
+
last_scenario.name.must_equal 'Another basic test'
|
63
|
+
last_scenario.tags.first.name.must_equal 'selenium'
|
64
|
+
last_scenario.tags.last.name.must_equal 'wip'
|
65
|
+
|
66
|
+
last_scenario.steps.first.keyword.must_equal 'When'
|
67
|
+
last_scenario.steps.first.name.must_equal 'another action takes place'
|
68
|
+
last_scenario.steps.first.line.must_equal 16
|
69
|
+
last_scenario.steps.last.keyword.must_equal 'Then'
|
70
|
+
last_scenario.steps.last.name.must_equal 'another observable occurs'
|
71
|
+
last_scenario.steps.last.line.must_equal 17
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module LucidTDL
|
4
|
+
describe Parser do
|
5
|
+
before do
|
6
|
+
@lexer = Parser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "can parse a single newline character" do
|
10
|
+
@lexer.tokenize("\n").must_equal [[:NEWLINE, "\n"]]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can parse multiple newline characters" do
|
14
|
+
@lexer.tokenize("\n\n").must_equal [[:NEWLINE, "\n"], [:NEWLINE, "\n"]]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can parse text strings" do
|
18
|
+
@lexer.tokenize("simple text").must_equal [[:TEXT, "simple text"]]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "strip parsed text strings" do
|
22
|
+
@lexer.tokenize(" simple text ").must_equal [[:TEXT, "simple text"]]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "parses a single tag" do
|
26
|
+
@lexer.tokenize("@selenium @headless").must_equal [
|
27
|
+
[:TAG, "selenium"],
|
28
|
+
[:TAG, "headless"],
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
it "parses multiple tags" do
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "high-level structural keywords" do
|
37
|
+
%w(Feature: Ability: Responsibility:).each do |keyword|
|
38
|
+
it "parses #{keyword}:" do
|
39
|
+
name = keyword[0..-2]
|
40
|
+
@lexer.tokenize(keyword).must_equal [[name.upcase.to_sym, name]]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "operational structural keywords" do
|
46
|
+
%w(Background: Scenario: Test:).each do |keyword|
|
47
|
+
it "parses #{keyword}:" do
|
48
|
+
name = keyword[0..-2]
|
49
|
+
@lexer.tokenize(keyword).must_equal [[name.upcase.to_sym, name]]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "specific step keywords" do
|
55
|
+
%w(Given When Then And But).each do |keyword|
|
56
|
+
it "parses #{keyword}" do
|
57
|
+
@lexer.tokenize(keyword).must_equal [[keyword.upcase.to_sym, keyword]]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "generic step keywords" do
|
63
|
+
%w(*).each do |keyword|
|
64
|
+
it "parses #{keyword}" do
|
65
|
+
@lexer.tokenize(keyword).must_equal [[:GENERIC, "*"]]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module LucidTDL
|
4
|
+
describe Parser do
|
5
|
+
|
6
|
+
def parse(input)
|
7
|
+
parser = Parser.new
|
8
|
+
parser.parse(input)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "Feature Element" do
|
12
|
+
it "parses feature description without narrative" do
|
13
|
+
feature = parse("Feature: Test Feature")
|
14
|
+
feature.must_be_kind_of AST::Feature
|
15
|
+
feature.name.must_equal "Test Feature"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses feature description with narrative" do
|
19
|
+
feature = parse("Feature: Test Feature\n As a... \n I want... \n So that...\n")
|
20
|
+
feature.must_be_kind_of AST::Feature
|
21
|
+
feature.name.must_equal "Test Feature"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "parses a feature with tags" do
|
25
|
+
feature = parse("""
|
26
|
+
@wip @selenium
|
27
|
+
Feature: Test Feature
|
28
|
+
""")
|
29
|
+
feature.name.must_equal "Test Feature"
|
30
|
+
feature.tags.first.name.must_equal "wip"
|
31
|
+
feature.tags.last.name.must_equal "selenium"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "parses a feature with tags, without prior newline" do
|
35
|
+
feature = parse("@wip\nFeature: Test Feature")
|
36
|
+
feature.name.must_equal "Test Feature"
|
37
|
+
feature.tags.first.name.must_equal "wip"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "Ability Element" do
|
42
|
+
it "parses ability description without narrative" do
|
43
|
+
feature = parse("Ability: Test Ability")
|
44
|
+
feature.must_be_kind_of AST::Feature
|
45
|
+
feature.name.must_equal "Test Ability"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "parses ability description with narrative" do
|
49
|
+
feature = parse("Ability: Test Ability\n As a... \n I want... \n So that...\n")
|
50
|
+
feature.must_be_kind_of AST::Feature
|
51
|
+
feature.name.must_equal "Test Ability"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "Responsility Element" do
|
56
|
+
it "parses responsibility description without narrative" do
|
57
|
+
feature = parse("Responsibility: Test Responsibility")
|
58
|
+
feature.must_be_kind_of AST::Feature
|
59
|
+
feature.name.must_equal "Test Responsibility"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "parses responsibility description with narrative" do
|
63
|
+
feature = parse("Responsibility: Test Responsibility\n As a... \n I want... \n So that...\n")
|
64
|
+
feature.must_be_kind_of AST::Feature
|
65
|
+
feature.name.must_equal "Test Responsibility"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "Backgrounds and Context" do
|
70
|
+
it "parses a background" do
|
71
|
+
feature = parse("""
|
72
|
+
Feature: Test Feature
|
73
|
+
|
74
|
+
Background:
|
75
|
+
Given a situation applies
|
76
|
+
And a context is operative
|
77
|
+
""")
|
78
|
+
feature.name.must_equal "Test Feature"
|
79
|
+
feature.background.must_be_kind_of AST::Background
|
80
|
+
steps = feature.background.steps
|
81
|
+
|
82
|
+
given_step = steps.first
|
83
|
+
and_step = steps.last
|
84
|
+
|
85
|
+
given_step.keyword.must_equal "Given"
|
86
|
+
given_step.name.must_equal "a situation applies"
|
87
|
+
and_step.keyword.must_equal "And"
|
88
|
+
and_step.name.must_equal "a context is operative"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "parses a context" do
|
92
|
+
feature = parse("""
|
93
|
+
Feature: Test Feature
|
94
|
+
|
95
|
+
Context:
|
96
|
+
Given a situation applies
|
97
|
+
And a context is operative
|
98
|
+
""")
|
99
|
+
feature.name.must_equal "Test Feature"
|
100
|
+
feature.background.must_be_kind_of AST::Background
|
101
|
+
steps = feature.background.steps
|
102
|
+
|
103
|
+
given_step = steps.first
|
104
|
+
and_step = steps.last
|
105
|
+
|
106
|
+
given_step.keyword.must_equal "Given"
|
107
|
+
given_step.name.must_equal "a situation applies"
|
108
|
+
and_step.keyword.must_equal "And"
|
109
|
+
and_step.name.must_equal "a context is operative"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "Scenarios and Tests" do
|
114
|
+
it "parses a feature with scenarios and tests" do
|
115
|
+
feature = parse("""
|
116
|
+
Feature: Test Feature
|
117
|
+
|
118
|
+
Scenario: A Scenario
|
119
|
+
Given some context
|
120
|
+
When some action
|
121
|
+
Then some observable
|
122
|
+
|
123
|
+
Test: A Test
|
124
|
+
Given some context
|
125
|
+
When some action
|
126
|
+
And some other action
|
127
|
+
Then some observable
|
128
|
+
But not some other observable
|
129
|
+
""")
|
130
|
+
scenarios = feature.scenarios
|
131
|
+
|
132
|
+
first_scenario = scenarios.first
|
133
|
+
last_scenario = scenarios.last
|
134
|
+
|
135
|
+
first_scenario.name.must_equal "A Scenario"
|
136
|
+
first_scenario.steps.first.name.must_equal "some context"
|
137
|
+
first_scenario.steps.last.name.must_equal "some observable"
|
138
|
+
|
139
|
+
last_scenario.name.must_equal "A Test"
|
140
|
+
last_scenario.steps.first.name.must_equal "some context"
|
141
|
+
last_scenario.steps.last.name.must_equal "not some other observable"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "parses a feature with generic steps" do
|
145
|
+
feature = parse("""
|
146
|
+
Feature: Test Feature
|
147
|
+
|
148
|
+
Scenario: A Scenario
|
149
|
+
* some context
|
150
|
+
* some action
|
151
|
+
""")
|
152
|
+
scenarios = feature.scenarios
|
153
|
+
|
154
|
+
first_scenario = scenarios.first
|
155
|
+
|
156
|
+
first_scenario.name.must_equal "A Scenario"
|
157
|
+
first_scenario.steps.first.name.must_equal "some context"
|
158
|
+
first_scenario.steps.last.name.must_equal "some action"
|
159
|
+
end
|
160
|
+
|
161
|
+
it "parses a scenario with tags" do
|
162
|
+
feature = parse("""
|
163
|
+
Feature: Test Feature
|
164
|
+
|
165
|
+
@critical @regression @smoke
|
166
|
+
Scenario: A Scenario
|
167
|
+
Given some context
|
168
|
+
When some action
|
169
|
+
Then some observable
|
170
|
+
""")
|
171
|
+
scenarios = feature.scenarios
|
172
|
+
first_scenario = scenarios.first
|
173
|
+
first_scenario.tags[0].name.must_equal "critical"
|
174
|
+
first_scenario.tags[1].name.must_equal "regression"
|
175
|
+
first_scenario.tags[2].name.must_equal "smoke"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lucid-tdl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jeff Nyman
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-12 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Test Description Language
|
15
|
+
email:
|
16
|
+
- jeffnyman@gmail.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/lucid-tdl.rb
|
27
|
+
- lib/lucid-tdl/ast.rb
|
28
|
+
- lib/lucid-tdl/parser/lexer.rb
|
29
|
+
- lib/lucid-tdl/parser/lucid-tdl.rex
|
30
|
+
- lib/lucid-tdl/parser/lucid-tdl.y
|
31
|
+
- lib/lucid-tdl/parser/parser.rb
|
32
|
+
- lib/lucid-tdl/version.rb
|
33
|
+
- lucid-tdl.gemspec
|
34
|
+
- test/lucid-tdl/parser/ast_test.rb
|
35
|
+
- test/lucid-tdl/parser/full_parsing_test.rb
|
36
|
+
- test/lucid-tdl/parser/lexer_test.rb
|
37
|
+
- test/lucid-tdl/parser/parser_test.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
homepage: https://github.com/jnyman/lucid-tdl
|
40
|
+
licenses: []
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.8.24
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Test Description Language
|
63
|
+
test_files:
|
64
|
+
- test/lucid-tdl/parser/ast_test.rb
|
65
|
+
- test/lucid-tdl/parser/full_parsing_test.rb
|
66
|
+
- test/lucid-tdl/parser/lexer_test.rb
|
67
|
+
- test/lucid-tdl/parser/parser_test.rb
|
68
|
+
- test/test_helper.rb
|