pad 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/.gitignore +3 -0
- data/.rubocop.yml +21 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +133 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +76 -0
- data/Rakefile +8 -0
- data/lib/pad.rb +41 -0
- data/lib/pad/configuration.rb +14 -0
- data/lib/pad/entity.rb +32 -0
- data/lib/pad/repository/memory.rb +25 -0
- data/lib/pad/version.rb +3 -0
- data/lib/pad/virtus.rb +21 -0
- data/pad.gemspec +34 -0
- data/spec/lib/pad/configuration_spec.rb +57 -0
- data/spec/lib/pad/repository/memory_spec.rb +28 -0
- data/spec/lib/pad/version_spec.rb +7 -0
- data/spec/lib/pad/virtus_spec.rb +9 -0
- data/spec/lib/pad_spec.rb +32 -0
- data/spec/shared/attribute_examples.rb +45 -0
- data/spec/shared/entity_examples.rb +82 -0
- data/spec/shared/model_examples.rb +22 -0
- data/spec/shared/value_object_examples.rb +24 -0
- data/spec/spec_helper.rb +27 -0
- metadata +236 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 058b01c4386ace1f7d6a9b898fa6da23f9b0518b
|
4
|
+
data.tar.gz: ea3349c1c52820c85d39b1974e7eb890e8e30b9b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c33ce3a17e5f3cb20f78f5c6a0720f5ffc43d4707b749ea2537ace2490db1fa3bf55c3637d435527d5babb55bae664ddd88b3d714e921d6d763c79bbc1bb9467
|
7
|
+
data.tar.gz: fce9ff83eab32c09ad397270670789627b83cde079387007c83d54b936db64b464f1b9e2e7aed0db8bf258b69141b8de18bbc10206cec0ee1d564582fa092207
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Metrics/LineLength:
|
2
|
+
Max: 160
|
3
|
+
Enabled: false
|
4
|
+
|
5
|
+
Lint/AmbiguousRegexpLiteral:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Style/TrailingComma:
|
9
|
+
EnforcedStyleForMultiline: comma
|
10
|
+
|
11
|
+
Style/EmptyLineBetweenDefs:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/SingleSpaceBeforeFirstArg:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Style/Documentation:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Lint/Eval:
|
21
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
pad (0.1)
|
5
|
+
virtus (~> 1.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.1.0)
|
11
|
+
astrolabe (1.3.1)
|
12
|
+
parser (~> 2.2)
|
13
|
+
attribute_matcher (0.1)
|
14
|
+
axiom-types (0.1.1)
|
15
|
+
descendants_tracker (~> 0.0.4)
|
16
|
+
ice_nine (~> 0.11.0)
|
17
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
18
|
+
coderay (1.1.0)
|
19
|
+
coercible (1.0.0)
|
20
|
+
descendants_tracker (~> 0.0.1)
|
21
|
+
coveralls (0.7.2)
|
22
|
+
multi_json (~> 1.3)
|
23
|
+
rest-client (= 1.6.7)
|
24
|
+
simplecov (>= 0.7)
|
25
|
+
term-ansicolor (= 1.2.2)
|
26
|
+
thor (= 0.18.1)
|
27
|
+
delegate_matcher (0.0.1)
|
28
|
+
descendants_tracker (0.0.4)
|
29
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
30
|
+
diff-lcs (1.2.5)
|
31
|
+
docile (1.1.5)
|
32
|
+
equalizer (0.0.11)
|
33
|
+
ffi (1.9.10)
|
34
|
+
formatador (0.2.5)
|
35
|
+
guard (2.13.0)
|
36
|
+
formatador (>= 0.2.4)
|
37
|
+
listen (>= 2.7, <= 4.0)
|
38
|
+
lumberjack (~> 1.0)
|
39
|
+
nenv (~> 0.1)
|
40
|
+
notiffany (~> 0.0)
|
41
|
+
pry (>= 0.9.12)
|
42
|
+
shellany (~> 0.0)
|
43
|
+
thor (>= 0.18.1)
|
44
|
+
guard-compat (1.2.1)
|
45
|
+
guard-rspec (4.6.4)
|
46
|
+
guard (~> 2.1)
|
47
|
+
guard-compat (~> 1.1)
|
48
|
+
rspec (>= 2.99.0, < 4.0)
|
49
|
+
ice_nine (0.11.1)
|
50
|
+
listen (3.0.3)
|
51
|
+
rb-fsevent (>= 0.9.3)
|
52
|
+
rb-inotify (>= 0.9)
|
53
|
+
lumberjack (1.0.9)
|
54
|
+
method_source (0.8.2)
|
55
|
+
mime-types (2.4.3)
|
56
|
+
multi_json (1.10.1)
|
57
|
+
nenv (0.2.0)
|
58
|
+
notiffany (0.0.8)
|
59
|
+
nenv (~> 0.1)
|
60
|
+
shellany (~> 0.0)
|
61
|
+
parser (2.2.2.6)
|
62
|
+
ast (>= 1.1, < 3.0)
|
63
|
+
powerpack (0.1.1)
|
64
|
+
pry (0.10.2)
|
65
|
+
coderay (~> 1.1.0)
|
66
|
+
method_source (~> 0.8.1)
|
67
|
+
slop (~> 3.4)
|
68
|
+
rainbow (2.0.0)
|
69
|
+
rake (10.4.2)
|
70
|
+
rb-fsevent (0.9.6)
|
71
|
+
rb-inotify (0.9.5)
|
72
|
+
ffi (>= 0.5.0)
|
73
|
+
rest-client (1.6.7)
|
74
|
+
mime-types (>= 1.16)
|
75
|
+
rspec (3.3.0)
|
76
|
+
rspec-core (~> 3.3.0)
|
77
|
+
rspec-expectations (~> 3.3.0)
|
78
|
+
rspec-mocks (~> 3.3.0)
|
79
|
+
rspec-core (3.3.2)
|
80
|
+
rspec-support (~> 3.3.0)
|
81
|
+
rspec-expectations (3.3.1)
|
82
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
83
|
+
rspec-support (~> 3.3.0)
|
84
|
+
rspec-its (1.1.0)
|
85
|
+
rspec-core (>= 3.0.0)
|
86
|
+
rspec-expectations (>= 3.0.0)
|
87
|
+
rspec-mocks (3.3.2)
|
88
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
89
|
+
rspec-support (~> 3.3.0)
|
90
|
+
rspec-support (3.3.0)
|
91
|
+
rubocop (0.33.0)
|
92
|
+
astrolabe (~> 1.3)
|
93
|
+
parser (>= 2.2.2.5, < 3.0)
|
94
|
+
powerpack (~> 0.1)
|
95
|
+
rainbow (>= 1.99.1, < 3.0)
|
96
|
+
ruby-progressbar (~> 1.4)
|
97
|
+
ruby-progressbar (1.7.5)
|
98
|
+
shellany (0.0.1)
|
99
|
+
simplecov (0.9.1)
|
100
|
+
docile (~> 1.1.0)
|
101
|
+
multi_json (~> 1.0)
|
102
|
+
simplecov-html (~> 0.8.0)
|
103
|
+
simplecov-html (0.8.0)
|
104
|
+
slop (3.6.0)
|
105
|
+
term-ansicolor (1.2.2)
|
106
|
+
tins (~> 0.8)
|
107
|
+
thor (0.18.1)
|
108
|
+
thread_safe (0.3.5)
|
109
|
+
tins (0.13.2)
|
110
|
+
virtus (1.0.5)
|
111
|
+
axiom-types (~> 0.1)
|
112
|
+
coercible (~> 1.0)
|
113
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
114
|
+
equalizer (~> 0.0, >= 0.0.9)
|
115
|
+
|
116
|
+
PLATFORMS
|
117
|
+
ruby
|
118
|
+
|
119
|
+
DEPENDENCIES
|
120
|
+
attribute_matcher (~> 0.1)
|
121
|
+
bundler (~> 1.7)
|
122
|
+
coveralls (~> 0.7)
|
123
|
+
delegate_matcher (~> 0.0)
|
124
|
+
guard (~> 2.13)
|
125
|
+
guard-rspec (~> 4.6)
|
126
|
+
pad!
|
127
|
+
rake (~> 10.0)
|
128
|
+
rspec (~> 3.0)
|
129
|
+
rspec-its (~> 1.1)
|
130
|
+
rubocop (~> 0.30)
|
131
|
+
|
132
|
+
BUNDLED WITH
|
133
|
+
1.10.6
|
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Declan Whelan
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
[](http://badge.fury.io/rb/pad)
|
2
|
+
[](https://travis-ci.org/dwhelan/pad)
|
3
|
+
[](https://codeclimate.com/github/dwhelan/pad)
|
4
|
+
[](https://coveralls.io/github/dwhelan/pad?branch=master)
|
5
|
+
|
6
|
+
# Pad
|
7
|
+
|
8
|
+
A gem that enables a [Ports and Adapter](http://alistair.cockburn.us/Hexagonal+architecture) architectural style with [Domain Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design).
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'pad'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install pad
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
### Entities
|
29
|
+
You can create entities which have a built-in 'id' attribute which uniquely identifies the entity.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'pad'
|
33
|
+
|
34
|
+
class Person
|
35
|
+
include Pad.entity
|
36
|
+
|
37
|
+
attribute :name
|
38
|
+
attribute :age
|
39
|
+
end
|
40
|
+
|
41
|
+
dave = Person.new id: 21, name: "Dave", age: 32 # => #<Person:0x007feaf4a3c668 @id=21, @name="Dave", @age=32>
|
42
|
+
dave.id # => 21
|
43
|
+
dave.name # => "Dave"
|
44
|
+
dave.age # => 32
|
45
|
+
|
46
|
+
another_dave = Person.new id: 21
|
47
|
+
dave == another_dave # => true
|
48
|
+
```
|
49
|
+
|
50
|
+
### Custom Classes
|
51
|
+
You can create your own classes and use Pad attributes.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
require 'pad'
|
55
|
+
|
56
|
+
class Vehicle
|
57
|
+
include Pad.model
|
58
|
+
|
59
|
+
attribute :year
|
60
|
+
attribute :manufacturer
|
61
|
+
attribute :make
|
62
|
+
end
|
63
|
+
|
64
|
+
sienna = Vehicle.new year: 2006, manufacturer: 'Toyota', make: 'Sienna' # => #<Vehicle:0x007fcdacd2ff38 @year=2006, @manufacturer="Toyota", @make="Sienna">
|
65
|
+
sienna.year # => 2006
|
66
|
+
sienna.year = 2007
|
67
|
+
sienna # => #<Vehicle:0x007fcdacd2ff38 @year=2007, @manufacturer="Toyota", @make="Sienna">
|
68
|
+
```
|
69
|
+
|
70
|
+
## Contributing
|
71
|
+
|
72
|
+
1. Fork it ( https://github.com/dwhelan/pad/fork )
|
73
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
74
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
75
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
76
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/pad.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'pad/virtus'
|
2
|
+
|
3
|
+
require 'pad/configuration'
|
4
|
+
require 'pad/version'
|
5
|
+
require 'pad/entity'
|
6
|
+
require 'pad/repository/memory'
|
7
|
+
|
8
|
+
module Pad
|
9
|
+
class << self
|
10
|
+
[:model, :entity, :value_object].each do |method|
|
11
|
+
define_method method do |options = {}, &block|
|
12
|
+
build(method, options, &block)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def config
|
17
|
+
yield configuration if block_given?
|
18
|
+
configuration
|
19
|
+
end
|
20
|
+
|
21
|
+
def reset
|
22
|
+
@configuration = Configuration.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
def build(method, options, &block)
|
27
|
+
options = options.dup
|
28
|
+
builder(options).public_send(method, options, &block)
|
29
|
+
end
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def builder(options)
|
33
|
+
options.delete(:builder) || configuration.builder
|
34
|
+
end
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
def configuration
|
38
|
+
@configuration ||= Configuration.new
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Pad
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :builder
|
4
|
+
attr_accessor :repository
|
5
|
+
|
6
|
+
# @api private
|
7
|
+
def initialize(options = {})
|
8
|
+
self.builder = options.fetch(:builder, Pad::Virtus)
|
9
|
+
self.repository = options.fetch(:repository, Pad::Repository::Memory)
|
10
|
+
|
11
|
+
yield self if block_given?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/pad/entity.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Pad
|
2
|
+
module Entity
|
3
|
+
def self.included(base)
|
4
|
+
base.instance_eval do
|
5
|
+
attribute :id
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def ==(other)
|
10
|
+
cmp?(__method__, other)
|
11
|
+
end
|
12
|
+
|
13
|
+
def eql?(other)
|
14
|
+
cmp?(__method__, other)
|
15
|
+
end
|
16
|
+
|
17
|
+
def hash
|
18
|
+
[self.class, id].hash
|
19
|
+
end
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def cmp?(comparator, other)
|
23
|
+
return false unless other.class == self.class
|
24
|
+
|
25
|
+
if id.nil?
|
26
|
+
equal?(other)
|
27
|
+
else
|
28
|
+
id.send(comparator, other.id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Pad
|
2
|
+
module Repository
|
3
|
+
class Memory
|
4
|
+
def initialize
|
5
|
+
self.repository = {}
|
6
|
+
end
|
7
|
+
|
8
|
+
def save(entity)
|
9
|
+
repository[entity.id] = entity
|
10
|
+
end
|
11
|
+
|
12
|
+
def find(id)
|
13
|
+
repository[id]
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(entity)
|
17
|
+
repository[entity.id] = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_accessor :repository
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/pad/version.rb
ADDED
data/lib/pad/virtus.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'virtus'
|
2
|
+
|
3
|
+
module Pad
|
4
|
+
module Virtus
|
5
|
+
[:model, :value_object].each do |method|
|
6
|
+
define_singleton_method method do |options = {}, &block|
|
7
|
+
::Virtus.public_send(method, options, &block)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.entity(options = {}, &block)
|
12
|
+
EntityBuilder.call(options, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
class EntityBuilder < ::Virtus::ModelBuilder
|
16
|
+
def extensions
|
17
|
+
super + [Entity]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/pad.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require 'pad/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = 'pad'
|
9
|
+
gem.version = Pad::VERSION
|
10
|
+
gem.authors = ['Declan Whelan']
|
11
|
+
gem.email = ['declan@pleanintuit.com']
|
12
|
+
gem.summary = 'A light weight framework for supporting Ports & Adapters designs with Domain Driven Design'
|
13
|
+
gem.description = 'A light weight framework for supporting Ports & Adapters designs with Domain Driven Design'
|
14
|
+
gem.homepage = 'https://github.com/dwhelan/pad'
|
15
|
+
gem.license = 'MIT'
|
16
|
+
|
17
|
+
gem.files = `git ls-files -z`.split("\x0")
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ['lib']
|
21
|
+
|
22
|
+
gem.add_dependency 'virtus', '~> 1.0'
|
23
|
+
|
24
|
+
gem.add_development_dependency 'attribute_matcher', '~> 0.1'
|
25
|
+
gem.add_development_dependency 'bundler', '~> 1.7'
|
26
|
+
gem.add_development_dependency 'coveralls', '~> 0.7'
|
27
|
+
gem.add_development_dependency 'delegate_matcher', '~> 0.0'
|
28
|
+
gem.add_development_dependency 'guard', '~> 2.13'
|
29
|
+
gem.add_development_dependency 'guard-rspec', '~> 4.6'
|
30
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
31
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
gem.add_development_dependency 'rspec-its', '~> 1.1'
|
33
|
+
gem.add_development_dependency 'rubocop', '~> 0.30'
|
34
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pad
|
4
|
+
describe Configuration do
|
5
|
+
describe 'initialize' do
|
6
|
+
it 'should allow no options' do
|
7
|
+
Configuration.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should allow options' do
|
11
|
+
Configuration.new(some: :option)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should yield self' do
|
15
|
+
yeilded_argument = nil
|
16
|
+
configuration = Configuration.new { |arg| yeilded_argument = arg }
|
17
|
+
expect(yeilded_argument).to be configuration
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'builder' do
|
22
|
+
let(:builder) { double 'builder' }
|
23
|
+
|
24
|
+
it 'should default to Pad::Virtus' do
|
25
|
+
expect(subject.builder).to be Pad::Virtus
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should be settable' do
|
29
|
+
subject.builder = builder
|
30
|
+
expect(subject.builder).to be builder
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be settable via initialization' do
|
34
|
+
configuration = Configuration.new(builder: builder)
|
35
|
+
expect(configuration.builder).to be builder
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'repository' do
|
40
|
+
let(:repository) { double 'repository' }
|
41
|
+
|
42
|
+
it 'should default to Pad::Repository::Memory' do
|
43
|
+
expect(subject.repository).to be Pad::Repository::Memory
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should be settable' do
|
47
|
+
subject.repository = repository
|
48
|
+
expect(subject.repository).to be repository
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should be settable via initialization' do
|
52
|
+
configuration = Configuration.new(repository: repository)
|
53
|
+
expect(configuration.repository).to be repository
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pad
|
4
|
+
module Repository
|
5
|
+
describe Memory do
|
6
|
+
let(:entity) { OpenStruct.new id: 42 }
|
7
|
+
|
8
|
+
describe 'find' do
|
9
|
+
it { should respond_to :find }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'save' do
|
13
|
+
it 'should save' do
|
14
|
+
subject.save entity
|
15
|
+
expect(subject.find 42).to be entity
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'delete' do
|
20
|
+
it 'should delete' do
|
21
|
+
subject.save entity
|
22
|
+
subject.delete entity
|
23
|
+
expect(subject.find 42).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Pad do
|
4
|
+
subject { Pad }
|
5
|
+
|
6
|
+
let(:options) { { some: :option } }
|
7
|
+
let(:builder) { double 'builder' }
|
8
|
+
let(:default_builder) { Pad.config.builder }
|
9
|
+
|
10
|
+
[:model, :entity, :value_object].each do |method|
|
11
|
+
describe method do
|
12
|
+
context 'with default builder' do
|
13
|
+
it { should delegate(method).with(options).to(default_builder).with_block }
|
14
|
+
it { should delegate(method).with.to(default_builder).with({}).with_block }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with global builder' do
|
18
|
+
before { Pad.config.builder = builder }
|
19
|
+
after { Pad.reset }
|
20
|
+
|
21
|
+
it { should delegate(method).with(options).to(builder).with_block }
|
22
|
+
it { should delegate(method).with.to(builder).with({}).with_block }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with specified builder' do
|
26
|
+
let(:options) { { builder: builder } }
|
27
|
+
|
28
|
+
it { should delegate(method).with(options).to(builder).with({}).with_block }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Pad
|
2
|
+
shared_examples 'attribute examples' do |mod|
|
3
|
+
let(:klass) { Class.new { include mod } }
|
4
|
+
subject { klass.new }
|
5
|
+
|
6
|
+
describe 'reader' do
|
7
|
+
before do
|
8
|
+
klass.class_eval do
|
9
|
+
attribute :name
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it { is_expected.to have_attribute(:name).with_reader(:public) }
|
14
|
+
it { expect(subject.name).to be_nil }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'type' do
|
18
|
+
before do
|
19
|
+
klass.class_eval do
|
20
|
+
attribute :name, String, default: ''
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it { is_expected.to have_attribute(:name).of_type(String) }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'visibility' do
|
28
|
+
before do
|
29
|
+
klass.class_eval do
|
30
|
+
attribute :private, String, reader: :private, writer: :private
|
31
|
+
attribute :protected, String, reader: :protected, writer: :protected
|
32
|
+
attribute :public, String, reader: :public, writer: :public
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it { is_expected.to have_attribute(:private). with_reader(:private). with_writer(:private) }
|
37
|
+
it { is_expected.to have_attribute(:protected).with_reader(:protected).with_writer(:protected) }
|
38
|
+
it { is_expected.to have_attribute(:public). with_reader(:public). with_writer(:public) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# TODO: add checks for mass assignment, constructor
|
42
|
+
# TODO: add checks for constructor
|
43
|
+
# TODO: add optional features of model
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Pad
|
2
|
+
shared_examples_for 'an entity builder' do
|
3
|
+
include_examples 'an entity module', described_class.entity
|
4
|
+
end
|
5
|
+
|
6
|
+
shared_examples_for 'an entity module' do |mod|
|
7
|
+
include_examples 'a model module', mod
|
8
|
+
|
9
|
+
let(:entity_class) { Class.new { include mod } }
|
10
|
+
let(:subclass) { Class.new(entity_class).new(id: 1) }
|
11
|
+
|
12
|
+
let(:entity0) { entity_class.new id: nil }
|
13
|
+
let(:entity0a) { entity_class.new id: nil }
|
14
|
+
let(:entity1) { entity_class.new id: 1 }
|
15
|
+
let(:entity1a) { entity_class.new id: 1 }
|
16
|
+
let(:entity2) { entity_class.new id: 2 }
|
17
|
+
|
18
|
+
it('should have an "id" attribute') { expect(entity1).to have_attributes id: 1 }
|
19
|
+
|
20
|
+
describe 'hash' do
|
21
|
+
it('for the same entity id should be equal') { expect(entity1.hash).to eq entity1a.hash }
|
22
|
+
it('for different entity ids should not be equal') { expect(entity1.hash).not_to eq entity2.hash }
|
23
|
+
it('for different classes should not be equal') { expect(entity1.hash).not_to eq subclass.hash }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'equality' do
|
27
|
+
context 'with nil id' do
|
28
|
+
it 'should be true when compared to self' do
|
29
|
+
expect(entity0).to eq entity0
|
30
|
+
expect(entity0).to eql entity0
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be false when compared to another entity with a nil id' do
|
34
|
+
expect(entity0).not_to eq entity0a
|
35
|
+
expect(entity0).not_to eql entity0a
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with the same id' do
|
40
|
+
it 'should be true when compared to self' do
|
41
|
+
expect(entity1).to eq entity1
|
42
|
+
expect(entity1).to eql entity1
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should be true when compared to another entity with the same id' do
|
46
|
+
expect(entity1).to eq entity1a
|
47
|
+
expect(entity1).to eql entity1a
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with a different id' do
|
52
|
+
it 'should be true when compared to another entity with a different id' do
|
53
|
+
expect(entity1).not_to eq entity2
|
54
|
+
expect(entity1).not_to eql entity2
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with an object of a different class' do
|
59
|
+
it 'should be false' do
|
60
|
+
expect(entity1).not_to eq Object.new
|
61
|
+
expect(entity1).not_to eql Object.new
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'with an object that is a subclass' do
|
66
|
+
it 'should be false' do
|
67
|
+
expect(entity1).not_to eq subclass
|
68
|
+
expect(entity1).not_to eql subclass
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with an object that is a superclass' do
|
73
|
+
it 'should be false' do
|
74
|
+
expect(subclass).not_to eq entity1
|
75
|
+
expect(subclass).not_to eql entity1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# TODO: Check for options being handled with entity
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Pad
|
2
|
+
shared_examples_for 'a model builder' do
|
3
|
+
include_examples 'a model module', described_class.model
|
4
|
+
end
|
5
|
+
|
6
|
+
shared_examples 'a model module' do |mod|
|
7
|
+
include_examples 'attribute examples', mod
|
8
|
+
|
9
|
+
let(:klass) { Class.new { include mod } }
|
10
|
+
subject { klass.new }
|
11
|
+
|
12
|
+
describe 'default visibility' do
|
13
|
+
before do
|
14
|
+
klass.class_eval do
|
15
|
+
attribute :default
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it { is_expected.to have_attribute(:default).with_reader(:public).with_writer(:public) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Pad
|
2
|
+
shared_examples_for 'a value object builder' do
|
3
|
+
include_examples 'a value object module', described_class.value_object
|
4
|
+
end
|
5
|
+
|
6
|
+
shared_examples 'a value object module' do |mod|
|
7
|
+
include_examples 'attribute examples', mod
|
8
|
+
|
9
|
+
let(:klass) { Class.new { include mod } }
|
10
|
+
subject { klass.new }
|
11
|
+
|
12
|
+
describe 'default visibility' do
|
13
|
+
subject { klass.new }
|
14
|
+
|
15
|
+
before do
|
16
|
+
klass.class_eval do
|
17
|
+
attribute :default
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it { is_expected.to have_attribute(:default).with_reader(:public).with_writer(:private) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'coveralls'
|
3
|
+
require 'simplecov'
|
4
|
+
require 'rspec/its'
|
5
|
+
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
7
|
+
SimpleCov::Formatter::HTMLFormatter,
|
8
|
+
Coveralls::SimpleCov::Formatter
|
9
|
+
]
|
10
|
+
SimpleCov.start
|
11
|
+
|
12
|
+
Coveralls.wear! if Coveralls.will_run?
|
13
|
+
|
14
|
+
Dir['./spec/shared/**/*.rb'].sort.each { |f| require f }
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.color = true
|
18
|
+
config.filter_run focus: true
|
19
|
+
config.run_all_when_everything_filtered = true
|
20
|
+
config.expect_with :rspec do |expectations|
|
21
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'pad'
|
26
|
+
require 'attribute_matcher'
|
27
|
+
require 'delegate_matcher'
|
metadata
ADDED
@@ -0,0 +1,236 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pad
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Declan Whelan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: virtus
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: attribute_matcher
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coveralls
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.7'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.7'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: delegate_matcher
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.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.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.13'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.13'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '4.6'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '4.6'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rake
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '10.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '10.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '3.0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '3.0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rspec-its
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.1'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.1'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.30'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.30'
|
167
|
+
description: A light weight framework for supporting Ports & Adapters designs with
|
168
|
+
Domain Driven Design
|
169
|
+
email:
|
170
|
+
- declan@pleanintuit.com
|
171
|
+
executables: []
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- ".gitignore"
|
176
|
+
- ".rubocop.yml"
|
177
|
+
- ".travis.yml"
|
178
|
+
- Gemfile
|
179
|
+
- Gemfile.lock
|
180
|
+
- Guardfile
|
181
|
+
- LICENSE.txt
|
182
|
+
- README.md
|
183
|
+
- Rakefile
|
184
|
+
- lib/pad.rb
|
185
|
+
- lib/pad/configuration.rb
|
186
|
+
- lib/pad/entity.rb
|
187
|
+
- lib/pad/repository/memory.rb
|
188
|
+
- lib/pad/version.rb
|
189
|
+
- lib/pad/virtus.rb
|
190
|
+
- pad.gemspec
|
191
|
+
- spec/lib/pad/configuration_spec.rb
|
192
|
+
- spec/lib/pad/repository/memory_spec.rb
|
193
|
+
- spec/lib/pad/version_spec.rb
|
194
|
+
- spec/lib/pad/virtus_spec.rb
|
195
|
+
- spec/lib/pad_spec.rb
|
196
|
+
- spec/shared/attribute_examples.rb
|
197
|
+
- spec/shared/entity_examples.rb
|
198
|
+
- spec/shared/model_examples.rb
|
199
|
+
- spec/shared/value_object_examples.rb
|
200
|
+
- spec/spec_helper.rb
|
201
|
+
homepage: https://github.com/dwhelan/pad
|
202
|
+
licenses:
|
203
|
+
- MIT
|
204
|
+
metadata: {}
|
205
|
+
post_install_message:
|
206
|
+
rdoc_options: []
|
207
|
+
require_paths:
|
208
|
+
- lib
|
209
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
210
|
+
requirements:
|
211
|
+
- - ">="
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: '0'
|
214
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
215
|
+
requirements:
|
216
|
+
- - ">="
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: '0'
|
219
|
+
requirements: []
|
220
|
+
rubyforge_project:
|
221
|
+
rubygems_version: 2.4.5
|
222
|
+
signing_key:
|
223
|
+
specification_version: 4
|
224
|
+
summary: A light weight framework for supporting Ports & Adapters designs with Domain
|
225
|
+
Driven Design
|
226
|
+
test_files:
|
227
|
+
- spec/lib/pad/configuration_spec.rb
|
228
|
+
- spec/lib/pad/repository/memory_spec.rb
|
229
|
+
- spec/lib/pad/version_spec.rb
|
230
|
+
- spec/lib/pad/virtus_spec.rb
|
231
|
+
- spec/lib/pad_spec.rb
|
232
|
+
- spec/shared/attribute_examples.rb
|
233
|
+
- spec/shared/entity_examples.rb
|
234
|
+
- spec/shared/model_examples.rb
|
235
|
+
- spec/shared/value_object_examples.rb
|
236
|
+
- spec/spec_helper.rb
|