domain_driven 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59a6fe1d7e8c0296a5fa6728d2b5686c5fabfc75
4
- data.tar.gz: 8b1cfcd6aebfeea2fd2035bbfcdfc8e45002c92d
3
+ metadata.gz: 251c9fc04d7f0f75d31e9297e0955f0f4283fcd7
4
+ data.tar.gz: aade59de5dc666d44fb172661e058e647c66eddb
5
5
  SHA512:
6
- metadata.gz: bd45d510cd4d2896c1c55617775af8944f66da2430bf7a6fba3d9e41072d6cca6f345da8444ccfd5c6e372bf8fd3facc83b03647ca5cd8ca140994bff007c3c8
7
- data.tar.gz: d7fb00f95a05fda5f00cce62939a19da5d75ed41c4741a75d2242ad961fc27c5d528bb0cf7efdba1b32e443fa9133b426012fdb9919da1f9e5433d568a3ac301
6
+ metadata.gz: 42d95a7056e73495ecca772bdedc44e6099730cdd96afc13a4d0a6f6d6444f8ccc4f70005a79f5cc2401bfcb82020564cd15f676e0717c5af2e97e0cafc58cc2
7
+ data.tar.gz: 4f4a720942aeb869d88a806575dad97e50a3a2967947f2ee10c318fed3a03cbac7cb95c50a58b03dd67c6cca4f6880826b63f2afe255e5017683a0c03684ae2f
data/README.md CHANGED
@@ -1,3 +1,9 @@
1
+ [![Gem Version](https://badge.fury.io/rb/domain_driven.png)](http://badge.fury.io/rb/domain_driven)
2
+
3
+ # Gem Status
4
+ As of 4 March 2014, Incomplete Extraction.
5
+ This gem is in the process of being extracted from a reference architecture RubyOnRails application.
6
+
1
7
  # DomainDriven
2
8
 
3
9
  This gem and set of techniques allow you to use *DDD* to controll complexity and dependencies as your RubyOnRails application grows. The additional benefit is that since core domain logic is decoupled from the Rails framework and database, automated tests of the core domain logic can run very fast.
@@ -58,3 +64,4 @@ For providing the concept of Domain Driven Design
58
64
  3. Commit your changes (`git commit -am 'Add some feature'`)
59
65
  4. Push to the branch (`git push origin my-new-feature`)
60
66
  5. Create new Pull Request
67
+
@@ -20,4 +20,11 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.5"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rails", '~> 4.0.2'
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency 'rspec-given'
26
+ spec.add_runtime_dependency 'interactor'
27
+ spec.add_runtime_dependency 'pundit'
28
+ spec.add_runtime_dependency 'activerecord'
29
+
23
30
  end
@@ -1,5 +1,12 @@
1
1
  require "domain_driven/version"
2
+ require "domain_driven/errors"
3
+ require "domain_driven/service"
4
+ require "domain_driven/repository"
5
+ require "domain_driven/block_active_record"
6
+ require "domain_driven/model"
7
+ require "domain_driven/entity"
8
+ require "domain_driven/criteria"
2
9
 
3
10
  module DomainDriven
4
- # Your code goes here...
11
+
5
12
  end
@@ -0,0 +1,42 @@
1
+ # Thanks to Jim Weirich for the concepts in this class.
2
+ # Extracted from https://github.com/jimweirich/wyriki
3
+ # domain_driven would not be possible without this critical part.
4
+
5
+ module DomainDriven
6
+
7
+ ActiveRecordNotAvailableError = Class.new(StandardError)
8
+
9
+ # Include this module to block ActiveRecord save/update_attributes
10
+ # calls on the object.
11
+ module BlockActiveRecord
12
+ def save
13
+ no_db_methods
14
+ end
15
+
16
+ def save!
17
+ no_db_methods
18
+ end
19
+
20
+ def update_attribute(*args)
21
+ no_db_methods
22
+ end
23
+
24
+ def update_attribute!(*args)
25
+ no_db_methods
26
+ end
27
+
28
+ def update_attributes(*args)
29
+ no_db_methods
30
+ end
31
+
32
+ def update_attributes!(*args)
33
+ no_db_methods
34
+ end
35
+
36
+ private
37
+
38
+ def no_db_methods
39
+ fail ActiveRecordNotAvailableError, "No DB methods on Business Objects"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,81 @@
1
+ module DomainDriven
2
+
3
+ class Message
4
+ def initialize(name, args=nil)
5
+ @name, @args = name, args
6
+ end
7
+
8
+ def to_s
9
+ "#{@name}(#{@args})"
10
+ end
11
+
12
+ def sendable
13
+ if @args
14
+ [@name.to_sym, @args]
15
+ else
16
+ @name.to_sym
17
+ end
18
+ end
19
+ end
20
+
21
+ class Criteria
22
+
23
+ def initialize()
24
+ @chain = []
25
+ end
26
+
27
+ def shift(criteria)
28
+ criteria.chain.each do |e|
29
+ add_message(e)
30
+ end
31
+ self
32
+ end
33
+
34
+ def unshift(criteria)
35
+ criteria.shift(self)
36
+ criteria
37
+ end
38
+
39
+ # sugar
40
+ def add(name, *args)
41
+ add_message(DomainDriven::Message.new(name, *args))
42
+ end
43
+
44
+ def to_s
45
+ return '' if @chain.empty?
46
+ "target." + @chain.map(&:to_s).join('.')
47
+ end
48
+
49
+ def send_to(target)
50
+ @chain.each do |e|
51
+ target = target.send(*(e.sendable))
52
+ end
53
+ target
54
+ end
55
+
56
+ def method_missing(sym, *args, &block)
57
+ self.add(sym.to_sym, *args)
58
+ end
59
+
60
+ # override Kernal.load
61
+ def load
62
+ self.add(:load)
63
+ end
64
+
65
+ def find(*)
66
+ raise "not supported"
67
+ end
68
+
69
+ def chain
70
+ @chain
71
+ end
72
+
73
+ private
74
+
75
+ def add_message(message)
76
+ @chain << message
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,61 @@
1
+ # Thanks to Jim Weirich for the concepts in this class.
2
+ # Extracted from https://github.com/jimweirich/wyriki
3
+ # domain_driven would not be possible without this critical part.
4
+
5
+ require 'delegate'
6
+
7
+ module DomainDriven
8
+ class Entity < SimpleDelegator
9
+ include BlockActiveRecord
10
+
11
+ def _data
12
+ datum = self
13
+ while datum.entity?
14
+ datum = datum.__getobj__
15
+ end
16
+ datum
17
+ end
18
+
19
+ def ==(other)
20
+ if other.respond_to?(:_data)
21
+ _data == other._data
22
+ else
23
+ _data == other
24
+ end
25
+ end
26
+
27
+ def entity?
28
+ true
29
+ end
30
+
31
+ def class
32
+ _data.class
33
+ end
34
+
35
+ def self.wrap(entity)
36
+ entity ? new(entity) : nil
37
+ end
38
+
39
+ def self.wraps(entities)
40
+ return nil unless entities
41
+ wrap(entities.extend Model).extend Collection
42
+ end
43
+
44
+ end
45
+
46
+ module Collection
47
+ def each
48
+ _data.each do |_item|
49
+ yield wrap(_item)
50
+ end
51
+ end
52
+ def include?(other)
53
+ if other.respond_to?(:_data)
54
+ _data.include?(other._data)
55
+ else
56
+ _data.include?(other)
57
+ end
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,5 @@
1
+ module DomainDriven
2
+ class Error < StandardError; end
3
+ class RecordNotFound < StandardError; end
4
+ class NotAuthorizedError < StandardError; end
5
+ end
@@ -0,0 +1,45 @@
1
+ # Thanks to Jim Weirich for the concepts in this class.
2
+ # Extracted from https://github.com/jimweirich/wyriki
3
+ # domain_driven would not be possible without this critical part.
4
+
5
+ module DomainDriven
6
+
7
+ # Include in ActiveRecord models to mimic Entity models.
8
+ module Model
9
+ def _data
10
+ self
11
+ end
12
+
13
+ def entity?
14
+ false
15
+ end
16
+
17
+ def ==(other)
18
+ if other.respond_to?(:entity?) && other.entity?
19
+ self == other._data
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+
27
+ def find(*)
28
+ super
29
+ rescue ActiveRecord::RecordNotFound => error
30
+ raise DomainDriven::RecordNotFound.new(error)
31
+ rescue => error
32
+ raise DomainDriven::Error.new(error)
33
+ end
34
+
35
+ end
36
+
37
+
38
+ def self.included(klass)
39
+ super
40
+ klass.extend ClassMethods
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,11 @@
1
+ class DomainDriven::Repository
2
+
3
+ protected
4
+ def initialize(name, logger)
5
+ @name = name
6
+ @logger = logger
7
+ end
8
+
9
+ def logger; @logger; end
10
+
11
+ end
@@ -0,0 +1,39 @@
1
+ require "interactor"
2
+ require "pundit"
3
+
4
+ module DomainDriven
5
+ class Service
6
+ include Interactor
7
+ include Pundit
8
+
9
+ def perform
10
+ perform_main
11
+ rescue DomainDriven::RecordNotFound
12
+ raise
13
+ rescue Pundit::NotAuthorizedError
14
+ raise
15
+ # rescue => x
16
+ # perform_rescue(x)
17
+ end
18
+
19
+ protected
20
+ def current_user
21
+ context[:current_member]
22
+ end
23
+
24
+ def request
25
+ context[:request]
26
+ end
27
+
28
+ def perform_main
29
+ raise "subclass responsibility for #{self.class} "
30
+ end
31
+
32
+ def perform_rescue(x)
33
+ context[:errors] = x.message
34
+ context.fail!
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -1,3 +1,3 @@
1
1
  module DomainDriven
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Criteria' do
4
+
5
+ Given! (:criteria) { DomainDriven::Criteria.new }
6
+
7
+ context "combining two criteria" do
8
+ Given! (:criteria1) { criteria }
9
+ Given! (:criteria2) { DomainDriven::Criteria.new }
10
+ Given { criteria1.where("id=5") }
11
+ Given { criteria2.page("3") }
12
+
13
+ context "shift" do
14
+ When(:result) { criteria1.shift(criteria2) }
15
+ Then { result.to_s.should eq("target.where(id=5).page(3)") }
16
+ end
17
+
18
+ context "unshift" do
19
+ When(:result) { criteria2.unshift(criteria1) }
20
+ Then { result.to_s.should eq("target.where(id=5).page(3)") }
21
+ end
22
+
23
+ end
24
+
25
+ context "empty criteria has no effect" do
26
+ Then { criteria.to_s.should eq("")}
27
+
28
+ context "send_to" do
29
+ Given(:target) { 'hello' }
30
+ When(:result) { criteria.send_to(target) }
31
+ Then { result.should eq('hello') }
32
+ end
33
+ end
34
+
35
+ context "send #where" do
36
+ Given(:email) { 'todd@example.com' }
37
+ When { criteria.where("email='#{email}'") }
38
+ Then { criteria.to_s.should eq("target.where(email='#{email}')") }
39
+ end
40
+
41
+ context "send #load" do
42
+ When(:result) { criteria.load }
43
+ Then { criteria.to_s.should eq("target.load()") }
44
+ # Then { expect(result).to have_failed(ArgumentError, /wrong number of arguments/) }
45
+ end
46
+
47
+ context "send #reverse " do
48
+ When { criteria.reverse }
49
+ Then { criteria.to_s.should eq("target.reverse()")}
50
+
51
+ context "send_to" do
52
+ Given(:target) { '123456' }
53
+ When(:result) { criteria.send_to(target) }
54
+ Then { result.should eq('654321') }
55
+ end
56
+ end
57
+
58
+ context "send #chomp with arugment " do
59
+ Whereas { criteria.chomp("llo") }
60
+ Then { criteria.to_s.should eq("target.chomp(llo)") }
61
+
62
+ context "send_to" do
63
+ Given(:target) { 'hello' }
64
+ Whereas(:result) { criteria.send_to(target) }
65
+ Then { result.should eq('he') }
66
+
67
+ context "send a second message" do
68
+ Given { criteria.add('+', " is great" ) }
69
+ Then { criteria.to_s.should eq("target.chomp(llo).+( is great)")}
70
+ Whereas(:result) { criteria.send_to(target) }
71
+ Then { result.should eq('he is great') }
72
+ end
73
+
74
+ context "send a second message with syntactic sugar" do
75
+ Given { criteria + " is great" }
76
+ Then { criteria.to_s.should eq("target.chomp(llo).+( is great)")}
77
+ Whereas(:result) { criteria.send_to(target) }
78
+ Then { result.should eq('he is great') }
79
+ end
80
+
81
+ end
82
+ end
83
+
84
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'rspec-given'
3
+ require 'domain_driven'
4
+
5
+ module Given
6
+ module ClassExtensions
7
+ alias Whereas Given
8
+ alias Whereas! Given!
9
+ end
10
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: domain_driven
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Windholtz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-01 00:00:00.000000000 Z
11
+ date: 2014-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,90 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.0.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.0.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-given
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: interactor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pundit
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activerecord
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
41
125
  description: Domain Driven provides Rails abstract classes and generators to support
42
126
  for a Domain Driven Design
43
127
  email:
@@ -53,7 +137,16 @@ files:
53
137
  - Rakefile
54
138
  - domain_driven.gemspec
55
139
  - lib/domain_driven.rb
140
+ - lib/domain_driven/block_active_record.rb
141
+ - lib/domain_driven/criteria.rb
142
+ - lib/domain_driven/entity.rb
143
+ - lib/domain_driven/errors.rb
144
+ - lib/domain_driven/model.rb
145
+ - lib/domain_driven/repository.rb
146
+ - lib/domain_driven/service.rb
56
147
  - lib/domain_driven/version.rb
148
+ - spec/domain_driven/criteria_spec.rb
149
+ - spec/spec_helper.rb
57
150
  homepage: https://github.com/mwindholtz/domain_driven
58
151
  licenses:
59
152
  - MIT
@@ -74,8 +167,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
167
  version: '0'
75
168
  requirements: []
76
169
  rubyforge_project:
77
- rubygems_version: 2.1.11
170
+ rubygems_version: 2.2.2
78
171
  signing_key:
79
172
  specification_version: 4
80
173
  summary: Domain Driven provides Rails hooks for a Domain Driven Design
81
- test_files: []
174
+ test_files:
175
+ - spec/domain_driven/criteria_spec.rb
176
+ - spec/spec_helper.rb