euston 1.2.3-java → 1.2.4-java

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.
data/euston.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'euston'
3
- s.version = '1.2.3'
4
- s.date = '2011-10-24'
3
+ s.version = '1.2.4'
4
+ s.date = '2011-11-29'
5
5
  s.platform = RUBY_PLATFORM.to_s == 'java' ? 'java' : Gem::Platform::RUBY
6
6
  s.authors = ['Lee Henson', 'Guy Boertje']
7
7
  s.email = ['lee.m.henson@gmail.com', 'guyboertje@gmail.com']
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
35
35
  spec/aggregate_command_map_spec.rb
36
36
  spec/aggregate_root_samples.rb
37
37
  spec/aggregate_root_spec.rb
38
+ spec/command_headers_spec.rb
38
39
  spec/spec_helper.rb
39
40
  ]
40
41
  # = MANIFEST =
@@ -161,10 +161,17 @@ module Euston
161
161
 
162
162
  def deliver_message headers, message, name_method, message_kind, expected_block_kind
163
163
  name = self.class.send(name_method, headers.type, headers.version).to_sym
164
-
165
164
  if respond_to? name
166
165
  @log.debug "Calling #{name} with: #{message.inspect}"
167
- method(name).call OpenStruct.new(message).freeze
166
+ m = method(name)
167
+ case m.arity
168
+ when 2, -2
169
+ m.call OpenStruct.new(headers.to_hash).freeze, OpenStruct.new(message).freeze
170
+ when 1, -1
171
+ m.call OpenStruct.new(message).freeze
172
+ else
173
+ m.call
174
+ end
168
175
  else
169
176
  raise "Couldn't deliver #{message_kind} (#{headers.type} v#{headers.version}) to #{self.class}. Did you forget #{expected_block_kind}?"
170
177
  end
@@ -40,8 +40,7 @@ module Euston
40
40
  private
41
41
 
42
42
  def define_private_method name, &block
43
- block = method(:null_block) if block.nil?
44
- define_method name do |*args| instance_exec *args, &block end
43
+ define_method name, &(block || method(:null_block))
45
44
  end
46
45
 
47
46
  def map_command(entry_point, type, command, opts)
@@ -22,6 +22,14 @@ module Euston
22
22
  @headers[:id] = value
23
23
  end
24
24
 
25
+ def publishing_user_id
26
+ @headers[:user_id]
27
+ end
28
+
29
+ def publishing_user_id= value
30
+ @headers[:user_id] = value
31
+ end
32
+
25
33
  def read_attribute_for_validation key
26
34
  match = /^__(.*)/.match(key.to_s)
27
35
 
@@ -1,29 +1,58 @@
1
1
  module Euston
2
2
  class CommandHeaders
3
- attr_reader :id, :type, :version, :log_completion
4
3
 
5
- def initialize id, type, version, log_completion = false
6
- @id = id
7
- @type = type
8
- @version = version
9
- @log_completion = log_completion
4
+ BASE_KEYS = [:id, :type, :version]
5
+
6
+ def initialize hash
7
+ arg_errors = []
8
+ BASE_KEYS.each do |arg|
9
+ arg_errors << arg unless hash.has_key?(arg)
10
+ end
11
+ raise Errors::CommandHeadersArgumentError.new("Missing args: #{arg_errors.join(", ")}") if arg_errors.size > 0
12
+ @headers = {}.merge(hash)
13
+ @headers[:type] = @headers[:type].to_sym
14
+ @headers_keys = @headers.keys
15
+ end
16
+
17
+ def [] name
18
+ @headers[name.to_sym]
10
19
  end
11
20
 
21
+ # only use method missing for uncommon attributes
22
+ def id() @headers[:id]; end
23
+ def type() @headers[:type]; end
24
+ def version() @headers[:version]; end
25
+
12
26
  def to_hash
13
- {
14
- :id => id,
15
- :type => type,
16
- :version => version,
17
- :log_completion => log_completion
18
- }
27
+ @headers.dup
28
+ end
29
+
30
+ def ==(other)
31
+ @headers == other.to_hash
19
32
  end
20
33
 
21
34
  def self.from_hash hash
22
- self.new hash[:id], hash[:type].to_sym, hash[:version], ( hash[:log_completion] || false )
35
+ self.new hash
23
36
  end
24
37
 
25
38
  def to_s
26
39
  "#{id} #{type} (v#{version})"
27
40
  end
41
+
42
+ def method_missing(name,*args,&block)
43
+ n = name.to_sym
44
+ is_dynamic_method?(n) ? @headers[n] : super
45
+ end
46
+
47
+ # >= 1.9.2
48
+ def respond_to_missing?(name, incl_private)
49
+ is_dynamic_method?(name.to_sym) || super
50
+ end
51
+
52
+ private
53
+
54
+ def is_dynamic_method? name
55
+ (@headers_keys - BASE_KEYS).include?(name)
56
+ end
28
57
  end
29
58
  end
data/lib/euston/errors.rb CHANGED
@@ -2,5 +2,6 @@ module Euston
2
2
  module Errors
3
3
  class InvalidCommandError < StandardError; end
4
4
  class AggregateNotFoundError < StandardError; end
5
+ class CommandHeadersArgumentError < StandardError; end
5
6
  end
6
7
  end
@@ -8,7 +8,7 @@ module Euston
8
8
  end
9
9
 
10
10
  module ClassMethods
11
- def subscribes type, version = 1, opts = nil, &consumer
11
+ def subscribes type, version = 1, opts = {}, &consumer
12
12
  if self.include? Euston::AggregateRoot
13
13
  o = { :id => :id }.merge opts
14
14
 
@@ -21,8 +21,12 @@ module Euston
21
21
  end
22
22
  end
23
23
 
24
- define_method event_handler_method_name(type, version) do |*args|
25
- instance_exec *args, &consumer
24
+ method_name = event_handler_method_name type, version
25
+ define_method method_name, &consumer
26
+ new_method = instance_method method_name
27
+
28
+ define_method method_name do |*args|
29
+ new_method.bind(self).call *args
26
30
  end
27
31
  end
28
32
  end
@@ -1,3 +1,3 @@
1
1
  module Euston
2
- VERSION = "1.2.3"
2
+ VERSION = "1.2.4"
3
3
  end
@@ -6,17 +6,17 @@ module Euston
6
6
  let(:guid1) {Euston.uuid.generate}
7
7
  let(:guid2) {Euston.uuid.generate}
8
8
 
9
- let(:command_cw) { { :headers => CommandHeaders.new(Euston.uuid.generate, :create_widget, 1),
9
+ let(:command_cw) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'create_widget', version: 1),
10
10
  :body => { :id => guid1} } }
11
- let(:command_iw) { { :headers => CommandHeaders.new(Euston.uuid.generate, :import_widget, 1),
11
+ let(:command_iw) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'import_widget', version: 1),
12
12
  :body => { :id => guid1, :imported_count => 5 } } }
13
- let(:command_aw) { { :headers => CommandHeaders.new(Euston.uuid.generate, :log_access_to_widget, 1),
13
+ let(:command_aw) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'log_access_to_widget', version: 1),
14
14
  :body => { :widget_id => guid1 } } }
15
- let(:command_cp) { { :headers => CommandHeaders.new(Euston.uuid.generate, :create_product, 1),
15
+ let(:command_cp) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'create_product', version: 1),
16
16
  :body => { :id => guid2} } }
17
- let(:command_ip) { { :headers => CommandHeaders.new(Euston.uuid.generate, :import_product, 1),
17
+ let(:command_ip) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'import_product', version: 1),
18
18
  :body => { :id => guid2, :imported_count => 5 } } }
19
- let(:command_ap) { { :headers => CommandHeaders.new(Euston.uuid.generate, :log_access_to_product, 1),
19
+ let(:command_ap) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'log_access_to_product', version: 1),
20
20
  :body => { :product_id => guid2 } } }
21
21
 
22
22
  describe "when creating new Aggregates" do
@@ -3,20 +3,20 @@ module Euston
3
3
  class Widget
4
4
  include Euston::AggregateRoot
5
5
 
6
- created_by :create_widget do |command|
6
+ created_by :create_widget do |header, command|
7
7
  apply_event :widget_created, 1, command
8
8
  end
9
9
 
10
- created_by :import_widget do |command|
10
+ created_by :import_widget do |header, command|
11
11
  apply_event :widget_imported, 1, :access_count => (@access_count || 0) + command.imported_count
12
12
  end
13
13
 
14
- consumes :log_access_to_widget, :id => :widget_id do |command|
14
+ consumes :log_access_to_widget, :id => :widget_id do |header, command|
15
15
  apply_event :widget_access_logged, 1, :widget_id => command.widget_id,
16
16
  :access_count => @access_count + 1
17
17
  end
18
18
 
19
- applies :widget_created, 1 do |event|
19
+ applies :widget_created, 1 do
20
20
  @access_count = 0
21
21
  end
22
22
 
@@ -32,11 +32,11 @@ module Euston
32
32
  class Product
33
33
  include Euston::AggregateRoot
34
34
 
35
- created_by :create_product do |command|
35
+ created_by :create_product do |header, command|
36
36
  apply_event :product_created, 1, command
37
37
  end
38
38
 
39
- created_by :import_product do |command|
39
+ created_by :import_product do |header, command|
40
40
  apply_event :product_imported, 1, :access_count => command.imported_count
41
41
  end
42
42
 
@@ -5,7 +5,7 @@ module Euston
5
5
  context 'duplicate command consumption' do
6
6
  let(:aggregate) { Sample::Widget.new }
7
7
  let(:aggregate2) { Sample::Widget.new }
8
- let(:command) { { :headers => CommandHeaders.new(Euston.uuid.generate, :create_widget, 1),
8
+ let(:command) { { :headers => CommandHeaders.new(id: Euston.uuid.generate, type: 'create_widget', version: 1),
9
9
  :body => { :id => Euston.uuid.generate } } }
10
10
 
11
11
  it 'does not handle the same command twice' do
@@ -0,0 +1,51 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+
3
+ module Euston
4
+ describe 'command_headers' do
5
+ let(:header) { CommandHeaders.new(parameters) }
6
+ context 'a new command headers object' do
7
+ it 'traps incorrect construction' do
8
+ expect { CommandHeaders.new({}) }.to raise_error(Errors::CommandHeadersArgumentError)
9
+ expect { CommandHeaders.new(id: 'foo', type: 'bah') }.to raise_error(Errors::CommandHeadersArgumentError,/version/)
10
+ expect { CommandHeaders.new(type: 'bah', version: 3) }.to raise_error(Errors::CommandHeadersArgumentError,/id/)
11
+ expect { CommandHeaders.new(id: 'foo', version: 2) }.to raise_error(Errors::CommandHeadersArgumentError,/type/)
12
+ end
13
+ let(:parameters) {{ id: 'foo', type: 'bah', version: 3 }}
14
+ it 'creates one from a hash' do
15
+ CommandHeaders.from_hash(parameters).should == header
16
+ end
17
+ end
18
+ context 'accessors' do
19
+ let(:parameters) {{ id: 'foo', type: 'bah', version: 3 }}
20
+ it 'converts type to a symbol' do
21
+ header.type.should == :bah
22
+ end
23
+ it 'has various accessor methods' do
24
+ header.id.should == 'foo'
25
+ header.version.should == 3
26
+ header[:id].should == 'foo'
27
+ header[:type].should == :bah
28
+ header['version'].should == 3
29
+ end
30
+ it 'treats respond_to correctly' do
31
+ header.respond_to?(:type).should be_true
32
+ header.respond_to?(:user_id).should be_false
33
+ end
34
+ end
35
+ context 'with more than the basic attributes' do
36
+ let(:parameters) {{ id: 'foo', type: 'bah', version: 3, user_id: 'bobby123' }}
37
+ it 'allows access to the extra attributes' do
38
+ header.respond_to?(:user_id).should be_true
39
+ header.user_id.should == 'bobby123'
40
+ header[:user_id].should == 'bobby123'
41
+ end
42
+ end
43
+ context 'auxilliary methods' do
44
+ let(:parameters) {{ id: 'foo', type: 'bah', version: 3, user_id: 'bobby123' }}
45
+ it 'has methods' do
46
+ header.to_hash.should == {id: 'foo', type: :bah, version: 3, user_id: 'bobby123'}
47
+ header.to_s.should == 'foo bah (v3)'
48
+ end
49
+ end
50
+ end
51
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,8 @@
1
1
  require 'euston'
2
2
  require 'aggregate_root_samples'
3
+
4
+ def apr(what, header='')
5
+ puts '', "== #{header} =="
6
+ puts what.inspect
7
+ puts ("="*(header.size + 6)), ''
8
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: euston
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.2.3
5
+ version: 1.2.4
6
6
  platform: java
7
7
  authors:
8
8
  - Lee Henson
@@ -10,62 +10,61 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-10-24 00:00:00.000000000 +01:00
14
- default_executable:
13
+ date: 2011-11-29 00:00:00.000000000Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: activemodel
18
- version_requirements: &2202 !ruby/object:Gem::Requirement
17
+ version_requirements: &2058 !ruby/object:Gem::Requirement
19
18
  requirements:
20
19
  - - ! '>='
21
20
  - !ruby/object:Gem::Version
22
21
  version: 3.0.10
23
22
  none: false
24
- requirement: *2202
23
+ requirement: *2058
25
24
  prerelease: false
26
25
  type: :runtime
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: activesupport
29
- version_requirements: &2220 !ruby/object:Gem::Requirement
28
+ version_requirements: &2076 !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ! '>='
32
31
  - !ruby/object:Gem::Version
33
32
  version: 3.0.10
34
33
  none: false
35
- requirement: *2220
34
+ requirement: *2076
36
35
  prerelease: false
37
36
  type: :runtime
38
37
  - !ruby/object:Gem::Dependency
39
38
  name: fuubar
40
- version_requirements: &2236 !ruby/object:Gem::Requirement
39
+ version_requirements: &2092 !ruby/object:Gem::Requirement
41
40
  requirements:
42
41
  - - ~>
43
42
  - !ruby/object:Gem::Version
44
43
  version: 0.0.0
45
44
  none: false
46
- requirement: *2236
45
+ requirement: *2092
47
46
  prerelease: false
48
47
  type: :development
49
48
  - !ruby/object:Gem::Dependency
50
49
  name: rspec
51
- version_requirements: &2254 !ruby/object:Gem::Requirement
50
+ version_requirements: &2110 !ruby/object:Gem::Requirement
52
51
  requirements:
53
52
  - - ~>
54
53
  - !ruby/object:Gem::Version
55
54
  version: 2.6.0
56
55
  none: false
57
- requirement: *2254
56
+ requirement: *2110
58
57
  prerelease: false
59
58
  type: :development
60
59
  - !ruby/object:Gem::Dependency
61
60
  name: uuid
62
- version_requirements: &2270 !ruby/object:Gem::Requirement
61
+ version_requirements: &2126 !ruby/object:Gem::Requirement
63
62
  requirements:
64
63
  - - ~>
65
64
  - !ruby/object:Gem::Version
66
65
  version: 2.3.0
67
66
  none: false
68
- requirement: *2270
67
+ requirement: *2126
69
68
  prerelease: false
70
69
  type: :development
71
70
  description: ''
@@ -100,8 +99,8 @@ files:
100
99
  - spec/aggregate_command_map_spec.rb
101
100
  - spec/aggregate_root_samples.rb
102
101
  - spec/aggregate_root_spec.rb
102
+ - spec/command_headers_spec.rb
103
103
  - spec/spec_helper.rb
104
- has_rdoc: true
105
104
  homepage: http://github.com/leemhenson/euston
106
105
  licenses: []
107
106
  post_install_message:
@@ -122,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
121
  none: false
123
122
  requirements: []
124
123
  rubyforge_project:
125
- rubygems_version: 1.5.1
124
+ rubygems_version: 1.8.9
126
125
  signing_key:
127
126
  specification_version: 3
128
127
  summary: Cqrs tooling.
@@ -130,5 +129,6 @@ test_files:
130
129
  - spec/aggregate_command_map_spec.rb
131
130
  - spec/aggregate_root_samples.rb
132
131
  - spec/aggregate_root_spec.rb
132
+ - spec/command_headers_spec.rb
133
133
  - spec/spec_helper.rb
134
134
  ...