serf 0.10.0 → 0.11.0

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.
Files changed (59) hide show
  1. data/.gitignore +21 -0
  2. data/.travis.yml +7 -0
  3. data/Gemfile +20 -26
  4. data/Guardfile +16 -0
  5. data/NOTICE.txt +1 -1
  6. data/README.md +223 -207
  7. data/Rakefile +3 -18
  8. data/lib/serf/builder.rb +31 -136
  9. data/lib/serf/errors/policy_failure.rb +10 -0
  10. data/lib/serf/middleware/error_handler.rb +53 -0
  11. data/lib/serf/middleware/parcel_freezer.rb +36 -0
  12. data/lib/serf/middleware/parcel_masher.rb +39 -0
  13. data/lib/serf/middleware/policy_checker.rb +31 -0
  14. data/lib/serf/middleware/uuid_tagger.rb +13 -11
  15. data/lib/serf/parcel_builder.rb +30 -0
  16. data/lib/serf/serfer.rb +27 -66
  17. data/lib/serf/util/error_handling.rb +13 -36
  18. data/lib/serf/util/protected_call.rb +2 -2
  19. data/lib/serf/util/uuidable.rb +14 -38
  20. data/lib/serf/version.rb +1 -1
  21. data/schemas/{caught_exception_event.json → serf/events/caught_error.json} +4 -7
  22. data/serf.gemspec +22 -101
  23. data/spec/serf/builder_spec.rb +44 -0
  24. data/spec/serf/errors/policy_failure_spec.rb +11 -0
  25. data/spec/serf/middleware/error_handler_spec.rb +48 -0
  26. data/spec/serf/middleware/parcel_freezer_spec.rb +20 -0
  27. data/spec/serf/middleware/parcel_masher_spec.rb +30 -0
  28. data/spec/serf/middleware/policy_checker_spec.rb +70 -0
  29. data/spec/serf/middleware/uuid_tagger_spec.rb +32 -0
  30. data/spec/serf/parcel_builder_spec.rb +46 -0
  31. data/spec/serf/serfer_spec.rb +61 -0
  32. data/spec/serf/util/error_handling_spec.rb +35 -0
  33. data/spec/serf/util/null_object_spec.rb +26 -0
  34. data/spec/serf/util/options_extraction_spec.rb +62 -0
  35. data/spec/serf/util/protected_call_spec.rb +33 -0
  36. data/spec/serf/util/uuidable_spec.rb +56 -0
  37. data/spec/serf_spec.rb +1 -4
  38. data/spec/spec_helper.rb +3 -0
  39. data/spec/support/error_handling_wrapper.rb +5 -0
  40. data/spec/support/factories.rb +32 -0
  41. data/spec/support/failing_policy.rb +9 -0
  42. data/spec/support/json_schema_tester.rb +14 -0
  43. data/spec/support/options_extraction_wrapper.rb +10 -0
  44. data/spec/support/passing_policy.rb +7 -0
  45. data/spec/support/protected_call_wrapper.rb +5 -0
  46. metadata +81 -131
  47. data/.document +0 -5
  48. data/.rspec +0 -1
  49. data/Gemfile.lock +0 -58
  50. data/docs/thread_pools.txt +0 -16
  51. data/lib/serf/command.rb +0 -79
  52. data/lib/serf/error.rb +0 -11
  53. data/lib/serf/errors/not_found.rb +0 -8
  54. data/lib/serf/middleware/girl_friday_async.rb +0 -39
  55. data/lib/serf/middleware/masherize.rb +0 -25
  56. data/lib/serf/routing/regexp_matcher.rb +0 -35
  57. data/lib/serf/routing/route.rb +0 -35
  58. data/lib/serf/routing/route_set.rb +0 -64
  59. data/schemas/message_accepted_event.json +0 -14
@@ -2,6 +2,8 @@ require 'base64'
2
2
  require 'hashie'
3
3
  require 'uuidtools'
4
4
 
5
+ require 'serf/util/options_extraction'
6
+
5
7
  module Serf
6
8
  module Util
7
9
 
@@ -11,30 +13,14 @@ module Util
11
13
  # 1. Primarily to create and parse 'coded' UUIDs, which are just
12
14
  # base64 encoded UUIDs without trailing '='.
13
15
  #
14
- module Uuidable
15
-
16
- ##
17
- # @see self.create_coded_uuid
18
- def create_coded_uuid
19
- Uuidable.create_coded_uuid
20
- end
21
-
22
- ##
23
- # @see self.parse_coded_uuid
24
- def parse_coded_uuid(coded_uuid)
25
- Uuidable.parse_coded_uuid coded_uuid
26
- end
16
+ class Uuidable
17
+ include Serf::Util::OptionsExtraction
27
18
 
28
- ##
29
- # @see self.create_uuids
30
- def create_uuids(parent={})
31
- Uuidable.create_uuids parent
32
- end
19
+ attr_reader :uuid_tool
33
20
 
34
- ##
35
- # @see self.annotate_with_uuids!
36
- def annotate_with_uuids!(message, parent={})
37
- Uuidable.annotate_with_uuids! message, parent
21
+ def initialize(*args)
22
+ extract_options! args
23
+ @uuid_tool = opts :uuid_tool, UUIDTools::UUID
38
24
  end
39
25
 
40
26
  ##
@@ -42,27 +28,28 @@ module Util
42
28
  #
43
29
  # NOTE: UUIDTools TimeStamp code creates a UTC based timestamp UUID.
44
30
  #
45
- def self.create_coded_uuid
31
+ def create_coded_uuid
46
32
  # All raw UUIDs are 16 bytes long. Base64 lengthens the string to
47
33
  # 24 bytes long. We chomp off the last two equal signs '==' to
48
34
  # trim the string length to 22 bytes. This gives us an overhead
49
35
  # of an extra 6 bytes over raw UUID, but with the readability
50
36
  # benefit. And saves us 14 bytes of size from the 'standard'
51
37
  # string hex representation of UUIDs.
52
- Base64.urlsafe_encode64(UUIDTools::UUID.timestamp_create.raw).chomp('==')
38
+ Base64.urlsafe_encode64(uuid_tool.timestamp_create.raw).chomp('==')
53
39
  end
54
40
 
55
41
  ##
56
42
  # @param coded_uuid a coded uuid to parse.
57
43
  #
58
- def self.parse_coded_uuid(coded_uuid)
59
- UUIDTools::UUID.parse_raw Base64.urlsafe_decode64("#{coded_uuid}==")
44
+ def parse_coded_uuid(coded_uuid)
45
+ uuid_tool.parse_raw Base64.urlsafe_decode64("#{coded_uuid}==")
60
46
  end
61
47
 
62
48
  ##
63
49
  # Create a new set of uuids.
64
50
  #
65
- def self.create_uuids(parent={})
51
+ def create_uuids(parent=nil)
52
+ parent ||= {}
66
53
  Hashie::Mash.new(
67
54
  uuid: create_coded_uuid,
68
55
  parent_uuid: parent[:uuid],
@@ -72,17 +59,6 @@ module Util
72
59
  parent[:uuid]))
73
60
  end
74
61
 
75
- ##
76
- # Set a message's UUIDs with new UUIDs based on the parent's UUIDs.
77
- #
78
- def self.annotate_with_uuids!(message, parent={})
79
- uuids = self.create_uuids parent
80
- message[:uuid] ||= uuids[:uuid]
81
- message[:parent_uuid] ||= uuids[:parent_uuid]
82
- message[:origin_uuid] ||= uuids[:origin_uuid]
83
- return nil
84
- end
85
-
86
62
  end
87
63
 
88
64
  end
data/lib/serf/version.rb CHANGED
@@ -2,7 +2,7 @@ module Serf
2
2
 
3
3
  module Version
4
4
  MAJOR = 0
5
- MINOR = 10
5
+ MINOR = 11
6
6
  PATCH = 0
7
7
  BUILD = nil
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join '.'
@@ -1,20 +1,17 @@
1
1
  {
2
- "description": "Message Kind: serf/messages/caught_exception_event",
2
+ "description": "serf/events/caught_error",
3
3
  "type": "object",
4
4
  "properties": {
5
- "context": {
6
- "type": "object"
7
- },
8
5
  "error": {
9
6
  "type": "string"
10
7
  },
11
8
  "message": {
12
9
  "type": "string"
13
10
  },
14
- "backtrace": {
15
- "type": "string"
11
+ "process_env": {
12
+ "type": "object"
16
13
  },
17
- "uuid": {
14
+ "backtrace": {
18
15
  "type": "string"
19
16
  }
20
17
  }
data/serf.gemspec CHANGED
@@ -1,107 +1,28 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
1
  # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/serf/version', __FILE__)
5
3
 
6
- Gem::Specification.new do |s|
7
- s.name = "serf"
8
- s.version = "0.10.0"
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'serf'
6
+ gem.version = Serf::Version::STRING
7
+ gem.authors = ['Benjamin Yu']
8
+ gem.email = 'benjaminlyu@gmail.com'
9
+ gem.description = 'Interactors with policy protection'
10
+ gem.summary = 'Interactors with policy protection'
11
+ gem.homepage = 'http://github.com/byu/serf'
12
+ gem.licenses = ['Apache 2.0']
9
13
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Benjamin Yu"]
12
- s.date = "2012-05-30"
13
- s.description = "Event-Driven SOA with CQRS"
14
- s.email = "benjaminlyu@gmail.com"
15
- s.extra_rdoc_files = [
16
- "LICENSE.txt",
17
- "README.md"
14
+ gem.rubygems_version = '1.8.17'
15
+ gem.files = `git ls-files`.split($\)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+ gem.extra_rdoc_files = [
20
+ 'LICENSE.txt',
21
+ 'NOTICE.txt',
22
+ 'README.md'
18
23
  ]
19
- s.files = [
20
- ".document",
21
- ".rspec",
22
- "Gemfile",
23
- "Gemfile.lock",
24
- "LICENSE.txt",
25
- "NOTICE.txt",
26
- "README.md",
27
- "Rakefile",
28
- "docs/thread_pools.txt",
29
- "lib/serf.rb",
30
- "lib/serf/builder.rb",
31
- "lib/serf/command.rb",
32
- "lib/serf/error.rb",
33
- "lib/serf/errors/not_found.rb",
34
- "lib/serf/middleware/girl_friday_async.rb",
35
- "lib/serf/middleware/masherize.rb",
36
- "lib/serf/middleware/uuid_tagger.rb",
37
- "lib/serf/routing/regexp_matcher.rb",
38
- "lib/serf/routing/route.rb",
39
- "lib/serf/routing/route_set.rb",
40
- "lib/serf/serfer.rb",
41
- "lib/serf/util/error_handling.rb",
42
- "lib/serf/util/null_object.rb",
43
- "lib/serf/util/options_extraction.rb",
44
- "lib/serf/util/protected_call.rb",
45
- "lib/serf/util/uuidable.rb",
46
- "lib/serf/version.rb",
47
- "schemas/caught_exception_event.json",
48
- "schemas/message_accepted_event.json",
49
- "serf.gemspec",
50
- "spec/serf_spec.rb",
51
- "spec/spec_helper.rb"
52
- ]
53
- s.homepage = "http://github.com/byu/serf"
54
- s.licenses = ["Apache 2.0"]
55
- s.require_paths = ["lib"]
56
- s.rubygems_version = "1.8.17"
57
- s.summary = "Event-Driven SOA with CQRS"
58
-
59
- if s.respond_to? :specification_version then
60
- s.specification_version = 3
61
24
 
62
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
63
- s.add_runtime_dependency(%q<activesupport>, [">= 3.2.0"])
64
- s.add_runtime_dependency(%q<i18n>, [">= 0.6.0"])
65
- s.add_runtime_dependency(%q<hashie>, [">= 1.2.0"])
66
- s.add_runtime_dependency(%q<uuidtools>, [">= 2.1.2"])
67
- s.add_development_dependency(%q<rspec>, ["~> 2.8.0"])
68
- s.add_development_dependency(%q<yard>, ["~> 0.7.5"])
69
- s.add_development_dependency(%q<bundler>, ["~> 1.1.3"])
70
- s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
71
- s.add_development_dependency(%q<simplecov>, [">= 0"])
72
- s.add_development_dependency(%q<log4r>, [">= 1.1.10"])
73
- s.add_development_dependency(%q<msgpack>, [">= 0.4.6"])
74
- s.add_development_dependency(%q<eventmachine>, [">= 0.12.10"])
75
- s.add_development_dependency(%q<girl_friday>, [">= 0.9.7"])
76
- else
77
- s.add_dependency(%q<activesupport>, [">= 3.2.0"])
78
- s.add_dependency(%q<i18n>, [">= 0.6.0"])
79
- s.add_dependency(%q<hashie>, [">= 1.2.0"])
80
- s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
81
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
82
- s.add_dependency(%q<yard>, ["~> 0.7.5"])
83
- s.add_dependency(%q<bundler>, ["~> 1.1.3"])
84
- s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
85
- s.add_dependency(%q<simplecov>, [">= 0"])
86
- s.add_dependency(%q<log4r>, [">= 1.1.10"])
87
- s.add_dependency(%q<msgpack>, [">= 0.4.6"])
88
- s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
89
- s.add_dependency(%q<girl_friday>, [">= 0.9.7"])
90
- end
91
- else
92
- s.add_dependency(%q<activesupport>, [">= 3.2.0"])
93
- s.add_dependency(%q<i18n>, [">= 0.6.0"])
94
- s.add_dependency(%q<hashie>, [">= 1.2.0"])
95
- s.add_dependency(%q<uuidtools>, [">= 2.1.2"])
96
- s.add_dependency(%q<rspec>, ["~> 2.8.0"])
97
- s.add_dependency(%q<yard>, ["~> 0.7.5"])
98
- s.add_dependency(%q<bundler>, ["~> 1.1.3"])
99
- s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
100
- s.add_dependency(%q<simplecov>, [">= 0"])
101
- s.add_dependency(%q<log4r>, [">= 1.1.10"])
102
- s.add_dependency(%q<msgpack>, [">= 0.4.6"])
103
- s.add_dependency(%q<eventmachine>, [">= 0.12.10"])
104
- s.add_dependency(%q<girl_friday>, [">= 0.9.7"])
105
- end
25
+ gem.add_runtime_dependency('hashie', ['>= 1.2.0'])
26
+ gem.add_runtime_dependency('ice_nine', ['>= 0.4.0'])
27
+ gem.add_runtime_dependency('uuidtools', ['>= 2.1.3'])
106
28
  end
107
-
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/builder'
4
+
5
+ describe Serf::Builder do
6
+ let(:request_parcel) {
7
+ FactoryGirl.create :random_parcel
8
+ }
9
+ let(:response_kind) {
10
+ 'MyResponseKindMessage'
11
+ }
12
+ let(:app) {
13
+ lambda { |parcel|
14
+ return parcel, response_kind
15
+ }
16
+ }
17
+ subject {
18
+ described_class.new interactor: app
19
+ }
20
+
21
+ describe '#to_app' do
22
+
23
+ it 'builds a callable app' do
24
+ subject.to_app.should respond_to(:call)
25
+ end
26
+
27
+ end
28
+
29
+ context 'with build app' do
30
+
31
+ describe '#call' do
32
+
33
+ it 'runs the app' do
34
+ response = subject.to_app.call request_parcel
35
+ puts response.to_hash
36
+ response.message.should == request_parcel.message
37
+ response.headers.kind.should == response_kind
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/errors/policy_failure'
4
+
5
+ describe Serf::Errors::PolicyFailure do
6
+
7
+ it {
8
+ should be_a_kind_of(RuntimeError)
9
+ }
10
+
11
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/middleware/error_handler'
4
+
5
+ describe Serf::Middleware::ErrorHandler do
6
+
7
+ describe '#call' do
8
+
9
+ context 'has a raised error' do
10
+ subject {
11
+ described_class.new(proc { |parcel|
12
+ raise 'Some Runtime Error'
13
+ })
14
+ }
15
+
16
+ it 'returns an error parcel' do
17
+ parcel = subject.call({})
18
+ JsonSchemaTester.new.validate_for!(
19
+ 'serf/events/caught_error',
20
+ parcel[:message])
21
+ end
22
+
23
+ it 'has an error parcel kind' do
24
+ parcel = subject.call({})
25
+ parcel[:headers][:kind].should == 'serf/events/caught_error'
26
+ end
27
+ end
28
+
29
+ context 'has a succeeding app' do
30
+ subject {
31
+ described_class.new(proc { |parcel|
32
+ response_parcel
33
+ })
34
+ }
35
+ let(:response_parcel) {
36
+ FactoryGirl.create :random_parcel
37
+ }
38
+
39
+ it 'returns a good response parcel' do
40
+ parcel = subject.call({})
41
+ parcel.should == response_parcel
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/middleware/parcel_freezer'
4
+
5
+ describe Serf::Middleware::ParcelFreezer do
6
+
7
+ describe '#call' do
8
+
9
+ it 'freezes the parcel' do
10
+ parcel = {}
11
+ app = described_class.new proc { |parcel|
12
+ parcel.frozen?.should be_true
13
+ }
14
+ app.call parcel
15
+ parcel.frozen?.should be_true
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ require 'hashie'
4
+
5
+ require 'serf/middleware/parcel_masher'
6
+
7
+ describe Serf::Middleware::ParcelMasher do
8
+
9
+ describe '#call' do
10
+
11
+ it 'should Hashie::Mash the parcel' do
12
+ parcel = nil
13
+ app = described_class.new proc { |parcel|
14
+ parcel.should be_a_kind_of(Hashie::Mash)
15
+ }
16
+ app.call parcel
17
+ end
18
+
19
+ it 'should autocreate headers and message' do
20
+ parcel = nil
21
+ app = described_class.new proc { |parcel|
22
+ parcel.headers.should be_a_kind_of(Hashie::Mash)
23
+ parcel.message.should be_a_kind_of(Hashie::Mash)
24
+ }
25
+ app.call parcel
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/errors/policy_failure'
4
+ require 'serf/middleware/policy_checker'
5
+
6
+ describe Serf::Middleware::PolicyChecker do
7
+
8
+ describe '#call' do
9
+
10
+ context 'when policy raises error' do
11
+
12
+ it 'should not call app' do
13
+ uncalled_mock = double 'uncalled mock'
14
+ app = described_class.new(
15
+ uncalled_mock,
16
+ policy_chain: [
17
+ PassingPolicy.new,
18
+ FailingPolicy.new,
19
+ PassingPolicy.new
20
+ ])
21
+ expect {
22
+ app.call nil
23
+ }.to raise_error(Serf::Errors::PolicyFailure)
24
+ end
25
+
26
+ end
27
+
28
+ context 'when all policies pass' do
29
+
30
+ it 'should call the app' do
31
+ parcel = double 'parcel'
32
+ parcel.should_receive :some_success
33
+ app = described_class.new(
34
+ proc { |parcel|
35
+ parcel.some_success
36
+ },
37
+ policy_chain: [
38
+ PassingPolicy.new,
39
+ PassingPolicy.new
40
+ ])
41
+ app.call parcel
42
+ end
43
+
44
+ end
45
+
46
+ it 'should iterate the policy chain' do
47
+ count = 10
48
+ policy_chain = (1..count).map { |i|
49
+ policy = double 'policy'
50
+ policy.should_receive(:check!).once do |parcel|
51
+ parcel.check_called
52
+ end
53
+ policy
54
+ }
55
+
56
+ parcel = double 'parcel'
57
+ parcel.should_receive(:check_called).exactly(count).times
58
+ parcel.should_receive :some_success
59
+
60
+ app = described_class.new(
61
+ proc { |parcel|
62
+ parcel.some_success
63
+ },
64
+ policy_chain: policy_chain)
65
+ app.call parcel
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/middleware/uuid_tagger'
4
+
5
+ describe Serf::Middleware::UuidTagger do
6
+
7
+ describe '#call' do
8
+
9
+ it 'should add uuid the parcel header' do
10
+ parcel = {}
11
+ app = described_class.new proc { |parcel|
12
+ parcel[:headers][:uuid].should_not be_nil
13
+ }
14
+ app.call parcel
15
+ end
16
+
17
+ it 'should not change the existing uuid' do
18
+ uuid = '0d3eccaabcc46c3bcbe2a53c4505e352'
19
+ parcel = {
20
+ headers: {
21
+ uuid: uuid
22
+ }
23
+ }
24
+ app = described_class.new proc { |parcel|
25
+ parcel[:headers][:uuid].should == uuid
26
+ }
27
+ app.call parcel
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ require 'hashie'
4
+
5
+ require 'serf/parcel_builder'
6
+
7
+ describe Serf::ParcelBuilder do
8
+
9
+ describe '#build' do
10
+ let(:random_headers) {
11
+ FactoryGirl.create :random_headers
12
+ }
13
+ let(:random_message) {
14
+ FactoryGirl.create :random_message
15
+ }
16
+
17
+ it 'returns a Hashie' do
18
+ parcel = subject.build
19
+ parcel.should be_a_kind_of(Hashie::Mash)
20
+ end
21
+
22
+ it 'sets default parcel headers' do
23
+ parcel = subject.build
24
+ parcel[:headers].should == {}
25
+ end
26
+
27
+ it 'sets default parcel message' do
28
+ parcel = subject.build
29
+ parcel[:headers].should == {}
30
+ end
31
+
32
+ it 'sets given headers and message' do
33
+ parcel = subject.build random_headers, random_message
34
+ parcel[:headers].should == random_headers
35
+ parcel[:message].should == random_message
36
+ end
37
+
38
+ it 'will coerce headers and message into Hashie::Mash' do
39
+ parcel = subject.build nil, nil
40
+ parcel[:headers].should be_a_kind_of(Hashie::Mash)
41
+ parcel[:message].should be_a_kind_of(Hashie::Mash)
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ require 'serf/serfer'
4
+
5
+ describe Serf::Serfer do
6
+
7
+ describe '#call' do
8
+ let(:request_message) {
9
+ FactoryGirl.create :random_message
10
+ }
11
+ let(:response_message) {
12
+ FactoryGirl.create :random_message
13
+ }
14
+
15
+ it 'calls app with message' do
16
+ mock_app = double 'mock_app'
17
+ mock_app.should_receive(:call).with(request_message)
18
+ serfer = described_class.new mock_app
19
+ serfer.call(
20
+ headers: nil,
21
+ message: request_message)
22
+ end
23
+
24
+ it 'returns a parcel' do
25
+ mock_app = double 'mock_app'
26
+ mock_app.
27
+ should_receive(:call).
28
+ with(request_message).
29
+ and_return(response_message)
30
+ serfer = described_class.new mock_app
31
+ parcel = serfer.call(
32
+ headers: nil,
33
+ message: request_message)
34
+ parcel.message.should == response_message
35
+ end
36
+
37
+ it 'sets the kind header in response' do
38
+ mock_app = double 'mock_app'
39
+ mock_app.
40
+ should_receive(:call).
41
+ with(request_message).
42
+ and_return([response_message, 'KIND'])
43
+ serfer = described_class.new mock_app
44
+ parcel = serfer.call(
45
+ headers: nil,
46
+ message: request_message)
47
+ parcel.headers.kind.should == 'KIND'
48
+ end
49
+
50
+ it 'generate uuids' do
51
+ uuidable = double 'uuidable'
52
+ uuidable.should_receive(:create_uuids).and_return({})
53
+ serfer = described_class.new(
54
+ lambda {|obj| return obj },
55
+ uuidable: uuidable)
56
+ serfer.call({})
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Serf::Util::ErrorHandling do
4
+ subject { ErrorHandlingWrapper.new }
5
+
6
+ context 'has a raised error' do
7
+
8
+ it 'returns an error message' do
9
+ result, error = subject.with_error_handling do
10
+ raise 'Some Error Message'
11
+ end
12
+ result.should be_nil
13
+ JsonSchemaTester.new.validate_for!(
14
+ 'serf/events/caught_error',
15
+ error)
16
+ end
17
+
18
+ end
19
+
20
+ context 'has a succeeding app' do
21
+ let(:response_parcel) {
22
+ FactoryGirl.create :random_parcel
23
+ }
24
+
25
+ it 'returns a good response parcel' do
26
+ result, error = subject.with_error_handling do
27
+ response_parcel
28
+ end
29
+ result.should == response_parcel
30
+ error.should be_nil
31
+ end
32
+
33
+ end
34
+
35
+ end