glimmer-dsl-specification 0.0.1
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.
- 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
|
+
[](http://badge.fury.io/rb/glimmer-dsl-specification)
|
4
|
+
[](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 [](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: []
|