Permalink
Browse files

New Test DSL. Using guard.

  • Loading branch information...
hsume2 committed Sep 21, 2011
1 parent 276707d commit 6a4cb76c73abbb0b7702d3d32413936607e97ad2
Showing with 157 additions and 15 deletions.
  1. +0 −5 .infinity_test
  2. +3 −1 Gemfile
  3. +13 −7 Gemfile.lock
  4. +5 −0 Guardfile
  5. +1 −1 Rakefile
  6. +1 −0 lib/call_center.rb
  7. +69 −0 lib/call_center/test/dsl.rb
  8. +64 −1 test/call_center_test.rb
  9. +1 −0 test/helper.rb
View
@@ -1,5 +0,0 @@
-infinity_test do
- before_run do
- clear :terminal
- end
-end
View
@@ -6,9 +6,11 @@ group :development do
gem 'jeweler', '~> 1.6.4'
gem 'rcov', '>= 0'
gem 'test-unit', :require => 'test/unit'
- gem 'infinity_test'
+ gem 'guard'
+ gem 'guard-test'
gem 'actionpack', '~> 2.3.10'
gem 'mocha'
+ gem 'bourne'
end
gem 'builder'
View
@@ -5,34 +5,40 @@ GEM
activesupport (= 2.3.12)
rack (~> 1.1.0)
activesupport (2.3.12)
+ bourne (1.0)
+ mocha (= 0.9.8)
builder (3.0.0)
git (1.2.5)
+ guard (0.7.0)
+ thor (~> 0.14.6)
+ guard-test (0.3.0)
+ guard (>= 0.2.2)
+ test-unit (~> 2.2)
hsume2-state_machine (1.0.5)
- infinity_test (1.0.3)
- notifiers (>= 1.1.0)
- watchr (>= 0.7)
jeweler (1.6.4)
bundler (~> 1.0)
git (>= 1.2.5)
rake
- mocha (0.9.12)
- notifiers (1.1.0)
+ mocha (0.9.8)
+ rake
rack (1.1.2)
rake (0.9.2)
rcov (0.9.9)
shoulda (2.11.3)
test-unit (2.3.0)
- watchr (0.7)
+ thor (0.14.6)
PLATFORMS
ruby
DEPENDENCIES
actionpack (~> 2.3.10)
+ bourne
builder
bundler (~> 1.0.0)
+ guard
+ guard-test
hsume2-state_machine (~> 1.0.5)
- infinity_test
jeweler (~> 1.6.4)
mocha
rcov
View
@@ -0,0 +1,5 @@
+guard 'test' do
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
+ watch(%r{^test/.+_test\.rb$})
+ watch('test/helper.rb') { "test" }
+end
View
@@ -28,7 +28,7 @@ Jeweler::RubygemsDotOrgTasks.new
require 'rake/testtask'
Rake::TestTask.new(:test) do |test|
test.libs << 'lib' << 'test'
- test.pattern = 'test/**/test_*.rb'
+ test.pattern = 'test/**/*_test.rb'
test.verbose = true
end
View
@@ -74,6 +74,7 @@ def draw_call_flow(*args)
def current_block_accessor(accessor, state_machine_name)
csm = self.class.state_machines[state_machine_name]
+ return unless csm.respond_to?(accessor)
blocks, name = csm.send(accessor), csm.name
blocks[current_flow_state(state_machine_name)] if blocks
end
@@ -0,0 +1,69 @@
+module CallCenter
+ module Test
+ module DSL
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.class_eval do
+ def response_from_page_or_rjs_with_body
+ HTML::Document.new(CGI.unescapeHTML(@body)).root
+ end
+ alias_method_chain :response_from_page_or_rjs, :body
+ end
+ end
+
+ def body(text, debug = false)
+ puts text if debug
+ @body = text
+ end
+
+ module ClassMethods
+ def should_flow(options, &block)
+ event = options.delete(:on)
+ setup_block = options.delete(:when)
+ setup_block_line = setup_block.to_s.match(/.*@(.*):([0-9]+)>/)[2] if setup_block
+ state_field = options.delete(:state) || :state
+ from, to = options.to_a.first
+ description = ":#{from} => :#{to} via #{event}!#{setup_block_line.present? ? " when:#{setup_block_line}" : nil}"
+ context "" do
+ should "transition #{description}" do
+ self.instance_eval(&setup_block) if setup_block
+ @call.send(:"#{state_field}=", from.to_s)
+ @call.send(:"#{event}")
+ assert_equal to, @call.send(:"#{state_field}_name"), "status should be :#{to}, not :#{@call.send(state_field)}"
+ end
+
+ if block.present?
+ context "#{description} and :#{to}" do
+ setup do
+ self.instance_eval(&setup_block) if setup_block
+ @call.send(:"#{state_field}=", from.to_s)
+ @call.send(:"#{event}")
+ body(@call.render) if @call.respond_to?(:render)
+ end
+
+ self.instance_eval(&block)
+ end
+ end
+ end
+ end
+
+ def should_also(&block)
+ line = block.to_s.match(/.*@(.*):([0-9]+)>/)[2]
+ should "also satisfy block on line #{line}" do
+ self.instance_eval(&block)
+ end
+ end
+ alias_method :and_also, :should_also
+
+ def should_render(&block)
+ line = block.to_s.match(/.*@(.*):([0-9]+)>/)[2]
+ should "render selector on line #{line}" do
+ args = [self.instance_eval(&block)].flatten
+ assert_select *args
+ end
+ end
+ alias_method :and_render, :should_render
+ end
+ end
+ end
+end
View
@@ -1,16 +1,22 @@
require 'helper'
+require 'call_center/test/dsl'
+
require 'test/examples/legacy_call'
require 'test/examples/call'
require 'test/examples/non_standard_call'
require 'test/examples/multiple_flow_call'
class CallCenterTest < Test::Unit::TestCase
+ include CallCenter::Test::DSL
+
[:call, :legacy_call].each do |call_type|
context "#{call_type.to_s.gsub('_', ' ')} workflow" do
setup do
klass = call_type.to_s.gsub('_', ' ').titleize.gsub(' ', '').constantize
@call = klass.new
+ @call.stubs(:notify)
+ @call.stubs(:flow_url).returns('the_flow')
end
context "agents available" do
@@ -58,10 +64,31 @@ class CallCenterTest < Test::Unit::TestCase
context "cancelled" do
should "stay in cancelled" do
+ @call.stubs(:cancelled)
@call.state = 'cancelled'
- @call.expects(:cancelled).never
+
@call.customer_hangs_up!
+
assert @call.cancelled?
+ assert_received(@call, :cancelled) { |e| e.never }
+ end
+ end
+
+ context "using test DSL:" do
+ should_flow :on => :incoming_call, :initial => :routing, :when => Proc.new {
+ @call.stubs(:agents_available?).returns(true)
+ }
+
+ should_flow :on => :incoming_call, :initial => :voicemail, :when => Proc.new {
+ @call.stubs(:agents_available?).returns(false)
+ } do
+ should_flow :on => :customer_hangs_up, :voicemail => :voicemail_completed
+ end
+
+ should_flow :on => :something_crazy_happens, :initial => :uh_oh
+
+ should_flow :on => :customer_hangs_up, :cancelled => :cancelled do
+ should_also { assert_received(@call, :cancelled) { |e| e.never } }
end
end
end
@@ -134,6 +161,42 @@ class CallCenterTest < Test::Unit::TestCase
Call.state_machines[:state].expects(:draw).with(:name => 'call_workflow', :font => 'Helvetica Neue')
@call.draw_call_flow(:name => 'call_workflow', :font => 'Helvetica Neue')
end
+
+ context "using test DSL:" do
+ should_flow :on => :incoming_call, :initial => :voicemail, :when => Proc.new {
+ @call.stubs(:agents_available?).returns(false)
+ @call.stubs(:notify)
+ @call.stubs(:flow_url).returns('the_flow')
+ } do
+ should_also { assert_received(@call, :notify) { |e| e.with(:rendering_voicemail) } }
+ and_also { assert_received(@call, :flow_url) { |e| e.with(:voicemail_complete) } }
+ and_render { "Response>Say" }
+ and_render { "Response>Record[action=the_flow]" }
+ end
+
+ should_flow :on => :incoming_call, :initial => :routing, :when => Proc.new {
+ @call.stubs(:agents_available?).returns(true)
+ } do
+ should_render { "Response" }
+ end
+
+ should_flow :on => :customer_hangs_up, :routing => :cancelled, :when => Proc.new {
+ @call.stubs(:notify)
+ } do
+ should_also { assert_received(@call, :notify) { |e| e.with(:cancelled).once } }
+ and_also { assert @call.cancelled? }
+
+ should_flow :on => :customer_hangs_up, :cancelled => :cancelled do
+ should_also { assert_received(@call, :notify) { |e| e.with(:cancelled).once } } # For above
+ and_also { assert @call.cancelled? }
+
+ should_flow :on => :customer_hangs_up, :cancelled => :cancelled do
+ should_also { assert_received(@call, :notify) { |e| e.with(:cancelled).once } } # For above
+ and_also { assert @call.cancelled? }
+ end
+ end
+ end
+ end
end
context "non-standard call" do
View
@@ -10,6 +10,7 @@
require 'test/unit'
require 'shoulda'
require 'mocha'
+require 'bourne'
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
$LOAD_PATH.unshift(File.dirname(__FILE__))

0 comments on commit 6a4cb76

Please sign in to comment.