Permalink
Browse files

add specs for member

  • Loading branch information...
slyphon committed May 29, 2012
1 parent 08ba54d commit 22f186b34b6fcca4886474819067f6ebcd3faa98
View
@@ -1,4 +1,4 @@
--color
---require ./spec/support/logging_progress_bar_formatter.rb
---format Motionbox::LoggingProgressBarFormatter
+--require ./spec/logging_progress_bar_formatter.rb
+--format LoggingProgressBarFormatter
View
@@ -22,6 +22,14 @@ group :docs do
end
end
+group :development do
+ gem 'guard', :require => false
+ gem 'guard-rspec', :require => false
+ gem 'guard-bundler', :require => false
+
+ gem 'growl' if `uname -s` =~ /darwin/i
+end
+
# Specify your gem's dependencies in zk-group.gemspec
gemspec
View
@@ -0,0 +1,16 @@
+# A sample Guardfile
+# More info at https://github.com/guard/guard#readme
+
+guard 'bundler' do
+ watch('Gemfile')
+ watch(/^.+\.gemspec/)
+end
+
+guard 'rspec', :version => 2 do
+ watch(%r{^spec/.+_spec\.rb$})
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
+ watch(%r%^lib/zk\.rb%) { "spec" }
+
+ watch('spec/spec_helper.rb') { "spec" }
+end
+
View
@@ -79,3 +79,4 @@ def method_missing(m, *a, &b)
require 'zk-group/group'
require 'zk-group/member'
+
View
@@ -1,5 +1,10 @@
module ZK
module Group
+ DEFAULT_ROOT = '/_zk/groups'
+
+ # @private
+ DEFAULT_PREFIX = 'm'.freeze
+
def self.new(*args)
ZK::Group::Group.new(*args)
end
@@ -14,11 +19,6 @@ class Group
def_delegators :@mutex, :synchronize
protected :synchronize
- DEFAULT_ROOT = '/_zk/groups'
-
- # @private
- DEFAULT_PREFIX = 'm'.freeze
-
# the ZK Client instance
attr_reader :zk
@@ -153,9 +153,13 @@ def create!(*args)
# You may receive notification that the member was created before this method
# returns your Member instance. "heads up"
#
+ # @param data [String] (nil) the data this node should have to start
+ # with, default is no data
+ #
# @return [Member] used to control a single member of the group
- def join
- create_member(zk.create("#{path}/#{prefix}", :sequence => true, :ephemeral => true))
+ def join(data=nil)
+ data ||= ''
+ create_member(zk.create("#{path}/#{prefix}", data, :sequence => true, :ephemeral => true))
end
# returns the current list of member names, sorted.
@@ -246,7 +250,7 @@ def broadcast_membership_change!(_ignored=nil)
end
end
- protected
+ private
# Creates a Member instance for this Group. This its own method to allow
# subclasses to override. By default, uses Member
def create_member(znode_path)
View
@@ -19,6 +19,7 @@ def initialize(zk, group, path)
@group = group
@path = path
@name = File.basename(@path)
+ @mutex = Mutex.new
end
# probably poor choice of name, but does this member still an active membership
@@ -33,11 +34,23 @@ def active?
# In the basic implementation, this is not meant to kick another member
# out of the group.
#
- # @abstract Implement 'leaving' behavior in subclasses
def leave
zk.delete(path)
end
- end # MemberBase
+
+ def data
+ @mutex.synchronize do
+ @data ||= zk.get(path).first
+ end
+ end
+
+ def data=(data)
+ @mutex.synchronize do
+ @data = data
+ zk.set(path, data)
+ data
+ end
+ end
+ end # Member
end # Group
end # ZK
-
@@ -0,0 +1,12 @@
+require 'rspec/core/formatters/progress_formatter'
+
+# essentially a monkey-patch to the ProgressBarFormatter, outputs
+# '== #{example_proxy.description} ==' in the logs before each test. makes it
+# easier to match up tests with the SQL they produce
+class LoggingProgressBarFormatter < RSpec::Core::Formatters::ProgressFormatter
+ def example_started(example)
+ ::Logging.logger['spec'].write(yellow("\n=====<([ #{example.full_description} ])>=====\n"))
+ super
+ end
+end
+
@@ -0,0 +1,6 @@
+RSpec::Matchers.define :exist do
+ match do |actual|
+ actual.exists?
+ end
+end
+
@@ -1,14 +0,0 @@
-require 'rspec/core/formatters/progress_formatter'
-
-module Motionbox
- # essentially a monkey-patch to the ProgressBarFormatter, outputs
- # '== #{example_proxy.description} ==' in the logs before each test. makes it
- # easier to match up tests with the SQL they produce
- class LoggingProgressBarFormatter < RSpec::Core::Formatters::ProgressFormatter
- def example_started(example)
- ZK.logger.info(yellow("\n=====<([ #{example.full_description} ])>=====\n"))
- super
- end
- end
-end
-
@@ -0,0 +1,61 @@
+require 'spec_helper'
+
+describe ZK::Group::Member do
+ include_context 'connections'
+
+ let(:group_name) { 'the_mothers' }
+ let(:group) do
+ double(
+ name: group_name,
+ root: @base_path,
+ path: "#{ZK::Group::DEFAULT_ROOT}/#{group_name}"
+ )
+ end
+
+ let(:member_data) { "LA DI *FREAKIN* DA!" }
+
+ let(:member_path) do
+ @zk.mkdir_p group.path
+ @zk.create("#{group.path}/#{ZK::Group::DEFAULT_PREFIX}", member_data, ephemeral: true, sequential: true)
+ end
+
+ subject { described_class.new(@zk, group, member_path) }
+
+ describe :active? do
+ it %[should return true if the path exists] do
+ @zk.stat(member_path).should exist
+ subject.should be_active
+ end
+
+ it %[should return false if the path does not exist] do
+ @zk.delete(member_path)
+ subject.should_not be_active
+ end
+ end
+
+ describe :leave do
+ it %[should delete the underlying path] do
+ subject.leave
+ @zk.stat(member_path).should_not exist
+ end
+
+ it %[should not be active after leave] do
+ subject.leave
+ subject.should_not be_active
+ end
+ end
+
+ describe :data do
+ it %[should return the data in the member's node] do
+ subject.data.should == member_data
+ end
+ end
+
+ describe :data= do
+ it %[should set the data for the member's node] do
+ subject.data = "new data"
+ @zk.get(member_path).first.should == 'new data'
+ end
+ end
+end
+

0 comments on commit 22f186b

Please sign in to comment.