waffle 0.3.5 → 0.4.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.
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --drb
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3-p125@waffle --create
data/Gemfile CHANGED
@@ -1,5 +1,15 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem 'rake'
4
- gem 'mocha'
5
- gem 'waffle', :git => 'git://github.com/peanut/waffle.git'
4
+
5
+ group :development, :test do
6
+ gem 'pry'
7
+ gem 'yajl-ruby', require: 'yajl'
8
+ gem 'bunny'
9
+ gem "hiredis", "~> 0.3.1", :platforms => :ruby
10
+ gem "redis", "~> 2.2.0", require: RUBY_PLATFORM =~ /mingw|mswin/ ? 'redis' : ["redis/connection/hiredis", "redis"]
11
+ end
12
+
13
+ group :test do
14
+ gem 'rspec'
15
+ end
@@ -0,0 +1,36 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ bunny (0.7.9)
5
+ coderay (1.0.6)
6
+ diff-lcs (1.1.3)
7
+ hiredis (0.3.2)
8
+ method_source (0.7.1)
9
+ pry (0.9.9.6)
10
+ coderay (~> 1.0.5)
11
+ method_source (~> 0.7.1)
12
+ slop (>= 2.4.4, < 3)
13
+ rake (0.9.2.2)
14
+ redis (2.2.2)
15
+ rspec (2.10.0)
16
+ rspec-core (~> 2.10.0)
17
+ rspec-expectations (~> 2.10.0)
18
+ rspec-mocks (~> 2.10.0)
19
+ rspec-core (2.10.1)
20
+ rspec-expectations (2.10.0)
21
+ diff-lcs (~> 1.1.3)
22
+ rspec-mocks (2.10.1)
23
+ slop (2.4.4)
24
+ yajl-ruby (1.1.0)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ bunny
31
+ hiredis (~> 0.3.1)
32
+ pry
33
+ rake
34
+ redis (~> 2.2.0)
35
+ rspec
36
+ yajl-ruby
data/README.md CHANGED
@@ -2,13 +2,18 @@
2
2
 
3
3
  An abstract flow publisher and subscriber.
4
4
 
5
- [![Build Status](https://secure.travis-ci.org/peanut/waffle.png?branch=master)](http://travis-ci.org/peanut/waffle)
5
+ [![Build Status](https://secure.travis-ci.org/undr/waffle.png?branch=master)](http://travis-ci.org/undr/waffle)
6
6
 
7
- ## Integration into Rails
7
+ It supports the following transports:
8
8
 
9
- Insert in your Rails Gemfile:
9
+ - RabbitMQ.
10
+ - Redis.
10
11
 
11
- gem 'waffle'
12
+ ## Configuration
13
+
14
+ Insert in your Gemfile:
15
+
16
+ gem 'waffle', :gem => 'git://github.com/undr/waffle.git'
12
17
 
13
18
  and create config file:
14
19
 
@@ -17,8 +22,30 @@ and create config file:
17
22
  encoder: marshal
18
23
  url: amqp://anyhost.com:5678
19
24
 
25
+ and load config file:
26
+
27
+ Waffle.configure(:path => 'config/waffle.yml')
28
+
29
+ You also can configure Waffle programmatically:
30
+
31
+ Waffle.configure({
32
+ :transport => 'redis',
33
+ :url => 'redis://localhost:6379/0',
34
+ :encoder => 'json'
35
+ })
36
+
37
+ or:
38
+
39
+ Waffle.configure do |config|
40
+ config.transport = 'redis'
41
+ config.url = 'redis://localhost:6379/0'
42
+ config.encoder = 'json'
43
+ end
44
+
20
45
  ## Usage
21
46
 
47
+ ### Event
48
+
22
49
  When you want to performan event, just insert this code in place, where it must occur:
23
50
 
24
51
  Waffle::Event.occurred 'index_page_load'
@@ -30,3 +57,16 @@ You can attach meta data to event like this:
30
57
  or like this:
31
58
 
32
59
  Waffle::Event.occurred 'index_page_load', 'bingo!'
60
+
61
+ ### Pub/Sub
62
+
63
+ Waffle.publish('event.name', message_hash_or_string)
64
+
65
+ Waffle.subscribe('event.name') do |message_type, message_hash_or_string|
66
+ pp message_type
67
+ pp message_hash_or_string
68
+ end
69
+
70
+ ### Reconnect
71
+
72
+ Don't care about any reconnects when transport server is down. Waffle just waits for server ready and reconnects automatically.
data/Rakefile CHANGED
@@ -1,8 +1,10 @@
1
- require 'rake/testtask'
1
+ require 'rake'
2
+ $LOAD_PATH.unshift File.expand_path("../..", __FILE__)
3
+ Dir[File.join('lib', 'tasks', '**', '*.rake')].each{|file| load file}
4
+ Bundler::GemHelper.install_tasks
2
5
 
3
- Rake::TestTask.new do |t|
4
- t.libs << 'test'
5
- end
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
6
8
 
7
- desc "Run tests"
8
- task :default => :test
9
+ RSpec::Core::RakeTask.new(:spec)
10
+ task :default => [:spec]
@@ -0,0 +1,8 @@
1
+ production: &base
2
+ transport: rabbitmq
3
+ encoder: json
4
+ url: 'amqp://localhost:5672'
5
+ development:
6
+ <<: *base
7
+ test:
8
+ <<: *base
@@ -1,15 +1,97 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ environment = defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : (ENV['RACK_ENV'] || 'development')
5
+ Bundler.require :default, environment.to_sym
1
6
  require 'waffle/version'
2
- require 'waffle/base'
3
- require 'waffle/config'
4
- require 'waffle/event'
7
+ require 'time'
5
8
 
6
9
  module Waffle
10
+ extend self
7
11
  module Transports
8
- autoload :Rabbitmq, 'waffle/transports/rabbitmq'
12
+ autoload :Base, 'waffle/transports/base'
13
+ autoload :Rabbitmq, 'waffle/transports/rabbitmq' if defined?(Bunny)
14
+ autoload :Redis, 'waffle/transports/redis' if defined?(::Redis)
9
15
  end
10
16
 
17
+ autoload :Config, 'waffle/config'
18
+ autoload :Event, 'waffle/event'
19
+
11
20
  module Encoders
12
- autoload :Json, 'waffle/encoders/json'
21
+ autoload :Json, 'waffle/encoders/json' if defined?(Yajl)
13
22
  autoload :Marshal, 'waffle/encoders/marshal'
14
23
  end
24
+
25
+ def reset_config!
26
+ @configured = false
27
+ end
28
+
29
+ def configure options=nil
30
+ @configured ||= begin
31
+ options = {:path => 'config/waffle.yml'} unless options
32
+ Config.load!(options)
33
+ true
34
+ end
35
+ block_given? ? yield(Config) : Config
36
+ end
37
+
38
+ def publish flow = 'events', message = ''
39
+ transport.publish(flow, message)
40
+ rescue *transport.connection_exceptions => e
41
+ transport.reconnect && retry if transport.ready_to_connect?
42
+ end
43
+
44
+ def subscribe flow = '', &block
45
+ transport.subscribe(flow, &block)
46
+ rescue *transport.connection_exceptions => e
47
+ until transport.reconnect do
48
+ sleep(config.connection_attempt_timeout)
49
+ end
50
+ retry
51
+ end
52
+
53
+ def transport
54
+ @transport ||= "Waffle::Transports::#{Waffle.config.transport.camelize}".constantize.new
55
+ end
56
+
57
+ def encoder
58
+ @encoder ||= "Waffle::Encoders::#{Waffle.config.encoder.camelize}".constantize
59
+ end
60
+
61
+ alias :config :configure
62
+ end
63
+
64
+ unless defined?(ActiveSupport::Inflector)
65
+ class String
66
+ def constantize
67
+ names = self.split('::')
68
+ names.shift if names.empty? || names.first.empty?
69
+
70
+ constant = Object
71
+ names.each do |name|
72
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
73
+ end
74
+ constant
75
+ end
76
+
77
+ def camelize
78
+ string = sub(/^[a-z\d]*/){$&.capitalize}
79
+ string.gsub(/(?:_|(\/))([a-z\d]*)/){ "#{$1}#{$2.capitalize}" }.gsub('/', '::')
80
+ end
81
+ end
82
+ end
83
+
84
+ unless defined?(ActiveSupport)
85
+ class Hash
86
+ def symbolize_keys!
87
+ keys.each do |key|
88
+ self[(key.to_sym rescue key) || key] = delete(key)
89
+ end
90
+ self
91
+ end
92
+
93
+ def symbolize_keys
94
+ dup.symbolize_keys!
95
+ end
96
+ end
15
97
  end
@@ -1,44 +1,57 @@
1
- require 'singleton'
2
1
  require 'yaml'
3
2
 
4
3
  module Waffle
5
- class Config
6
- include Singleton
4
+ module Config
5
+ extend self
6
+ attr_accessor :settings, :defaults
7
7
 
8
- attr_reader :config_hash
8
+ @settings = {}
9
+ @defaults = {}
9
10
 
10
- def initialize
11
- @config_hash = {'transport' => 'rabbitmq', 'url' => nil, 'encoder' => 'json'}
11
+ def option(name, options = {})
12
+ defaults[name] = settings[name] = options[:default]
12
13
 
13
- filename = "config/waffle.yml"
14
-
15
- if defined? Rails
16
- fielname = "#{Rails.root}/config/waffle.yml"
17
- end
14
+ class_eval <<-RUBY
15
+ def #{name}
16
+ settings[#{name.inspect}]
17
+ end
18
18
 
19
- if File.exists?(filename)
20
- loaded_config = YAML.load_file filename
19
+ def #{name}=(value)
20
+ settings[#{name.inspect}] = value
21
+ end
21
22
 
22
- if defined?(Rails) && loaded_config[Rails.env]
23
- @config_hash.merge! loaded_config[Rails.env]
24
- else
25
- @config_hash.merge! loaded_config
23
+ def #{name}?
24
+ #{name}
26
25
  end
27
- end
26
+ RUBY
27
+ end
28
28
 
29
+ option :url, :default => nil
30
+ option :encoder, :default => 'json'
31
+ option :transport, :default => nil
32
+ option :connection_attempt_timeout, :default => 30
33
+
34
+ def load! options=nil
35
+ options[:path] ? load_from_yaml!(options[:path]) : load_from_hash!(options)
36
+ self
29
37
  end
30
38
 
31
- class << self
39
+ def load_from_yaml! filename
40
+ filename = Rails.root.join(filename) if defined?(Rails)
41
+ filename = File.expand_path(filename)
32
42
 
33
- def method_missing(m, *args, &block)
34
- if self.instance.config_hash.has_key?(m.to_s)
35
- self.instance.config_hash[m.to_s]
36
- else
37
- super
38
- end
43
+ if File.exists?(filename)
44
+ settings_hash = YAML.load_file(filename)[environment]
45
+ @settings = defaults.merge(settings_hash.symbolize_keys) if settings_hash
39
46
  end
40
-
41
47
  end
42
48
 
49
+ def load_from_hash! options
50
+ @settings = defaults.merge(options)
51
+ end
52
+
53
+ def environment
54
+ defined?(Rails) && Rails.respond_to?(:env) ? Rails.env : (ENV['RACK_ENV'] || 'development')
55
+ end
43
56
  end
44
57
  end
@@ -2,20 +2,15 @@ require 'yajl'
2
2
 
3
3
  module Waffle
4
4
  module Encoders
5
- class Json
6
-
7
- class << self
8
-
9
- def encode(message = nil)
10
- Yajl::Encoder.encode message
11
- end
12
-
13
- def decode(message = '')
14
- Yajl::Parser.parse message
15
- end
16
-
5
+ module Json
6
+ module_function
7
+ def encode message
8
+ Yajl::Encoder.encode(message)
17
9
  end
18
10
 
11
+ def decode message
12
+ Yajl::Parser.parse(message)
13
+ end
19
14
  end
20
15
  end
21
16
  end
@@ -1,19 +1,14 @@
1
1
  module Waffle
2
2
  module Encoders
3
- class Marshal
4
-
5
- class << self
6
-
7
- def encode(message = nil)
8
- ::Marshal.dump message
9
- end
10
-
11
- def decode(message = '')
12
- ::Marshal.restore message
13
- end
14
-
3
+ module Marshal
4
+ module_function
5
+ def encode message
6
+ ::Marshal.dump(message)
15
7
  end
16
8
 
9
+ def decode message
10
+ ::Marshal.restore(message)
11
+ end
17
12
  end
18
13
  end
19
14
  end
@@ -1,34 +1,16 @@
1
- require 'singleton'
2
-
3
1
  module Waffle
4
2
  class Event
5
- include Singleton
6
-
7
3
  class << self
8
- # Syntactic sugar ^_^
9
- def occured(*args)
10
- self.instance.occured(*args)
11
- end
12
- alias :occurred :occured
13
- end
14
-
15
- def transport
16
- @transport ||= Waffle::Base.new eval("Waffle::Transports::#{Waffle::Config.transport.capitalize}").new
17
- end
4
+ def occured(event_name = 'event', event_data = nil)
5
+ unless event_data.is_a?(Hash)
6
+ event_data = {'body' => event_data.to_s}
7
+ end
18
8
 
19
- def encoder
20
- @encoder ||= eval("Waffle::Encoders::#{Waffle::Config.encoder.capitalize}")
21
- end
9
+ event_data.merge!({'occured_at' => Time.now})
22
10
 
23
- def occured(event_name = 'event', event_data = nil)
24
- unless event_data.is_a? Hash
25
- event_data = {'body' => event_data.to_s}
11
+ Waffle.publish(event_name, event_data)
26
12
  end
27
-
28
- event_data.merge!({'occured_at' => Time.now})
29
-
30
- transport.publish event_name, encoder.encode(event_data)
13
+ alias :occurred :occured
31
14
  end
32
-
33
15
  end
34
16
  end
@@ -0,0 +1,28 @@
1
+ module Waffle
2
+ module Transports
3
+ class Base
4
+ def initialize
5
+ connect!
6
+ end
7
+
8
+ def ready_to_connect?
9
+ (Time.now - @last_connection_attempt) > Waffle.config.connection_attempt_timeout
10
+ end
11
+
12
+ def reconnect
13
+ connect!
14
+ end
15
+
16
+ protected
17
+ def connect!
18
+ @last_connection_attempt = Time.now
19
+ do_connect
20
+ rescue
21
+ false
22
+ end
23
+
24
+ def do_connect
25
+ end
26
+ end
27
+ end
28
+ end
@@ -3,60 +3,44 @@ require 'bunny'
3
3
 
4
4
  module Waffle
5
5
  module Transports
6
- class Rabbitmq
7
-
8
- CONNECTION_ATTEMPT_TIMEOUT = 30
9
-
6
+ class Rabbitmq < Base
10
7
  EXCHANGE = 'events'
11
8
 
12
- @@last_connection_attempt = Time.now
13
-
14
- def initialize
15
- @bunny = Bunny.new Waffle::Config.url
16
- connect
17
- end
18
-
19
- def encoder
20
- @encoder ||= eval("Waffle::Encoders::#{Waffle::Config.encoder.capitalize}")
21
- end
22
-
23
9
  def publish(flow = 'events', message = '')
24
- begin
25
- @exchange = @bunny.exchange EXCHANGE
26
- @exchange.publish message, :key => flow
27
- rescue
28
- if (Time.now - @@last_connection_attempt) > CONNECTION_ATTEMPT_TIMEOUT
29
- connect
30
- end
31
- end
10
+ exchange.publish(Waffle.encoder.encode(message), :key => flow)
32
11
  end
33
12
 
34
13
  def subscribe(flow = 'events')
35
- @exchange = @bunny.exchange EXCHANGE
36
- @queue = @bunny.queue '', :durable => true, :auto_delete => true
37
-
38
- if flow.is_a? Array
39
- flow.each{ |f| @queue.bind @exchange, :key => f }
14
+ if flow.is_a?(Array)
15
+ flow.each{|f| queue.bind(exchange, :key => f)}
40
16
  else
41
- @queue.bind @exchange, :key => flow
17
+ queue.bind(exchange, :key => flow)
42
18
  end
43
19
 
44
- @queue.subscribe do |message|
45
- yield message[:delivery_details][:routing_key], encoder.decode(message[:payload])
20
+ queue.subscribe do |message|
21
+ yield(message[:delivery_details][:routing_key], Waffle.encoder.decode(message[:payload]))
46
22
  end
47
23
  end
48
24
 
25
+ def connection_exceptions
26
+ [Bunny::ServerDownError, Bunny::ConnectionError, Errno::ECONNRESET]
27
+ end
28
+
49
29
  private
30
+ def exchange
31
+ @exchange ||= @bunny.exchange(EXCHANGE)
32
+ end
50
33
 
51
- def connect
52
- begin
53
- @@last_connection_attempt = Time.now
54
- @bunny.start
55
- rescue
56
- nil
57
- end
58
- end
34
+ def queue
35
+ @queue ||= @bunny.queue('', :durable => true, :auto_delete => true)
36
+ end
59
37
 
38
+ def do_connect
39
+ @exchange = nil
40
+ @queue = nil
41
+ @bunny = Bunny.new(Waffle.config.url)
42
+ @bunny.start
43
+ end
60
44
  end
61
45
  end
62
46
  end
@@ -0,0 +1,28 @@
1
+ module Waffle
2
+ module Transports
3
+ class Redis < Base
4
+ attr_reader :db
5
+
6
+ def publish(flow = 'events', message = '')
7
+ db.publish(flow, Waffle.encoder.encode(message))
8
+ end
9
+
10
+ def subscribe(flow = 'events')
11
+ db.subscribe(*flow) do |on|
12
+ on.message do |channel, message|
13
+ yield(channel, Waffle.encoder.decode(message))
14
+ end
15
+ end
16
+ end
17
+
18
+ def connection_exceptions
19
+ [Errno::ECONNREFUSED, Errno::ECONNRESET]
20
+ end
21
+
22
+ protected
23
+ def do_connect
24
+ @db = ::Redis.new(:url => Waffle.config.url)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,3 @@
1
1
  module Waffle
2
-
3
- VERSION = '0.3.5'
4
-
2
+ VERSION = '0.4.0'
5
3
  end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift File.expand_path("../..", __FILE__)
2
+ ENV['RACK_ENV'] = 'test'
3
+
4
+ require "rspec"
5
+ require 'waffle'
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :rspec
9
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Waffle::Encoders::Json do
4
+ let(:message){{"data" => 'message data', "occured_at" => 'DateTime'}}
5
+ describe '.encode' do
6
+ specify{Waffle::Encoders::Json.encode(message).should == '{"data":"message data","occured_at":"DateTime"}'}
7
+ end
8
+
9
+ describe '.decode' do
10
+ specify{Waffle::Encoders::Json.decode('{"data":"message data","occured_at":"DateTime"}').should == message}
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe Waffle::Encoders::Marshal do
4
+ let(:message){{:data => 'message data', :occured_at => 'DateTime'}}
5
+ let(:marshalized_message){Marshal.dump(message)}
6
+ describe '.encode' do
7
+ specify do
8
+ Waffle::Encoders::Marshal.encode(message).should == marshalized_message
9
+ end
10
+ end
11
+
12
+ describe '.decode' do
13
+ specify do
14
+ Waffle::Encoders::Marshal.decode(marshalized_message).should == message
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Waffle::Event do
4
+ describe '.occured' do
5
+ let(:flow){'event'}
6
+ let(:now){Time.now}
7
+
8
+ before do
9
+ Time.stub(:now => now)
10
+ Waffle.should_receive(:publish).with(flow, message)
11
+ end
12
+
13
+ context do
14
+ let(:message){{"key1" => "value1", "key2" => "value2", "occured_at" => now}}
15
+ specify{Waffle::Event.occured(flow, {'key1' => 'value1', 'key2' => 'value2'})}
16
+ end
17
+
18
+ context do
19
+ let(:message){{"body" => "message data", "occured_at" => now}}
20
+ specify{Waffle::Event.occured(flow, 'message data')}
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ class Waffle::Transports::Rabbitmq
4
+ def initialize
5
+ end
6
+ end
7
+
8
+ describe Waffle::Transports::Rabbitmq do
9
+ subject{Waffle::Transports::Rabbitmq.new}
10
+
11
+ let(:exchange){mock(:exchange)}
12
+
13
+ before do
14
+ subject.stub(:exchange => exchange)
15
+ end
16
+
17
+ describe '.publish' do
18
+ before{exchange.should_receive(:publish).with('"message"', :key => 'events')}
19
+ specify{subject.publish('events', 'message')}
20
+ end
21
+
22
+ describe '.subscribe' do
23
+ let(:queue){mock(:queue, :bind => nil)}
24
+
25
+ before do
26
+ subject.stub(:queue => queue)
27
+ queue.should_receive(:subscribe).and_yield({
28
+ :payload => '{"data":"message"}',
29
+ :delivery_details => {:routing_key => 'event'}
30
+ })
31
+ end
32
+
33
+ specify{subject.subscribe('events'){}}
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ class Waffle::Transports::Redis
4
+ def initialize
5
+ end
6
+ end
7
+
8
+ describe Waffle::Transports::Redis do
9
+ subject{Waffle::Transports::Redis.new}
10
+
11
+ let(:redis){mock(:redis)}
12
+ let(:subscription){mock(:subscription)}
13
+
14
+ before do
15
+ subject.stub(:db => redis)
16
+ end
17
+
18
+ describe '.publish' do
19
+ before{redis.should_receive(:publish).with('events', '"message"')}
20
+ specify{subject.publish('events', 'message')}
21
+ end
22
+
23
+ describe '.subscribe' do
24
+ before do
25
+ redis.should_receive(:subscribe).with('events').and_yield(subscription)
26
+ subscription.should_receive(:message).and_yield('event', '{"data":"message"}')
27
+ end
28
+ specify{subject.subscribe('events'){}}
29
+ end
30
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe Waffle do
4
+ describe ".configure" do
5
+ after do
6
+ Waffle.reset_config!
7
+ end
8
+
9
+ context "when no block supplied" do
10
+ let(:config_hash){{
11
+ 'development' => {
12
+ 'transport' => 'redis',
13
+ 'url' => 'redis://localhost:port/0',
14
+ 'encoder' => 'json'
15
+ }
16
+ }}
17
+
18
+ before do
19
+ YAML.stub(:load_file => config_hash)
20
+ File.stub(:exists? => true)
21
+ Waffle::Config.stub(:environment => 'development')
22
+ end
23
+
24
+ specify{Waffle.configure.should == Waffle::Config}
25
+ specify{Waffle.config.should == Waffle::Config}
26
+ specify{Waffle.config.transport.should == 'redis'}
27
+ specify{Waffle.config.encoder.should == 'json'}
28
+ specify{Waffle.config.connection_attempt_timeout.should == 30}
29
+ specify{Waffle.config.url.should == 'redis://localhost:port/0'}
30
+ end
31
+
32
+ context "when a block is supplied" do
33
+ before do
34
+ Waffle.configure do |config|
35
+ config.transport = 'redis'
36
+ end
37
+ end
38
+
39
+ after do
40
+ Waffle.configure do |config|
41
+ config.transport = nil
42
+ end
43
+ end
44
+
45
+ specify{Waffle.config.transport.should == 'redis'}
46
+ end
47
+ end
48
+
49
+ context do
50
+ before do
51
+ Waffle.stub(:transport => transport)
52
+ end
53
+
54
+ let(:transport){mock(:transport)}
55
+
56
+ describe '#publish' do
57
+ let(:args){['flow', 'message']}
58
+
59
+ before do
60
+ transport.should_receive(:publish).with(*args)
61
+ end
62
+
63
+ specify{Waffle.publish(*args)}
64
+ end
65
+
66
+ describe '#subscribe' do
67
+ before do
68
+ transport.should_receive(:subscribe).with('flow').and_yield
69
+ end
70
+
71
+ specify{Waffle.subscribe('flow'){}}
72
+ end
73
+ end
74
+ end
@@ -3,18 +3,17 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
  require "waffle/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.name = 'waffle'
6
+ s.name = 'waffle'
7
7
  s.version = Waffle::VERSION
8
+ s.rubyforge_project = "waffle"
8
9
 
9
- s.homepage = 'http://github.com/peanut/waffle'
10
- s.authors = ['Alexander Lomakin']
11
- s.email = 'alexander.lomakin@gmail.com'
10
+ s.homepage = 'http://github.com/undr/waffle'
11
+ s.authors = ['Alexander Lomakin', 'Andrey Lepeshkin']
12
+ s.email = ['alexander.lomakin@gmail.com', 'lilipoper@gmail.com']
12
13
 
13
- s.summary = 'Abstract flow publisher and subscriber'
14
- s.description = 'Client part of Patty statistics server'
14
+ s.summary = 'Abstract flow publisher and subscriber'
15
+ s.description = 'Abstract flow publisher and subscriber'
15
16
 
16
17
  s.files = `git ls-files`.split("\n")
17
-
18
- s.add_runtime_dependency 'bunny'
19
- s.add_runtime_dependency 'yajl-ruby'
18
+ s.add_dependency("rake")
20
19
  end
metadata CHANGED
@@ -1,19 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waffle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Alexander Lomakin
9
+ - Andrey Lepeshkin
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2012-04-05 00:00:00.000000000Z
13
+ date: 2012-07-06 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
- name: bunny
16
- requirement: &75330640 !ruby/object:Gem::Requirement
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
17
18
  none: false
18
19
  requirements:
19
20
  - - ! '>='
@@ -21,40 +22,46 @@ dependencies:
21
22
  version: '0'
22
23
  type: :runtime
23
24
  prerelease: false
24
- version_requirements: *75330640
25
- - !ruby/object:Gem::Dependency
26
- name: yajl-ruby
27
- requirement: &75330060 !ruby/object:Gem::Requirement
25
+ version_requirements: !ruby/object:Gem::Requirement
28
26
  none: false
29
27
  requirements:
30
28
  - - ! '>='
31
29
  - !ruby/object:Gem::Version
32
30
  version: '0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: *75330060
36
- description: Client part of Patty statistics server
37
- email: alexander.lomakin@gmail.com
31
+ description: Abstract flow publisher and subscriber
32
+ email:
33
+ - alexander.lomakin@gmail.com
34
+ - lilipoper@gmail.com
38
35
  executables: []
39
36
  extensions: []
40
37
  extra_rdoc_files: []
41
38
  files:
39
+ - .rspec
40
+ - .rvmrc
42
41
  - .travis.yml
43
42
  - Gemfile
43
+ - Gemfile.lock
44
44
  - README.md
45
45
  - Rakefile
46
+ - config/waffle.yml
46
47
  - lib/waffle.rb
47
- - lib/waffle/base.rb
48
48
  - lib/waffle/config.rb
49
49
  - lib/waffle/encoders/json.rb
50
50
  - lib/waffle/encoders/marshal.rb
51
51
  - lib/waffle/event.rb
52
+ - lib/waffle/transports/base.rb
52
53
  - lib/waffle/transports/rabbitmq.rb
54
+ - lib/waffle/transports/redis.rb
53
55
  - lib/waffle/version.rb
54
- - test/test_config.rb
55
- - test/test_rabbitmq.rb
56
+ - spec/spec_helper.rb
57
+ - spec/waffle/encoders/json_spec.rb
58
+ - spec/waffle/encoders/marshal_spec.rb
59
+ - spec/waffle/event_spec.rb
60
+ - spec/waffle/transports/rabbitmq_spec.rb
61
+ - spec/waffle/transports/redis_spec.rb
62
+ - spec/waffle_spec.rb
56
63
  - waffle.gemspec
57
- homepage: http://github.com/peanut/waffle
64
+ homepage: http://github.com/undr/waffle
58
65
  licenses: []
59
66
  post_install_message:
60
67
  rdoc_options: []
@@ -66,6 +73,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
66
73
  - - ! '>='
67
74
  - !ruby/object:Gem::Version
68
75
  version: '0'
76
+ segments:
77
+ - 0
78
+ hash: 2130519817389681143
69
79
  required_rubygems_version: !ruby/object:Gem::Requirement
70
80
  none: false
71
81
  requirements:
@@ -73,8 +83,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
83
  - !ruby/object:Gem::Version
74
84
  version: '0'
75
85
  requirements: []
76
- rubyforge_project:
77
- rubygems_version: 1.8.10
86
+ rubyforge_project: waffle
87
+ rubygems_version: 1.8.24
78
88
  signing_key:
79
89
  specification_version: 3
80
90
  summary: Abstract flow publisher and subscriber
@@ -1,17 +0,0 @@
1
- module Waffle
2
- class Base
3
-
4
- def initialize(transport = nil)
5
- @transport = transport
6
- end
7
-
8
- def publish(flow = 'events', message = '')
9
- @transport.publish flow, message
10
- end
11
-
12
- def subscribe(flow = '', &block)
13
- @transport.subscribe flow, &block
14
- end
15
-
16
- end
17
- end
@@ -1,11 +0,0 @@
1
- require 'test/unit'
2
- require 'waffle/config'
3
-
4
- class RabbitmqTest < Test::Unit::TestCase
5
-
6
- def test_config_options_mapping
7
- assert_equal Waffle::Config.transport, 'rabbitmq'
8
- assert_equal Waffle::Config.encoder, 'json'
9
- end
10
-
11
- end
@@ -1,20 +0,0 @@
1
- require 'test/unit'
2
- require 'mocha'
3
- require 'bunny'
4
- require 'waffle/transports/rabbitmq'
5
-
6
- class RabbitmqTest < Test::Unit::TestCase
7
-
8
- def test_publish
9
- Bunny.setup nil
10
- Bunny::Exchange.any_instance.stubs(:publish).returns(nil)
11
- assert_equal nil, Waffle::Transports::Rabbitmq.new.publish('events', 'message')
12
- end
13
-
14
- def test_subscribe
15
- Bunny.setup nil
16
- Bunny::Queue.any_instance.stubs(:subscribe).returns(nil)
17
- assert_equal nil, Waffle::Transports::Rabbitmq.new.subscribe{ |m| puts m }
18
- end
19
-
20
- end