glimmer-dsl-specification 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +20 -0
- data/README.md +260 -0
- data/TODO.md +4 -0
- data/VERSION +1 -0
- data/glimmer-dsl-specification.gemspec +67 -0
- data/lib/glimmer/dsl/specification/attribute_expression.rb +17 -0
- data/lib/glimmer/dsl/specification/block_method_expression.rb +18 -0
- data/lib/glimmer/dsl/specification/dsl.rb +17 -0
- data/lib/glimmer/dsl/specification/element_expression.rb +29 -0
- data/lib/glimmer/specification/element/fact.rb +23 -0
- data/lib/glimmer/specification/element/scenario.rb +29 -0
- data/lib/glimmer/specification/element/specification.rb +12 -0
- data/lib/glimmer/specification/element/use_case.rb +8 -0
- data/lib/glimmer/specification/element.rb +100 -0
- data/lib/glimmer/specification/rake_tasks.rb +6 -0
- data/lib/glimmer/specification.rb +5 -0
- data/lib/glimmer-dsl-specification.rb +29 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5a7d09deaf02f95b8eb86bab872f38f977aeb76d958dbf201d80ad6b57008316
|
4
|
+
data.tar.gz: 928737b70dffe90683005f15b1f8eecd01e0e43fd0ff5ace33522acf895a15f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8615c3c1b8ce1e83025d0e5be9aff6de42fcb613987764287236d81785dfff10ffdfcc994ebd77329a3bd9eb515b9a58d9edfd83cb935bf869f2c957d8fc966a
|
7
|
+
data.tar.gz: e0b5cfce47413fc9c9c88f1b1587b1133bd5b636d3d5a7167dec9dfe7ffba4f113fe495d12f4ea77719c5c292ddaa145c28be42fcc7c8562996a37979b42e864
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2021 Andy Maleh
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Specification 0.0.1
|
2
|
+
## Pure Ruby Declarative Use Case Specification and Automated Verification
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-specification.svg)](http://badge.fury.io/rb/glimmer-dsl-specification)
|
4
|
+
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
|
+
|
6
|
+
Despite Ruby's highly expressive nature, all testing toolkits written in Ruby are either imperative (e.g. using `assert` or `expect`), thus losing expressiveness and focusing software engineers on the wrong thing, or mix non-Ruby code with Ruby (e.g. `cucumber` & `gherkin`), thus missing out on the simplicity of Ruby.
|
7
|
+
|
8
|
+
Glimmer DSL for Specification aims to provide a simple minimalistic and noun-based declarative syntax. No more verbs! It is time to think declaratively not imperatively!
|
9
|
+
|
10
|
+
As such, software engineers focus on [Requirements Specification](https://en.wikipedia.org/wiki/Software_requirements_specification) at the [Use Case](https://en.wikipedia.org/wiki/Use_case) level whereby each use case is composed of multiple scenarios. No need to specify scenario steps. The code is the steps!!!
|
11
|
+
|
12
|
+
Also, no need for extra DSL constructs for making comparisons in verification statements. Just use plain old Ruby and let the library figure out the rest!
|
13
|
+
|
14
|
+
For example:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
scenario 'Same-content strings are equal' do
|
18
|
+
'string' == 'string'
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
That tells me the whole story without needing either `assert` or `expect`. It just contains plain Ruby code for performing the comparison.
|
23
|
+
|
24
|
+
Another example:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
scenario 'person name consists of first name and last name' do
|
28
|
+
person = Person.new(first_name: 'Bob', last_name: 'Winfrey')
|
29
|
+
|
30
|
+
fact { person.first_name == 'Bob' }
|
31
|
+
fact { person.last_name == 'Winfrey' }
|
32
|
+
person.name == 'Bob Winfrey'
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
That states a few extra facts in addition to the last statement in the scenario denoting the final verification.
|
37
|
+
|
38
|
+
## Full Example
|
39
|
+
|
40
|
+
This library was written specification-first utilizing itself. In fact, here is the initial specification of [glimmer-dsl-specification](https://rubygems.org/gems/glimmer-dsl-specification) to prove it!
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
require 'glimmer-dsl-specification'
|
44
|
+
|
45
|
+
class Person
|
46
|
+
attr_reader :first_name, :last_name
|
47
|
+
|
48
|
+
def initialize(first_name: , last_name: )
|
49
|
+
@first_name = first_name
|
50
|
+
@last_name = last_name
|
51
|
+
end
|
52
|
+
|
53
|
+
def name
|
54
|
+
"#{first_name} #{last_name}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
module Glimmer::Specification
|
59
|
+
specification('Glimmer DSL for Specification') {
|
60
|
+
use_case('Compare Two Objects for Equality') {
|
61
|
+
scenario 'Same-content strings are equal' do
|
62
|
+
'string' == 'string'
|
63
|
+
end
|
64
|
+
|
65
|
+
scenario 'Different-content strings are not equal' do
|
66
|
+
'string1' != 'string2'
|
67
|
+
end
|
68
|
+
|
69
|
+
scenario 'Same-number integers are equal' do
|
70
|
+
1 == 1
|
71
|
+
end
|
72
|
+
|
73
|
+
scenario 'Different-number integers are not equal' do
|
74
|
+
1 != 2
|
75
|
+
end
|
76
|
+
}
|
77
|
+
|
78
|
+
use_case('Verify Multiple Facts') {
|
79
|
+
scenario 'person name consists of first name and last name' do
|
80
|
+
person = Person.new(first_name: 'Bob', last_name: 'Winfrey')
|
81
|
+
|
82
|
+
fact { person.first_name == 'Bob' }
|
83
|
+
fact { person.last_name == 'Winfrey' }
|
84
|
+
person.name == 'Bob Winfrey'
|
85
|
+
end
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Output (colored in actual usage):
|
92
|
+
|
93
|
+
```
|
94
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Same-content strings are equal
|
95
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Different-content strings are not equal
|
96
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Same-number integers are equal
|
97
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Different-number integers are not equal
|
98
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality
|
99
|
+
VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts - person name consists of first name and last name - fact { person.first_name == 'Bob' }
|
100
|
+
VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts - person name consists of first name and last name - fact { person.last_name == 'Winfrey' }
|
101
|
+
VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts - person name consists of first name and last name
|
102
|
+
VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts
|
103
|
+
VERIFIED: Glimmer DSL for Specification
|
104
|
+
```
|
105
|
+
|
106
|
+
Failure output when fudging some code (colored in actual usage):
|
107
|
+
|
108
|
+
```
|
109
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Same-content strings are equal
|
110
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Different-content strings are not equal
|
111
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Same-number integers are equal
|
112
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality - Different-number integers are not equal
|
113
|
+
VERIFIED: Glimmer DSL for Specification - Compare Two Objects for Equality
|
114
|
+
VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts - person name consists of first name and last name - fact { person.first_name == 'Bob' }
|
115
|
+
VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts - person name consists of first name and last name - fact { person.last_name == 'Winfrey' }
|
116
|
+
NOT VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts - person name consists of first name and last name
|
117
|
+
NOT VERIFIED: Glimmer DSL for Specification - Verify Multiple Facts
|
118
|
+
NOT VERIFIED: Glimmer DSL for Specification
|
119
|
+
```
|
120
|
+
|
121
|
+
## Usage
|
122
|
+
|
123
|
+
1 - Include in `Gemfile`
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
gem 'glimmer-dsl-specification', '~> 0.0.1'
|
127
|
+
```
|
128
|
+
|
129
|
+
And, run:
|
130
|
+
|
131
|
+
```
|
132
|
+
bundle
|
133
|
+
```
|
134
|
+
|
135
|
+
2 - Create specification files with `_specification.rb` extension under `specification` directory utilizing `specification`, `use_case`, `scenario`, and `fact` keywords explained in [DSL](#dsl) section by adding require statement on top and inserting specification/verification code in `Glimmer::Specification` module:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
require 'glimmer-dsl-specification'
|
139
|
+
|
140
|
+
module Glimmer::Specification
|
141
|
+
specification('title of specification') {
|
142
|
+
use_case('title of use case') {
|
143
|
+
scenario('second scenario') {
|
144
|
+
fact { something2 == something_else2 } # optional
|
145
|
+
fact { something3 != something_else3 } # optional
|
146
|
+
fact { something1.include?(something_else1) } # optional
|
147
|
+
something == something_else # final verification can be a fact if preferred
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
3 - Run a specification directly with ruby:
|
155
|
+
|
156
|
+
```
|
157
|
+
ruby specification/lib/glimmer-dsl-specification_specification.rb
|
158
|
+
```
|
159
|
+
|
160
|
+
4 - Alternatively run `rake verify` task assuming you have `rake` gem installed/configured in `Gemfile`:
|
161
|
+
|
162
|
+
```
|
163
|
+
rake verify
|
164
|
+
```
|
165
|
+
|
166
|
+
It is also recommended that you add the following lines to your `Rakefile`:
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
require 'glimmer-dsl-specification' # unless loaded by Bundler
|
170
|
+
require 'glimmer/specification/rake_tasks'
|
171
|
+
|
172
|
+
task :default => :verify
|
173
|
+
```
|
174
|
+
|
175
|
+
That way, you can simply run:
|
176
|
+
|
177
|
+
```
|
178
|
+
rake
|
179
|
+
```
|
180
|
+
|
181
|
+
## DSL
|
182
|
+
|
183
|
+
The Domain Specific Language consists of the following keywords simply nested under `Glimmer::Specification` module (to avoid namespace pollution).
|
184
|
+
|
185
|
+
This library highly emphasizes declarative specification, so it avoids "test" jargon including "pass" or "fail" and unit-test jargon including "class", "method", "attribute", or "assert" as that is not the ultimate aim of the library, yet specifying application requirements.
|
186
|
+
|
187
|
+
Specifications do not care about what specific "classes" or "methods" are executed. They only care about meeting the verification criteria.
|
188
|
+
|
189
|
+
### specification
|
190
|
+
|
191
|
+
(nested directly under `Glimmer::Specification` module.)
|
192
|
+
|
193
|
+
`specification(title)` is the top-level keyword denoting a requirement specification.
|
194
|
+
|
195
|
+
### use_case
|
196
|
+
|
197
|
+
(nested under `specification`)
|
198
|
+
|
199
|
+
`use_case(title)` represents one or more use cases that the requirement specification consists of
|
200
|
+
|
201
|
+
### scenario
|
202
|
+
|
203
|
+
(nested under `use_case` or directly under `specification` for very simple cases)
|
204
|
+
|
205
|
+
`scenario(title)` represents one scenario in a use case that performs a verification by setting up preconditions, performing an action, and returning the final result as a postconditition boolean or alternatively relying on nested `fact` occurances.
|
206
|
+
|
207
|
+
### fact
|
208
|
+
|
209
|
+
(nested under `scenario`)
|
210
|
+
|
211
|
+
`fact {}` states a fact embodied by a boolean result for the passed block of code.
|
212
|
+
|
213
|
+
## Process
|
214
|
+
|
215
|
+
[Glimmer Process](https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md)
|
216
|
+
|
217
|
+
## Resources
|
218
|
+
|
219
|
+
- [Code Master Blog](https://andymaleh.blogspot.com/search/label/glimmer)
|
220
|
+
|
221
|
+
## Help
|
222
|
+
|
223
|
+
### Issues
|
224
|
+
|
225
|
+
If you encounter [issues](https://github.com/AndyObtiva/glimmer-dsl-specification/issues) that are not reported, discover missing features that are not mentioned in [TODO.md](TODO.md), or think up better ways to write declarative automated tests, you may submit an [issue](https://github.com/AndyObtiva/glimmer-dsl-libui/issues/new) or [pull request](https://github.com/AndyObtiva/glimmer-dsl-specification/compare) on [GitHub](https://github.com). In the meantime, you may try an older version of the [Ruby gem](https://rubygems.org/gems/glimmer-dsl-specification) in case it works better for you until your issues are resolved.
|
226
|
+
|
227
|
+
### Chat
|
228
|
+
|
229
|
+
If you need live help, try to [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
230
|
+
|
231
|
+
## TODO
|
232
|
+
|
233
|
+
[TODO.md](TODO.md)
|
234
|
+
|
235
|
+
## Change Log
|
236
|
+
|
237
|
+
[CHANGELOG.md](CHANGELOG.md)
|
238
|
+
|
239
|
+
## Contributing
|
240
|
+
|
241
|
+
- Check out the latest master to make sure the feature hasn't been
|
242
|
+
implemented or the bug hasn't been fixed yet.
|
243
|
+
- Check out the issue tracker to make sure someone already hasn't
|
244
|
+
requested it and/or contributed it.
|
245
|
+
- Fork the project.
|
246
|
+
- Start a feature/bugfix branch.
|
247
|
+
- Commit and push until you are happy with your contribution.
|
248
|
+
- Make sure to add tests for it. This is important so I don't break it
|
249
|
+
in a future version unintentionally.
|
250
|
+
- Please try not to mess with the Rakefile, version, or history. If
|
251
|
+
you want to have your own version, or is otherwise necessary, that
|
252
|
+
is fine, but please isolate to its own commit so I can cherry-pick
|
253
|
+
around it.
|
254
|
+
|
255
|
+
## Copyright
|
256
|
+
|
257
|
+
[MIT](LICENSE.txt)
|
258
|
+
|
259
|
+
Copyright (c) 2021 Andy Maleh. See
|
260
|
+
[LICENSE.txt](LICENSE.txt) for further details.
|
data/TODO.md
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
# TODO
|
2
|
+
|
3
|
+
- Ensure that each element is only nestable under specific types of elements (e.g. `use_case` can go under `specification` only and `fact` can go under `scenario` only)
|
4
|
+
- Support setting up common `scenario`, `use case` or `specification` preconditions by adding code directly under their block or inside a `before`/`after` block
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Generated by juwelier
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: glimmer-dsl-specification 0.0.1 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "glimmer-dsl-specification".freeze
|
9
|
+
s.version = "0.0.1"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib".freeze]
|
13
|
+
s.authors = ["Andy Maleh".freeze]
|
14
|
+
s.date = "2021-11-23"
|
15
|
+
s.description = "Glimmer DSL for Specification - Pure Ruby Declarative Use Case Specification and Automated Verification".freeze
|
16
|
+
s.email = "andy.am@gmail.com".freeze
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"CHANGELOG.md",
|
19
|
+
"LICENSE.txt",
|
20
|
+
"README.md"
|
21
|
+
]
|
22
|
+
s.files = [
|
23
|
+
"CHANGELOG.md",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.md",
|
26
|
+
"TODO.md",
|
27
|
+
"VERSION",
|
28
|
+
"glimmer-dsl-specification.gemspec",
|
29
|
+
"lib/glimmer-dsl-specification.rb",
|
30
|
+
"lib/glimmer/dsl/specification/attribute_expression.rb",
|
31
|
+
"lib/glimmer/dsl/specification/block_method_expression.rb",
|
32
|
+
"lib/glimmer/dsl/specification/dsl.rb",
|
33
|
+
"lib/glimmer/dsl/specification/element_expression.rb",
|
34
|
+
"lib/glimmer/specification.rb",
|
35
|
+
"lib/glimmer/specification/element.rb",
|
36
|
+
"lib/glimmer/specification/element/fact.rb",
|
37
|
+
"lib/glimmer/specification/element/scenario.rb",
|
38
|
+
"lib/glimmer/specification/element/specification.rb",
|
39
|
+
"lib/glimmer/specification/element/use_case.rb",
|
40
|
+
"lib/glimmer/specification/rake_tasks.rb"
|
41
|
+
]
|
42
|
+
s.homepage = "http://github.com/AndyObtiva/glimmer-dsl-specification".freeze
|
43
|
+
s.licenses = ["MIT".freeze]
|
44
|
+
s.rubygems_version = "3.2.31".freeze
|
45
|
+
s.summary = "Glimmer DSL for Specification".freeze
|
46
|
+
|
47
|
+
if s.respond_to? :specification_version then
|
48
|
+
s.specification_version = 4
|
49
|
+
end
|
50
|
+
|
51
|
+
if s.respond_to? :add_runtime_dependency then
|
52
|
+
s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 2.5.1"])
|
53
|
+
s.add_runtime_dependency(%q<puts_debuggerer>.freeze, ["~> 0.13.1"])
|
54
|
+
s.add_runtime_dependency(%q<colours>.freeze, ["~> 0.6.1"])
|
55
|
+
s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
56
|
+
s.add_development_dependency(%q<rake-tui>.freeze, ["> 0"])
|
57
|
+
s.add_development_dependency(%q<glimmer-dsl-specification>.freeze, [">= 0"])
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<glimmer>.freeze, ["~> 2.5.1"])
|
60
|
+
s.add_dependency(%q<puts_debuggerer>.freeze, ["~> 0.13.1"])
|
61
|
+
s.add_dependency(%q<colours>.freeze, ["~> 0.6.1"])
|
62
|
+
s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
|
63
|
+
s.add_dependency(%q<rake-tui>.freeze, ["> 0"])
|
64
|
+
s.add_dependency(%q<glimmer-dsl-specification>.freeze, [">= 0"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module DSL
|
5
|
+
module Specification
|
6
|
+
class AttributeExpression < Expression
|
7
|
+
def can_interpret?(parent, keyword, *args, &block)
|
8
|
+
parent.respond_to?("#{keyword}=") && !args.empty? && block.nil?
|
9
|
+
end
|
10
|
+
|
11
|
+
def interpret(parent, keyword, *args, &block)
|
12
|
+
parent.send("#{keyword}=", *args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
|
3
|
+
module Glimmer
|
4
|
+
module DSL
|
5
|
+
module Specification
|
6
|
+
class BlockMethodExpression < Expression
|
7
|
+
def can_interpret?(parent, keyword, *args, &block)
|
8
|
+
parent.respond_to?(keyword) and
|
9
|
+
block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
def interpret(parent, keyword, *args, &block)
|
13
|
+
parent.send("#{keyword}", &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'glimmer/dsl/engine'
|
2
|
+
Dir[File.expand_path('*_expression.rb', __dir__)].each {|f| require f}
|
3
|
+
|
4
|
+
module Glimmer
|
5
|
+
module DSL
|
6
|
+
module Specification
|
7
|
+
Engine.add_dynamic_expressions(
|
8
|
+
Specification,
|
9
|
+
%w[
|
10
|
+
block_method
|
11
|
+
attribute
|
12
|
+
element
|
13
|
+
]
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
require 'glimmer/dsl/parent_expression'
|
3
|
+
require 'glimmer/dsl/top_level_expression'
|
4
|
+
require_relative '../../specification/element'
|
5
|
+
|
6
|
+
module Glimmer
|
7
|
+
module DSL
|
8
|
+
module Specification
|
9
|
+
class ElementExpression < Expression
|
10
|
+
include ParentExpression
|
11
|
+
include TopLevelExpression
|
12
|
+
|
13
|
+
def can_interpret?(parent, keyword, *args, &block)
|
14
|
+
Glimmer::Specification::Element.element_exist?(keyword)
|
15
|
+
end
|
16
|
+
|
17
|
+
def interpret(parent, keyword, *args, &block)
|
18
|
+
Glimmer::Specification::Element.element_class(keyword).new(parent, keyword, *args, &block) unless parent&.content_added?
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_content(element, keyword, *args, &block)
|
22
|
+
result = super unless element.executable? && !element.content_added?
|
23
|
+
element.post_add_content
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Specification
|
3
|
+
class Element
|
4
|
+
class Fact < Element
|
5
|
+
def initialize(parent, keyword, *args, &block)
|
6
|
+
@executable = true
|
7
|
+
super
|
8
|
+
source_code = PutsDebuggerer::SourceFile.new(@block.source_location.first).source(1, @block.source_location.last)
|
9
|
+
@title = source_code.strip
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
@verified = @block.call
|
14
|
+
if @verified
|
15
|
+
puts Colours::GREEN + "VERIFIED: #{to_s}"
|
16
|
+
else
|
17
|
+
puts Colours::RED + "NOT VERIFIED: #{to_s}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Specification
|
3
|
+
class Element
|
4
|
+
class Scenario < Element
|
5
|
+
def initialize(parent, keyword, *args, &block)
|
6
|
+
@executable = true
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def fact(&block)
|
11
|
+
new_fact = Fact.new(self, 'fact', [], &block)
|
12
|
+
new_fact.run
|
13
|
+
@verified &&= new_fact.verified?
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
@verified = true
|
18
|
+
own_block_verified = Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Specification::ElementExpression.new, @keyword, &@block)
|
19
|
+
@verified &&= own_block_verified if own_block_verified.is_a?(TrueClass) || own_block_verified.is_a?(FalseClass)
|
20
|
+
if @verified
|
21
|
+
puts Colours::GREEN + "VERIFIED: #{to_s}"
|
22
|
+
else
|
23
|
+
puts Colours::RED + "NOT VERIFIED: #{to_s}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Glimmer
|
2
|
+
module Specification
|
3
|
+
class Element
|
4
|
+
class << self
|
5
|
+
def element_exist?(keyword)
|
6
|
+
constants.include?(element_class_name(keyword)) && element_class(keyword).respond_to?(:new)
|
7
|
+
end
|
8
|
+
|
9
|
+
def element_class(keyword)
|
10
|
+
const_get(element_class_name(keyword))
|
11
|
+
end
|
12
|
+
|
13
|
+
def element_class_name(keyword)
|
14
|
+
keyword.to_s.camelcase(:upper).to_sym
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :parent, :keyword, :args, :block
|
19
|
+
attr_accessor :title
|
20
|
+
|
21
|
+
def initialize(parent, keyword, *args, &block)
|
22
|
+
@parent = parent
|
23
|
+
@keyword = keyword
|
24
|
+
@args = args
|
25
|
+
@title = @args.first
|
26
|
+
@block = block
|
27
|
+
@children = children
|
28
|
+
@parent&.post_initialize_child(self)
|
29
|
+
post_add_content if @block.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
def children
|
33
|
+
@children ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
def verified?
|
37
|
+
@verified
|
38
|
+
end
|
39
|
+
|
40
|
+
def content_added?
|
41
|
+
@content_added
|
42
|
+
end
|
43
|
+
|
44
|
+
# subclasses may override (e.g. Scenario)
|
45
|
+
def executable?
|
46
|
+
!!@executable
|
47
|
+
end
|
48
|
+
|
49
|
+
def scenarios
|
50
|
+
children.map do |child|
|
51
|
+
child.is_a?(Scenario) ? child : child.scenarios
|
52
|
+
end.flatten
|
53
|
+
end
|
54
|
+
|
55
|
+
# ancestors including self ordered from closest to farthest
|
56
|
+
def ancestors
|
57
|
+
if @ancestors.nil?
|
58
|
+
@ancestors = [self]
|
59
|
+
current = self
|
60
|
+
while current.parent
|
61
|
+
current = current.parent
|
62
|
+
@ancestors << current
|
63
|
+
end
|
64
|
+
end
|
65
|
+
@ancestors
|
66
|
+
end
|
67
|
+
|
68
|
+
def post_initialize_child(child)
|
69
|
+
children << child
|
70
|
+
end
|
71
|
+
|
72
|
+
def post_add_content
|
73
|
+
# No Op (subclasses may override to do something at the closing of the element)
|
74
|
+
@content_added = true
|
75
|
+
end
|
76
|
+
|
77
|
+
# Enables re-opening content and adding new shapes
|
78
|
+
def content(&block)
|
79
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Specification::ElementExpression.new, @keyword, &block)
|
80
|
+
end
|
81
|
+
|
82
|
+
# runs children by default. subclasses may override.
|
83
|
+
def run
|
84
|
+
children.each(&:run)
|
85
|
+
@verified = children.all?(&:verified?)
|
86
|
+
if @verified
|
87
|
+
puts Colours::GREEN + "VERIFIED: #{to_s}"
|
88
|
+
else
|
89
|
+
puts Colours::RED + "NOT VERIFIED: #{to_s}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_s
|
94
|
+
ancestors.reverse.map(&:title).join(' - ')
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
Dir[File.expand_path('./element/*.rb', __dir__)].each {|f| require f}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
$LOAD_PATH.unshift(File.expand_path('.', __dir__))
|
23
|
+
|
24
|
+
require 'facets/string/camelcase'
|
25
|
+
require 'puts_debuggerer'
|
26
|
+
require 'colours'
|
27
|
+
require 'glimmer'
|
28
|
+
require 'glimmer/dsl/specification/dsl'
|
29
|
+
require 'glimmer/specification'
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: glimmer-dsl-specification
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andy Maleh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: glimmer
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.5.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.5.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: puts_debuggerer
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.13.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.13.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colours
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: juwelier
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.1.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.1.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake-tui
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: glimmer-dsl-specification
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Glimmer DSL for Specification - Pure Ruby Declarative Use Case Specification
|
98
|
+
and Automated Verification
|
99
|
+
email: andy.am@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files:
|
103
|
+
- CHANGELOG.md
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.md
|
106
|
+
files:
|
107
|
+
- CHANGELOG.md
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- TODO.md
|
111
|
+
- VERSION
|
112
|
+
- glimmer-dsl-specification.gemspec
|
113
|
+
- lib/glimmer-dsl-specification.rb
|
114
|
+
- lib/glimmer/dsl/specification/attribute_expression.rb
|
115
|
+
- lib/glimmer/dsl/specification/block_method_expression.rb
|
116
|
+
- lib/glimmer/dsl/specification/dsl.rb
|
117
|
+
- lib/glimmer/dsl/specification/element_expression.rb
|
118
|
+
- lib/glimmer/specification.rb
|
119
|
+
- lib/glimmer/specification/element.rb
|
120
|
+
- lib/glimmer/specification/element/fact.rb
|
121
|
+
- lib/glimmer/specification/element/scenario.rb
|
122
|
+
- lib/glimmer/specification/element/specification.rb
|
123
|
+
- lib/glimmer/specification/element/use_case.rb
|
124
|
+
- lib/glimmer/specification/rake_tasks.rb
|
125
|
+
homepage: http://github.com/AndyObtiva/glimmer-dsl-specification
|
126
|
+
licenses:
|
127
|
+
- MIT
|
128
|
+
metadata: {}
|
129
|
+
post_install_message:
|
130
|
+
rdoc_options: []
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubygems_version: 3.2.31
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Glimmer DSL for Specification
|
148
|
+
test_files: []
|