Class: Arrow::AppletTestCase
- Inherits:
-
Test::Unit::TestCase
- Object
- Test::Unit::TestCase
- Arrow::AppletTestCase
- Includes:
- Loggable, FlexMock::TestCase, Test::Unit::Assertions
- Defined in:
- lib/arrow/applettestcase.rb
Overview
This is an abstract test case class for building Test::Unit unit tests for Arrow applets.
Synopsis
$LOAD_PATH.unshift “tests/lib” unless $LOAD_PATH.include?(“tests/lib”) require ‘applettestcase’
class MySomethingTest < Arrow::AppletTestCase
applet_under_test “jobs”
def test_default_request_should_return_object_list end
def test_default_request_with_oid_arg_should_display_details set_request_params :oid => 13 end
end
VCS Id
$Id$
Authors
-
Michael Granger <[email protected]>
Copyright © 2003, 2004, 2006 RubyCrafters, LLC.
This work is licensed under the Creative Commons Attribution License. To view a copy of this license, visit creativecommons.org/licenses/by/1.0 or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
Constant Summary collapse
- APPLET_PATH =
The default path to the directory where applets live
Pathname.new( $0 )..dirname + "applets"
- AnsiAttributes =
Set some ANSI escape code constants (Shamelessly stolen from Perl’s Term::ANSIColor by Russ Allbery <[email protected]> and Zenin <[email protected]>
{ 'clear' => 0, 'reset' => 0, 'bold' => 1, 'dark' => 2, 'underline' => 4, 'underscore' => 4, 'blink' => 5, 'reverse' => 7, 'concealed' => 8, 'black' => 30, 'on_black' => 40, 'red' => 31, 'on_red' => 41, 'green' => 32, 'on_green' => 42, 'yellow' => 33, 'on_yellow' => 43, 'blue' => 34, 'on_blue' => 44, 'magenta' => 35, 'on_magenta' => 45, 'cyan' => 36, 'on_cyan' => 46, 'white' => 37, 'on_white' => 47 }
Class Attribute Summary collapse
-
.appletclass ⇒ Object
Returns the value of attribute appletclass.
-
.appletname ⇒ Object
Returns the value of attribute appletname.
-
.fixture_data ⇒ Object
Returns the value of attribute fixture_data.
Class Method Summary collapse
-
.ansicode(*attributes) ⇒ Object
Returns a String containing the specified ANSI escapes suitable for inclusion in another string.
-
.applet_under_test(applet) ⇒ Object
Define the name of the applet under test.
-
.debug_msg(*msgs) ⇒ Object
Output the specified
msgs
joined together toSTDERR
if$DEBUG
is set. -
.message(*msgs) ⇒ Object
Output the specified
msgs
joined together toSTDOUT
. -
.set_fixture_data(model_class, data) ⇒ Object
Set up model
data
for the givenmodel_class
that can be used in the stub data classes.
Instance Method Summary collapse
-
#ansicode(*attributes) ⇒ Object
Instance-alias for the like-named class method.
-
#create_mock(name) ⇒ Object
Create a new mock object and register it to be verified at the end of the test.
-
#debug_msg(*msgs) ⇒ Object
Instance alias for the like-named class method.
-
#default_delegation_behavior ⇒ Object
The default block passed to Arrow::Applet#delegate by #with_fixtured_delegation if no block is passed to either #should_delegate or #should_not_delegate.
-
#extract_parameters(queryhash, key = nil) ⇒ Object
Extract parameters for the given
key
from the givenqueryhash
using the form validator for the current action and return it. -
#fixture_session(txn) ⇒ Object
Set up a mock object as the given transaction’s session.
-
#hrule(length = 75, char = "-") ⇒ Object
Return a separator line made up of
length
of the specifiedchar
. -
#hrule_section(content, caption = '') ⇒ Object
Return a section delimited by hrules with the specified
caption
andcontent
. -
#initialize(*args) ⇒ AppletTestCase
constructor
Check to be sure an applet has been associated before instantiation.
-
#message(*msgs) ⇒ Object
Instance alias for the like-named class method.
-
#print_test_header(desc) ⇒ Object
Output a header for delimiting tests.
-
#run(result) ⇒ Object
Output the name of the test as it’s running if in verbose mode, and support per-test debugging settings.
-
#setup ⇒ Object
Set up a test with some useful test objects.
-
#setup_fixtured_request(action, *args) ⇒ Object
Set up faked request and transaction objects for the given
action
, using the givenargs
as REST-style arguments, and/or query arguments if the last element is a Hash. -
#should_delegate(&block) ⇒ Object
The default delegate block – call this from within your #with_fixtured_delegation block if the applet under test should delegate to the next applet in the chain.
-
#should_load_template(key) {|mock_template| ... } ⇒ Object
Assert that the current action should load the template associated with the given
key
, and passes a mock template object to the given block for further specification. -
#should_not_delegate(&block) ⇒ Object
Negated delegate block – call this at the end of your #with_fixtured_delegation block if the applet under test should not delegate to the next applet in the chain.
-
#with_fixtured_action(action = nil, *args, &block) ⇒ Object
Set up faked request and transaction objects, yield to the given block with them, then run the applet under test with them when the block returns.
-
#with_fixtured_delegation(chain = [], *args, &block) ⇒ Object
Set up a faked request and transaction object, yield to the given block with them, and then call the #delegate method of the applet under test.
Constructor Details
#initialize(*args) ⇒ AppletTestCase
Check to be sure an applet has been associated before instantiation.
239 240 241 242 |
# File 'lib/arrow/applettestcase.rb', line 239 def initialize( *args ) # :notnew: throw :invalid_test unless self.class.appletclass super end |
Class Attribute Details
.appletclass ⇒ Object
Returns the value of attribute appletclass.
96 97 98 |
# File 'lib/arrow/applettestcase.rb', line 96 def appletclass @appletclass end |
.appletname ⇒ Object
Returns the value of attribute appletname.
96 97 98 |
# File 'lib/arrow/applettestcase.rb', line 96 def appletname @appletname end |
.fixture_data ⇒ Object
Returns the value of attribute fixture_data.
96 97 98 |
# File 'lib/arrow/applettestcase.rb', line 96 def fixture_data @fixture_data end |
Class Method Details
.ansicode(*attributes) ⇒ Object
Returns a String containing the specified ANSI escapes suitable for inclusion in another string. The attributes
should be one or more of the keys of AnsiAttributes.
127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/arrow/applettestcase.rb', line 127 def self::ansicode( *attributes ) return '' unless /(?:xterm(?:-color)?|eterm|linux)/i =~ ENV['TERM'] attr = attributes.collect {|a| AnsiAttributes[a] ? AnsiAttributes[a] : nil }.compact.join(';') if attr.empty? return '' else return "\e[%sm" % attr end end |
.applet_under_test(applet) ⇒ Object
Define the name of the applet under test. The given name
will be stringified, downcased, and searched for in the #applet_path.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/arrow/applettestcase.rb', line 201 def self::applet_under_test( applet ) if applet.is_a?( Class ) self.appletclass = applet self.appletname = applet.signature.name else debug_msg "Setting applet under test for testcase: %p" % [self] if Arrow::Applet.derivatives.empty? Pathname.glob( APPLET_PATH + '**/*.rb' ).each do |appletfile| debug_msg "Trying to load #{appletfile}" begin Arrow::Applet.load( appletfile ) rescue LoadError end end end # :view_template becomes /view[-_]template/ applet_pat = Regexp.new( applet.to_s.gsub(/_/, '[-_]?') ) self.appletclass = Arrow::Applet.derivatives.find {|klass| debug_msg " Checking applet '#{klass.name.downcase}' =~ #{applet_pat}..." applet_pat.match( klass.name.downcase ) or applet_pat.match( klass.filename ) } or raise "Failed to load applet matching #{applet_pat}" self.appletname = applet.to_s debug_msg "Applet under test is: #{self.appletclass}" end end |
.debug_msg(*msgs) ⇒ Object
Output the specified msgs
joined together to STDERR
if $DEBUG
is set.
143 144 145 146 147 |
# File 'lib/arrow/applettestcase.rb', line 143 def self::debug_msg( *msgs ) return unless $DEBUG self. "%sDEBUG>>> %s %s" % [ ansicode('dark', 'white'), msgs.join(''), ansicode('reset') ] end |
.message(*msgs) ⇒ Object
Output the specified msgs
joined together to STDOUT
.
152 153 154 155 |
# File 'lib/arrow/applettestcase.rb', line 152 def self::( *msgs ) $stderr.puts msgs.join('') $stderr.flush end |
.set_fixture_data(model_class, data) ⇒ Object
Set up model data
for the given model_class
that can be used in the stub data classes. The data
argument is an Array of data, and can be either Hashes or Arrays. If Arrays are used, the first one in the list should be a list of fields, and each subsequent Array should be field values. E.g.,
[
[ :title, :description, :date ],
[ "title1", "desc1", Date.today ],
[ "title2", "desc2", Date.today-4 ],
]
which is equivalent to:
[
{ :title => "title1", :description => "desc1", :date => Date.today }
{ :title => "title1", :description => "desc1", :date => Date.today }
]
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/arrow/applettestcase.rb', line 173 def self::set_fixture_data( model_class, data ) @fixture_data ||= {} # [ [<fields>], [<values1], [<values2>] ] if data.first.is_a?( Array ) fields = data.shift objects = data.collect do |row| obj = OpenStruct.new fields.each_with_index {|f,i| obj.__send__(f, row[i])} end # [ {:field1 => <value1>}, {:field1 => <value2>} ] elsif data.first.is_a?( Hash ) objects = data.collect do |row| OpenStruct.new( row ) end # Custom objects (Mocks, etc.) elsif data.is_a?( Array ) objects = data end @fixture_data[ model_class ] = objects end |
Instance Method Details
#ansicode(*attributes) ⇒ Object
Instance-alias for the like-named class method
298 299 300 |
# File 'lib/arrow/applettestcase.rb', line 298 def ansicode( *attributes ) self.class.ansicode( *attributes ) end |
#create_mock(name) ⇒ Object
Create a new mock object and register it to be verified at the end of the test.
469 470 471 |
# File 'lib/arrow/applettestcase.rb', line 469 def create_mock( name ) return flexmock( name ) end |
#debug_msg(*msgs) ⇒ Object
Instance alias for the like-named class method
304 305 306 |
# File 'lib/arrow/applettestcase.rb', line 304 def debug_msg( *msgs ) self.class.debug_msg( *msgs ) end |
#default_delegation_behavior ⇒ Object
The default block passed to Arrow::Applet#delegate by #with_fixtured_delegation if no block is passed to either #should_delegate or #should_not_delegate. If you override this, you should either super to this method or set @delegate_called yourself.
412 413 414 |
# File 'lib/arrow/applettestcase.rb', line 412 def default_delegation_behavior @delegate_called = true end |
#extract_parameters(queryhash, key = nil) ⇒ Object
Extract parameters for the given key
from the given queryhash
using the form validator for the current action and return it.
488 489 490 491 492 493 494 495 496 497 498 499 500 |
# File 'lib/arrow/applettestcase.rb', line 488 def extract_parameters( queryhash, key=nil ) profile = @applet.signature.validator_profiles[ @action ] || @applet.signature_profiles[ :__default__ ] validator = Arrow::FormValidator.new( profile ) validator.validate( queryhash ) if key return validator.valid[ key ] else return validator.valid end end |
#fixture_session(txn) ⇒ Object
Set up a mock object as the given transaction’s session.
475 476 477 478 479 480 481 482 483 |
# File 'lib/arrow/applettestcase.rb', line 475 def fixture_session( txn ) session = create_mock( "session" ) txn.should_receive( :session ). and_return( session ).zero_or_more_times session.should_receive( :[] ).and_return( nil ).zero_or_more_times session.should_receive( :[]= ).and_return( nil ).zero_or_more_times return session end |
#hrule(length = 75, char = "-") ⇒ Object
Return a separator line made up of length
of the specified char
.
311 312 313 |
# File 'lib/arrow/applettestcase.rb', line 311 def hrule( length=75, char="-" ) return (char * length ) + "\n" end |
#hrule_section(content, caption = '') ⇒ Object
Return a section delimited by hrules with the specified caption
and content
.
317 318 319 320 321 322 323 |
# File 'lib/arrow/applettestcase.rb', line 317 def hrule_section( content, ='' ) << ' ' unless .empty? return + hrule( 75 - .length ) + content.chomp + "\n" + hrule() end |
#message(*msgs) ⇒ Object
Instance alias for the like-named class method.
292 293 294 |
# File 'lib/arrow/applettestcase.rb', line 292 def ( *msgs ) self.class.( *msgs ) end |
#print_test_header(desc) ⇒ Object
Output a header for delimiting tests
327 328 329 330 331 |
# File 'lib/arrow/applettestcase.rb', line 327 def print_test_header( desc ) return unless $VERBOSE || $DEBUG "%s>>> %s <<<%s" % [ ansicode('bold','yellow','on_blue'), desc, ansicode('reset') ] end |
#run(result) ⇒ Object
Output the name of the test as it’s running if in verbose mode, and support per-test debugging settings.
280 281 282 283 |
# File 'lib/arrow/applettestcase.rb', line 280 def run( result ) print_test_header self.name super end |
#setup ⇒ Object
Set up a test with some useful test objects
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'lib/arrow/applettestcase.rb', line 246 def setup super debug_msg "%p: Setting up test for applet %p" % [self.class, self.class.appletclass] # Give the test an easy reference to the applet class under test @appletclass = self.class.appletclass or raise "No applet defined for '#{self.class.name}'. Add " + "'applet_under_test :<appletname>' to correct this." @appletname = self.class.appletname @action = nil @config = flexmock( "mock config" ) @config.should_receive( :symbolize_keys ).and_return({}) @config.should_receive( :member? ). with( :db ). and_return( false ) @config.should_receive( :name ).and_return( "mock" ) @config.should_receive( :member? ). with( :model ). and_return( false ) @config.should_ignore_missing @template_factory = flexmock( "mock template factory" ) @applet = @appletclass.new( @config, @template_factory, "#{@appletname}" ) @delegate_behavior = nil @delegate_should_be_called = true @delegate_called = false end |
#setup_fixtured_request(action, *args) ⇒ Object
Set up faked request and transaction objects for the given action
, using the given args
as REST-style arguments, and/or query arguments if the last element is a Hash.
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
# File 'lib/arrow/applettestcase.rb', line 420 def setup_fixtured_request( action, *args ) uri = '/' + File.join( @appletname, action.to_s ) req = Apache::Request.new( uri ) params = args.last.is_a?( Hash ) ? args.pop : {} debug_msg "Parameters hash set to: %p" % [params] req.paramtable = params debug_msg "Request is: %p" % [req] #txn = Arrow::Transaction.new( req, @config, nil ) txn = flexmock( "transaction" ) txn.should_receive( :request ). and_return( req ).zero_or_more_times txn.should_receive( :vargs= ). with( Arrow::FormValidator ).zero_or_more_times vargs = flexmock( "form validator" ) txn.should_receive( :vargs ). and_return( vargs ). zero_or_more_times vargs.should_receive( :[] ).zero_or_more_times debug_msg "Transaction is: %p" % [txn] return txn, req, vargs, *args end |
#should_delegate(&block) ⇒ Object
The default delegate block – call this from within your #with_fixtured_delegation block if the applet under test should delegate to the next applet in the chain.
391 392 393 394 395 |
# File 'lib/arrow/applettestcase.rb', line 391 def should_delegate( &block ) @delegate_should_be_called = true @delegate_behavior = block || method( :default_delegation_behavior ).to_proc end |
#should_load_template(key) {|mock_template| ... } ⇒ Object
Assert that the current action should load the template associated with the given key
, and passes a mock template object to the given block for further specification.
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
# File 'lib/arrow/applettestcase.rb', line 450 def should_load_template( key ) tname = @applet.signature.templates[ key ] or raise Test::Unit::AssertionFailedError.new( "Expected applet to load the '#{key.inspect}' template\n" + "but there was no such template registered by the application." ) mock_template = flexmock( "#{key.inspect} template") @template_factory.should_receive( :get_template ). with( tname ).and_return( mock_template ).at_least.once mock_template.should_ignore_missing yield( mock_template ) if block_given? return mock_template end |
#should_not_delegate(&block) ⇒ Object
Negated delegate block – call this at the end of your #with_fixtured_delegation block if the applet under test should not delegate to the next applet in the chain.
401 402 403 404 405 |
# File 'lib/arrow/applettestcase.rb', line 401 def should_not_delegate( &block ) @delegate_should_be_called = false @delegate_behavior = block || method( :default_delegation_behavior ).to_proc end |
#with_fixtured_action(action = nil, *args, &block) ⇒ Object
Set up faked request and transaction objects, yield to the given block with them, then run the applet under test with them when the block returns.
341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/arrow/applettestcase.rb', line 341 def with_fixtured_action( action=nil, *args, &block ) @action = action txn, req, vargs, *args = setup_fixtured_request( action, *args ) if block.arity == 3 block.call( txn, req, vargs ) else block.call( txn, req ) end return @applet.run( txn, action.to_s, *args ) ensure @action = nil end |
#with_fixtured_delegation(chain = [], *args, &block) ⇒ Object
Set up a faked request and transaction object, yield to the given block with them, and then call the #delegate method of the applet under test. Unless otherwise indicated (via a call to #should_not_delegate), the expectation will be set up that the applet under test should call its delegate.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
# File 'lib/arrow/applettestcase.rb', line 362 def with_fixtured_delegation( chain=[], *args, &block ) txn, req, vargs, *args = setup_fixtured_request( "delegated_action", *args ) # Set delegation expectation @delegate_behavior ||= should_delegate() if block.arity == 3 block.call( txn, req, vargs ) else block.call( txn, req ) end rval = @applet.delegate( txn, chain, *args, &@delegate_behavior ) if @delegate_should_be_called assert @delegate_called, "delegate applet was never called" else assert !@delegate_called, "delegate applet was called unexpectedly" end return rval end |