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.
@@ -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
@@ -0,0 +1,4 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+
4
+ require_relative '../lib/lucid-tdl'
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