pad 0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,3 @@
1
+ /.idea/
2
+ /coverage/
3
+ /pkg/
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
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1
6
+ - 2.2
7
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pad.gemspec
4
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ guard :rspec, cmd: 'bundle exec rspec' do
2
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
3
+ watch(%r{^spec/spec_helper.rb$}) { 'spec' }
4
+ watch(%r{^spec/shared/.+.rb$}) { 'spec' }
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ end
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
+ [![Gem Version](https://badge.fury.io/rb/pad.svg)](http://badge.fury.io/rb/pad)
2
+ [![Build Status](https://travis-ci.org/dwhelan/pad.svg?branch=master)](https://travis-ci.org/dwhelan/pad)
3
+ [![Code Climate](https://codeclimate.com/github/dwhelan/pad/badges/gpa.svg)](https://codeclimate.com/github/dwhelan/pad)
4
+ [![Coverage Status](https://coveralls.io/repos/dwhelan/pad/badge.svg?branch=master&service=github)](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
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: [:spec, :rubocop, :build]
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
@@ -0,0 +1,3 @@
1
+ module Pad
2
+ VERSION ||= '0.1'
3
+ end
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,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Version' do
4
+ before { load './lib/pad/version.rb' }
5
+
6
+ it('should be present') { expect(Pad::VERSION).to_not be_empty }
7
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ module Pad
4
+ describe Virtus do
5
+ it_should_behave_like 'an entity builder'
6
+ it_should_behave_like 'a model builder'
7
+ it_should_behave_like 'a value object builder'
8
+ end
9
+ 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
@@ -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