outbox 0.1.0 → 0.1.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: 0b94d8233a2c331495060c6d33e8e94b2d3d0cae
4
+ data.tar.gz: eb43a9e7d7b3ced480238c6b47ac0ca6eb5af721
5
+ SHA512:
6
+ metadata.gz: 14d61db45eff14c42092302401dd1317bfeffb13fa500f3ad86f7d387b3a766049b36dcf69e525e63f3c9f6605c34d8e2d87cfe217bd67f7da40d712cd19b9a1
7
+ data.tar.gz: 5fcf9d9938dbece72b956402b0644a08b7c7bb7dd2ec51d36b16c49d3aa7cc1e1d677b246b18b81fe02b12e7311181adbc42de07110849e2af03b1a3dffb21ce
data/lib/outbox.rb CHANGED
@@ -3,6 +3,7 @@ module Outbox
3
3
  require 'outbox/version'
4
4
 
5
5
  autoload 'Accessor', 'outbox/accessor'
6
+ autoload 'DefineInheritableMethod', 'outbox/define_inheritable_method'
6
7
  autoload 'Message', 'outbox/message'
7
8
  autoload 'MessageClients', 'outbox/message_clients'
8
9
  autoload 'MessageFields', 'outbox/message_fields'
@@ -0,0 +1,25 @@
1
+ module Outbox
2
+ module DefineInheritableMethod
3
+ # Similar to .define_method, but adds a dynamic module in the inheritance
4
+ # change to attach the method to. See:
5
+ #
6
+ # http://thepugautomatic.com/2013/07/dsom/
7
+ def define_inheritable_method(mod_name, *args, &block)
8
+ mod = get_inheritable_module(mod_name)
9
+ mod.module_eval do
10
+ define_method(*args, &block)
11
+ end
12
+ end
13
+
14
+ protected
15
+
16
+ def get_inheritable_module(mod_name)
17
+ if const_defined?(mod_name, _search_ancestors = false)
18
+ mod = const_get(mod_name)
19
+ else
20
+ mod = const_set(mod_name, Module.new)
21
+ include mod
22
+ end
23
+ end
24
+ end
25
+ end
@@ -23,6 +23,15 @@ module Outbox
23
23
  end
24
24
  end
25
25
 
26
+ # Loops through each registered message type and sets the content body.
27
+ def body(value)
28
+ each_message_type do |message_type, message|
29
+ next if message.nil?
30
+ message.body = value
31
+ end
32
+ end
33
+ alias :body= :body
34
+
26
35
  # Delivers all of the messages to the given 'audience'. An 'audience' object
27
36
  # can be a hash or an object that responds to the current message types. Only
28
37
  # the message types specified in the 'audience' object will be sent to.
@@ -35,8 +44,7 @@ module Outbox
35
44
  def deliver(audience)
36
45
  audience = Outbox::Accessor.new(audience)
37
46
 
38
- self.class.message_types.each_key do |message_type|
39
- message = self.public_send(message_type)
47
+ each_message_type do |message_type, message|
40
48
  next if message.nil?
41
49
 
42
50
  recipient = audience[message_type]
@@ -1,10 +1,13 @@
1
1
  module Outbox
2
2
  module MessageFields
3
3
  def self.included(base)
4
+ base.extend Outbox::DefineInheritableMethod
4
5
  base.extend ClassMethods
5
6
  end
6
7
 
7
8
  module ClassMethods
9
+ DYNAMIC_MODULE_NAME = :DynamicFields
10
+
8
11
  # Sets default values for defined fields.
9
12
  #
10
13
  # Email.defaults from: 'bob@example.com'
@@ -123,7 +126,7 @@ module Outbox
123
126
  protected
124
127
 
125
128
  def define_field_reader(name)
126
- define_method(name) do |value = nil|
129
+ define_inheritable_method(DYNAMIC_MODULE_NAME, name) do |value = nil|
127
130
  if value.nil?
128
131
  @fields[name]
129
132
  else
@@ -133,7 +136,7 @@ module Outbox
133
136
  end
134
137
 
135
138
  def define_field_writer(name)
136
- define_method("#{name}=") do |value|
139
+ define_inheritable_method(DYNAMIC_MODULE_NAME, "#{name}=") do |value|
137
140
  @fields[name] = value
138
141
  end
139
142
  end
@@ -1,10 +1,13 @@
1
1
  module Outbox
2
2
  module MessageTypes
3
3
  def self.included(base)
4
+ base.extend Outbox::DefineInheritableMethod
4
5
  base.extend ClassMethods
5
6
  end
6
7
 
7
8
  module ClassMethods
9
+ DYNAMIC_MODULE_NAME = :DynamicMessageTypes
10
+
8
11
  # Registers a message type for sending & creates accessors.
9
12
  #
10
13
  # Message.register_message_type :telepathy, TelepathyMessage
@@ -23,6 +26,7 @@ module Outbox
23
26
  message_types[name.to_sym] = message_type
24
27
  define_message_type_reader(name, message_type)
25
28
  define_message_type_writer(name)
29
+ define_default_message_type_client_accessor(name, message_type)
26
30
  end
27
31
 
28
32
  # Returns a hash of the registred message types, where the key is the name
@@ -35,28 +39,51 @@ module Outbox
35
39
 
36
40
  def define_message_type_reader(name, message_type)
37
41
  ivar_name = "@#{name}"
38
- define_method(name) do |options = nil, &block|
39
- if options || block
40
- instance_variable_set(ivar_name, message_type.new(options, &block))
41
- else
42
- instance_variable_get(ivar_name)
42
+ define_inheritable_method(DYNAMIC_MODULE_NAME, name) do |fields = nil, &block|
43
+ instance = instance_variable_get(ivar_name)
44
+
45
+ if instance.nil? && (fields || block)
46
+ instance = message_type.new
47
+ instance_variable_set(ivar_name, instance)
48
+ end
49
+
50
+ if block
51
+ instance.instance_eval(&block)
52
+ elsif fields
53
+ instance.fields = fields
43
54
  end
55
+
56
+ instance
44
57
  end
45
58
  end
46
59
 
47
60
  def define_message_type_writer(name)
48
- define_method("#{name}=") do |value|
61
+ define_inheritable_method(DYNAMIC_MODULE_NAME, "#{name}=") do |value|
49
62
  instance_variable_set("@#{name}", value)
50
63
  end
51
64
  end
52
- end
53
65
 
54
- protected
66
+ def define_default_message_type_client_accessor(name, message_type)
67
+ define_singleton_method "default_#{name}_client" do |*args|
68
+ message_type.default_client(*args)
69
+ end
70
+ end
71
+ end
55
72
 
73
+ # Assign the given hash where each key is a message type and
74
+ # the value is a hash of options for that message type.
56
75
  def assign_message_type_values(values)
57
76
  values.each do |key, value|
58
77
  self.public_send(key, value) if self.respond_to?(key)
59
78
  end
60
79
  end
80
+
81
+ # Loops through each registered message type and yields the instance
82
+ # of that type on this message.
83
+ def each_message_type
84
+ self.class.message_types.each_key do |message_type|
85
+ yield message_type, self.public_send(message_type)
86
+ end
87
+ end
61
88
  end
62
89
  end
@@ -34,6 +34,12 @@ module Outbox
34
34
  self.to = audience if self.respond_to?(:to=)
35
35
  end
36
36
 
37
+ # Sets the 'body' for this message. All message types must implement
38
+ # this method.
39
+ def body=(body)
40
+ raise NotImplementedError, 'Subclasses must implement a body= method'
41
+ end
42
+
37
43
  # Validates the current message and delivers the message using the
38
44
  # defined client.
39
45
  def deliver(audience = nil)
@@ -39,7 +39,9 @@ module Outbox
39
39
  :resent_message_id, :resent_sender, :resent_to, :return_path,
40
40
  :sender, :to, :comments, :subject, accessor: false
41
41
 
42
- def initialize(fields = nil, &block)
42
+ undef :body=, :[], :[]=
43
+
44
+ def initialize(fields = nil, &block) # :nodoc:
43
45
  @message = ::Mail::Message.new
44
46
  super
45
47
  end
@@ -49,7 +51,7 @@ module Outbox
49
51
  @message
50
52
  end
51
53
 
52
- def audience=(audience)
54
+ def audience=(audience) # :nodoc:
53
55
  case audience
54
56
  when String, Array
55
57
  self.to = audience
@@ -61,6 +63,8 @@ module Outbox
61
63
  end
62
64
  end
63
65
 
66
+ protected
67
+
64
68
  def method_missing(method, *args, &block)
65
69
  if @message.respond_to?(method)
66
70
  @message.public_send(method, *args, &block)
@@ -70,7 +74,7 @@ module Outbox
70
74
  end
71
75
 
72
76
  def respond_to_missing?(method, include_private = false)
73
- @message.respond_to?(method, include_private) || super
77
+ super || @message.respond_to?(method, include_private)
74
78
  end
75
79
  end
76
80
  end
@@ -1,3 +1,3 @@
1
1
  module Outbox
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -1,20 +1,20 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Outbox::Clients::Base do
4
- class Client < Outbox::Clients::Base
4
+ class BaseClient < Outbox::Clients::Base
5
5
  defaults foo: 10
6
6
  end
7
7
 
8
8
  describe '.defaults' do
9
9
  it 'defines default settings' do
10
- client = Client.new
10
+ client = BaseClient.new
11
11
  expect(client.settings[:foo]).to eq(10)
12
12
  end
13
13
  end
14
14
 
15
15
  describe '.new' do
16
16
  it 'initializes settings' do
17
- client = Client.new foo: 1, bar: 2
17
+ client = BaseClient.new foo: 1, bar: 2
18
18
  expect(client.settings[:foo]).to eq(1)
19
19
  expect(client.settings[:bar]).to eq(2)
20
20
  end
@@ -22,7 +22,7 @@ describe Outbox::Clients::Base do
22
22
 
23
23
  describe '#deliver' do
24
24
  it 'raises an error' do
25
- client = Client.new
25
+ client = BaseClient.new
26
26
  expect{client.deliver(Outbox::Messages::Base.new)}.to raise_error(NotImplementedError)
27
27
  end
28
28
  end
@@ -4,11 +4,19 @@ describe Outbox::Message do
4
4
  class Telepathy < Outbox::Messages::Base
5
5
  default_client :test
6
6
  fields :to, :from, :thought
7
+
8
+ def body=(value)
9
+ self.thought = value
10
+ end
7
11
  end
8
12
 
9
13
  class MessageInABottle < Outbox::Messages::Base
10
14
  default_client :test
11
15
  fields :to, :bottle, :message
16
+
17
+ def body=(value)
18
+ self.message = value
19
+ end
12
20
  end
13
21
 
14
22
  before do
@@ -63,6 +71,68 @@ describe Outbox::Message do
63
71
  end
64
72
  end
65
73
 
74
+ describe 'default message type client' do
75
+ after do
76
+ Telepathy.registered_client_aliases.delete(:foo)
77
+ Telepathy.default_client :test
78
+ end
79
+
80
+ it 'sets the default client for that message type' do
81
+ client_class = Class.new
82
+ Telepathy.register_client_alias :foo, client_class
83
+ client = double :client
84
+ options = { option_1: 1, option_2: 2 }
85
+ expect(client_class).to receive(:new).with(options) { client}
86
+ Outbox::Message.default_telepathy_client :foo, options
87
+ expect(Telepathy.default_client).to be(client)
88
+ end
89
+ end
90
+
91
+ describe 'message type reader' do
92
+ context 'when uninitialized' do
93
+ it 'returns nil' do
94
+ expect(Outbox::Message.new.telepathy).to be_nil
95
+ end
96
+
97
+ context 'with a hash' do
98
+ it 'creates a new instance' do
99
+ message = Outbox::Message.new
100
+ message.telepathy thought: 'What?'
101
+ expect(message.telepathy.thought).to eq('What?')
102
+ end
103
+ end
104
+ end
105
+
106
+ context 'when initialized' do
107
+ before do
108
+ @message = Outbox::Message.new do
109
+ telepathy do
110
+ from 'Bob'
111
+ thought 'What?'
112
+ end
113
+ end
114
+ end
115
+
116
+ context 'with a hash' do
117
+ it 'applies the fields values' do
118
+ @message.telepathy thought: 'Hello world.'
119
+ expect(@message.telepathy.from).to eq('Bob')
120
+ expect(@message.telepathy.thought).to eq('Hello world.')
121
+ end
122
+ end
123
+
124
+ context 'with a block' do
125
+ it 'applies the fields values' do
126
+ @message.telepathy do
127
+ thought 'Hello world.'
128
+ end
129
+ expect(@message.telepathy.from).to eq('Bob')
130
+ expect(@message.telepathy.thought).to eq('Hello world.')
131
+ end
132
+ end
133
+ end
134
+ end
135
+
66
136
  describe '#deliver' do
67
137
  before do
68
138
  @message = Outbox::Message.new do
@@ -100,4 +170,18 @@ describe Outbox::Message do
100
170
  end
101
171
  end
102
172
  end
173
+
174
+ describe '#body' do
175
+ it 'assigns the value to all message types' do
176
+ message = Outbox::Message.new do
177
+ email {}
178
+ telepathy {}
179
+ bottle {}
180
+ body 'Simple Message'
181
+ end
182
+ expect(message.email.body.encoded).to eq('Simple Message')
183
+ expect(message.telepathy.thought).to eq('Simple Message')
184
+ expect(message.bottle.message).to eq('Simple Message')
185
+ end
186
+ end
103
187
  end
@@ -19,37 +19,19 @@ describe Outbox::Messages::Base do
19
19
  end
20
20
 
21
21
  class MessageWithoutFieldAccessors < Outbox::Messages::Base
22
- attr_reader :to_reader_called, :to_writer_called,
23
- :from_reader_called, :from_writer_called,
24
- :body_reader_called, :body_writer_called
25
-
26
22
  def to(value = nil)
27
- @to_reader_called = true
28
23
  value ? @to = value : @to
29
24
  end
30
25
 
31
26
  def to=(value)
32
- @to_writer_called = true
33
27
  @to = value
34
28
  end
35
29
 
36
30
  def from(value = nil)
37
- @from_reader_called = true
38
31
  value ? @fields[:from] = value : @fields[:from]
39
32
  end
40
33
 
41
- def from=(value)
42
- @from_writer_called = true
43
- @fields[:from] = value
44
- end
45
-
46
- def body
47
- @body_reader_called = true
48
- @fields[:body]
49
- end
50
-
51
34
  def body=(value)
52
- @body_writer_called = true
53
35
  @fields[:body] = value
54
36
  end
55
37
 
@@ -74,11 +56,11 @@ describe Outbox::Messages::Base do
74
56
  after { Message.default_client :test }
75
57
 
76
58
  it 'registers a client alias' do
77
- Client = Class.new
78
- Message.register_client_alias :foo, Client
59
+ client_class = Class.new
60
+ Message.register_client_alias :foo, client_class
79
61
  client = double :client
80
62
  options = { option_1: 1, option_2: 2 }
81
- expect(Client).to receive(:new).with(options) { client}
63
+ expect(client_class).to receive(:new).with(options) { client}
82
64
  Message.default_client :foo, options
83
65
  expect(Message.default_client).to be(client)
84
66
  end
@@ -101,19 +83,11 @@ describe Outbox::Messages::Base do
101
83
  end
102
84
 
103
85
  it 'does not create accessors if specified' do
104
- message = MessageWithoutFieldAccessors.new
105
- message.to = 'Bob'
106
- message.from = 'John'
107
- message.body = 'Hi'
108
- expect(message.to).to eq('Bob')
109
- expect(message.from).to eq('John')
110
- expect(message.body).to eq('Hi')
111
- expect(message.to_reader_called).to be_true
112
- expect(message.to_writer_called).to be_true
113
- expect(message.from_reader_called).to be_true
114
- expect(message.from_writer_called).to be_false
115
- expect(message.body_reader_called).to be_false
116
- expect(message.body_writer_called).to be_true
86
+ dynamic_methods = MessageWithoutFieldAccessors::DynamicFields.public_instance_methods
87
+ expect(dynamic_methods).not_to include(:to=)
88
+ expect(dynamic_methods).not_to include(:to)
89
+ expect(dynamic_methods).not_to include(:from)
90
+ expect(dynamic_methods).not_to include(:body=)
117
91
  end
118
92
  end
119
93
 
@@ -176,6 +150,14 @@ describe Outbox::Messages::Base do
176
150
  end
177
151
  end
178
152
 
153
+ describe '#body=' do
154
+ it 'raises an error' do
155
+ message_type = Class.new Outbox::Messages::Base
156
+ message = message_type.new
157
+ expect{message.body = 'Something'}.to raise_error(NotImplementedError)
158
+ end
159
+ end
160
+
179
161
  describe '#deliver' do
180
162
  context 'when valid' do
181
163
  it 'delivers the message using a client' do
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: outbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.1.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Pete Browne
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-31 00:00:00.000000000 Z
11
+ date: 2013-08-01 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: mail
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: bundler
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,49 +41,43 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rake
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rspec
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rspec_junit_formatter
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - '>='
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  description: A generic interface for sending email, SMS, & push notifications.
@@ -109,6 +98,7 @@ files:
109
98
  - lib/outbox/clients/base.rb
110
99
  - lib/outbox/clients/mail_client.rb
111
100
  - lib/outbox/clients/test_client.rb
101
+ - lib/outbox/define_inheritable_method.rb
112
102
  - lib/outbox/errors.rb
113
103
  - lib/outbox/message.rb
114
104
  - lib/outbox/message_clients.rb
@@ -130,33 +120,26 @@ files:
130
120
  homepage: https://github.com/localmed/outbox
131
121
  licenses:
132
122
  - MIT
123
+ metadata: {}
133
124
  post_install_message:
134
125
  rdoc_options: []
135
126
  require_paths:
136
127
  - lib
137
128
  required_ruby_version: !ruby/object:Gem::Requirement
138
- none: false
139
129
  requirements:
140
- - - ! '>='
130
+ - - '>='
141
131
  - !ruby/object:Gem::Version
142
132
  version: '0'
143
- segments:
144
- - 0
145
- hash: -1152741713307649410
146
133
  required_rubygems_version: !ruby/object:Gem::Requirement
147
- none: false
148
134
  requirements:
149
- - - ! '>='
135
+ - - '>='
150
136
  - !ruby/object:Gem::Version
151
137
  version: '0'
152
- segments:
153
- - 0
154
- hash: -1152741713307649410
155
138
  requirements: []
156
139
  rubyforge_project:
157
- rubygems_version: 1.8.23
140
+ rubygems_version: 2.0.3
158
141
  signing_key:
159
- specification_version: 3
142
+ specification_version: 4
160
143
  summary: Outbox is a generic interface for sending notifications using a variety of
161
144
  protocols, with built-in support for the most popular SaaS solutions.
162
145
  test_files: