PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/test/functional/state_machine_test.rb

http://github.com/pluginaweek/state_machine
Ruby | 1066 lines | 831 code | 226 blank | 9 comment | 3 complexity | a839e9d0c41ba915379899344dcd5152 MD5 | raw file
  1. require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
  2. class AutoShop
  3. attr_accessor :num_customers
  4. def initialize
  5. @num_customers = 0
  6. super
  7. end
  8. state_machine :initial => :available do
  9. after_transition :available => any, :do => :increment_customers
  10. after_transition :busy => any, :do => :decrement_customers
  11. event :tow_vehicle do
  12. transition :available => :busy
  13. end
  14. event :fix_vehicle do
  15. transition :busy => :available
  16. end
  17. end
  18. # Increments the number of customers in service
  19. def increment_customers
  20. self.num_customers += 1
  21. end
  22. # Decrements the number of customers in service
  23. def decrement_customers
  24. self.num_customers -= 1
  25. end
  26. end
  27. class ModelBase
  28. def save
  29. @saved = true
  30. self
  31. end
  32. end
  33. class Vehicle < ModelBase
  34. attr_accessor :auto_shop, :seatbelt_on, :insurance_premium, :force_idle, :callbacks, :saved, :time_elapsed, :last_transition_args
  35. def initialize(attributes = {})
  36. attributes = {
  37. :auto_shop => AutoShop.new,
  38. :seatbelt_on => false,
  39. :insurance_premium => 50,
  40. :force_idle => false,
  41. :callbacks => [],
  42. :saved => false
  43. }.merge(attributes)
  44. attributes.each {|attr, value| send("#{attr}=", value)}
  45. super()
  46. end
  47. # Defines the state machine for the state of the vehicled
  48. state_machine :initial => lambda {|vehicle| vehicle.force_idle ? :idling : :parked}, :action => :save do
  49. before_transition {|vehicle, transition| vehicle.last_transition_args = transition.args}
  50. before_transition :parked => any, :do => :put_on_seatbelt
  51. before_transition any => :stalled, :do => :increase_insurance_premium
  52. after_transition any => :parked, :do => lambda {|vehicle| vehicle.seatbelt_on = false}
  53. after_transition :on => :crash, :do => :tow
  54. after_transition :on => :repair, :do => :fix
  55. # Callback tracking for initial state callbacks
  56. after_transition any => :parked, :do => lambda {|vehicle| vehicle.callbacks << 'before_enter_parked'}
  57. before_transition any => :idling, :do => lambda {|vehicle| vehicle.callbacks << 'before_enter_idling'}
  58. around_transition do |vehicle, transition, block|
  59. time = Time.now
  60. block.call
  61. vehicle.time_elapsed = Time.now - time
  62. end
  63. event all do
  64. transition :locked => :parked
  65. end
  66. event :park do
  67. transition [:idling, :first_gear] => :parked
  68. end
  69. event :ignite do
  70. transition :stalled => :stalled
  71. transition :parked => :idling
  72. end
  73. event :idle do
  74. transition :first_gear => :idling
  75. end
  76. event :shift_up do
  77. transition :idling => :first_gear, :first_gear => :second_gear, :second_gear => :third_gear
  78. end
  79. event :shift_down do
  80. transition :third_gear => :second_gear
  81. transition :second_gear => :first_gear
  82. end
  83. event :crash do
  84. transition [:first_gear, :second_gear, :third_gear] => :stalled, :if => lambda {|vehicle| vehicle.auto_shop.available?}
  85. end
  86. event :repair do
  87. transition :stalled => :parked, :if => :auto_shop_busy?
  88. end
  89. end
  90. state_machine :insurance_state, :initial => :inactive, :namespace => 'insurance' do
  91. event :buy do
  92. transition :inactive => :active
  93. end
  94. event :cancel do
  95. transition :active => :inactive
  96. end
  97. end
  98. def save
  99. super
  100. end
  101. def new_record?
  102. @saved == false
  103. end
  104. def park
  105. super
  106. end
  107. # Tows the vehicle to the auto shop
  108. def tow
  109. auto_shop.tow_vehicle
  110. end
  111. # Fixes the vehicle; it will no longer be in the auto shop
  112. def fix
  113. auto_shop.fix_vehicle
  114. end
  115. def decibels
  116. 0.0
  117. end
  118. private
  119. # Safety first! Puts on our seatbelt
  120. def put_on_seatbelt
  121. self.seatbelt_on = true
  122. end
  123. # We crashed! Increase the insurance premium on the vehicle
  124. def increase_insurance_premium
  125. self.insurance_premium += 100
  126. end
  127. # Is the auto shop currently servicing another customer?
  128. def auto_shop_busy?
  129. auto_shop.busy?
  130. end
  131. end
  132. class Car < Vehicle
  133. state_machine do
  134. event :reverse do
  135. transition [:parked, :idling, :first_gear] => :backing_up
  136. end
  137. event :park do
  138. transition :backing_up => :parked
  139. end
  140. event :idle do
  141. transition :backing_up => :idling
  142. end
  143. event :shift_up do
  144. transition :backing_up => :first_gear
  145. end
  146. end
  147. end
  148. class Motorcycle < Vehicle
  149. state_machine :initial => :idling do
  150. state :first_gear do
  151. def decibels
  152. 1.0
  153. end
  154. end
  155. end
  156. end
  157. class TrafficLight
  158. state_machine :initial => :stop do
  159. event :cycle do
  160. transition :stop => :proceed, :proceed => :caution, :caution => :stop
  161. end
  162. state :stop do
  163. def color(transform)
  164. value = 'red'
  165. if block_given?
  166. yield value
  167. else
  168. value.send(transform)
  169. end
  170. value
  171. end
  172. end
  173. state all - :proceed do
  174. def capture_violations?
  175. true
  176. end
  177. end
  178. state :proceed do
  179. def color(transform)
  180. 'green'
  181. end
  182. def capture_violations?
  183. false
  184. end
  185. end
  186. state :caution do
  187. def color(transform)
  188. 'yellow'
  189. end
  190. end
  191. end
  192. def color(transform = :to_s)
  193. super
  194. end
  195. end
  196. class VehicleTest < Test::Unit::TestCase
  197. def setup
  198. @vehicle = Vehicle.new
  199. end
  200. def test_should_not_allow_access_to_subclass_events
  201. assert !@vehicle.respond_to?(:reverse)
  202. end
  203. def test_should_have_human_state_names
  204. assert_equal 'parked', Vehicle.human_state_name(:parked)
  205. end
  206. def test_should_have_human_state_event_names
  207. assert_equal 'park', Vehicle.human_state_event_name(:park)
  208. end
  209. end
  210. class VehicleUnsavedTest < Test::Unit::TestCase
  211. def setup
  212. @vehicle = Vehicle.new
  213. end
  214. def test_should_be_in_parked_state
  215. assert_equal 'parked', @vehicle.state
  216. end
  217. def test_should_raise_exception_if_checking_invalid_state
  218. assert_raise(IndexError) { @vehicle.state?(:invalid) }
  219. end
  220. def test_should_raise_exception_if_getting_name_of_invalid_state
  221. @vehicle.state = 'invalid'
  222. assert_raise(ArgumentError) { @vehicle.state_name }
  223. end
  224. def test_should_be_parked
  225. assert @vehicle.parked?
  226. assert @vehicle.state?(:parked)
  227. assert_equal :parked, @vehicle.state_name
  228. assert_equal 'parked', @vehicle.human_state_name
  229. end
  230. def test_should_not_be_idling
  231. assert !@vehicle.idling?
  232. end
  233. def test_should_not_be_first_gear
  234. assert !@vehicle.first_gear?
  235. end
  236. def test_should_not_be_second_gear
  237. assert !@vehicle.second_gear?
  238. end
  239. def test_should_not_be_stalled
  240. assert !@vehicle.stalled?
  241. end
  242. def test_should_not_be_able_to_park
  243. assert !@vehicle.can_park?
  244. end
  245. def test_should_not_have_a_transition_for_park
  246. assert_nil @vehicle.park_transition
  247. end
  248. def test_should_not_allow_park
  249. assert !@vehicle.park
  250. end
  251. def test_should_be_able_to_ignite
  252. assert @vehicle.can_ignite?
  253. end
  254. def test_should_have_a_transition_for_ignite
  255. transition = @vehicle.ignite_transition
  256. assert_not_nil transition
  257. assert_equal 'parked', transition.from
  258. assert_equal 'idling', transition.to
  259. assert_equal :ignite, transition.event
  260. assert_equal :state, transition.attribute
  261. assert_equal @vehicle, transition.object
  262. end
  263. def test_should_have_a_list_of_possible_events
  264. assert_equal [:ignite], @vehicle.state_events
  265. end
  266. def test_should_have_a_list_of_possible_transitions
  267. assert_equal [{:object => @vehicle, :attribute => :state, :event => :ignite, :from => 'parked', :to => 'idling'}], @vehicle.state_transitions.map {|transition| transition.attributes}
  268. end
  269. def test_should_have_a_list_of_possible_paths
  270. assert_equal [[
  271. StateMachine::Transition.new(@vehicle, Vehicle.state_machine, :ignite, :parked, :idling),
  272. StateMachine::Transition.new(@vehicle, Vehicle.state_machine, :shift_up, :idling, :first_gear)
  273. ]], @vehicle.state_paths(:to => :first_gear)
  274. end
  275. def test_should_allow_generic_event_to_fire
  276. assert @vehicle.fire_state_event(:ignite)
  277. assert_equal 'idling', @vehicle.state
  278. end
  279. def test_should_pass_arguments_through_to_generic_event_runner
  280. @vehicle.fire_state_event(:ignite, 1, 2, 3)
  281. assert_equal [1, 2, 3], @vehicle.last_transition_args
  282. end
  283. def test_should_allow_skipping_action_through_generic_event_runner
  284. @vehicle.fire_state_event(:ignite, false)
  285. assert_equal false, @vehicle.saved
  286. end
  287. def test_should_raise_error_with_invalid_event_through_generic_event_runer
  288. assert_raise(IndexError) { @vehicle.fire_state_event(:invalid) }
  289. end
  290. def test_should_allow_ignite
  291. assert @vehicle.ignite
  292. assert_equal 'idling', @vehicle.state
  293. end
  294. def test_should_allow_ignite_with_skipped_action
  295. assert @vehicle.ignite(false)
  296. assert @vehicle.new_record?
  297. end
  298. def test_should_allow_ignite_bang
  299. assert @vehicle.ignite!
  300. end
  301. def test_should_allow_ignite_bang_with_skipped_action
  302. assert @vehicle.ignite!(false)
  303. assert @vehicle.new_record?
  304. end
  305. def test_should_be_saved_after_successful_event
  306. @vehicle.ignite
  307. assert !@vehicle.new_record?
  308. end
  309. def test_should_not_allow_idle
  310. assert !@vehicle.idle
  311. end
  312. def test_should_not_allow_shift_up
  313. assert !@vehicle.shift_up
  314. end
  315. def test_should_not_allow_shift_down
  316. assert !@vehicle.shift_down
  317. end
  318. def test_should_not_allow_crash
  319. assert !@vehicle.crash
  320. end
  321. def test_should_not_allow_repair
  322. assert !@vehicle.repair
  323. end
  324. def test_should_be_insurance_inactive
  325. assert @vehicle.insurance_inactive?
  326. end
  327. def test_should_be_able_to_buy
  328. assert @vehicle.can_buy_insurance?
  329. end
  330. def test_should_allow_buying_insurance
  331. assert @vehicle.buy_insurance
  332. end
  333. def test_should_allow_buying_insurance_bang
  334. assert @vehicle.buy_insurance!
  335. end
  336. def test_should_allow_ignite_buying_insurance_with_skipped_action
  337. assert @vehicle.buy_insurance!(false)
  338. assert @vehicle.new_record?
  339. end
  340. def test_should_not_be_insurance_active
  341. assert !@vehicle.insurance_active?
  342. end
  343. def test_should_not_be_able_to_cancel
  344. assert !@vehicle.can_cancel_insurance?
  345. end
  346. def test_should_not_allow_cancelling_insurance
  347. assert !@vehicle.cancel_insurance
  348. end
  349. end
  350. class VehicleParkedTest < Test::Unit::TestCase
  351. def setup
  352. @vehicle = Vehicle.new
  353. end
  354. def test_should_be_in_parked_state
  355. assert_equal 'parked', @vehicle.state
  356. end
  357. def test_should_not_have_the_seatbelt_on
  358. assert !@vehicle.seatbelt_on
  359. end
  360. def test_should_not_allow_park
  361. assert !@vehicle.park
  362. end
  363. def test_should_allow_ignite
  364. assert @vehicle.ignite
  365. assert_equal 'idling', @vehicle.state
  366. end
  367. def test_should_not_allow_idle
  368. assert !@vehicle.idle
  369. end
  370. def test_should_not_allow_shift_up
  371. assert !@vehicle.shift_up
  372. end
  373. def test_should_not_allow_shift_down
  374. assert !@vehicle.shift_down
  375. end
  376. def test_should_not_allow_crash
  377. assert !@vehicle.crash
  378. end
  379. def test_should_not_allow_repair
  380. assert !@vehicle.repair
  381. end
  382. def test_should_raise_exception_if_repair_not_allowed!
  383. exception = assert_raise(StateMachine::InvalidTransition) {@vehicle.repair!}
  384. assert_equal @vehicle, exception.object
  385. assert_equal Vehicle.state_machine(:state), exception.machine
  386. assert_equal :repair, exception.event
  387. assert_equal 'parked', exception.from
  388. end
  389. end
  390. class VehicleIdlingTest < Test::Unit::TestCase
  391. def setup
  392. @vehicle = Vehicle.new
  393. @vehicle.ignite
  394. end
  395. def test_should_be_in_idling_state
  396. assert_equal 'idling', @vehicle.state
  397. end
  398. def test_should_be_idling
  399. assert @vehicle.idling?
  400. end
  401. def test_should_have_seatbelt_on
  402. assert @vehicle.seatbelt_on
  403. end
  404. def test_should_track_time_elapsed
  405. assert_not_nil @vehicle.time_elapsed
  406. end
  407. def test_should_allow_park
  408. assert @vehicle.park
  409. end
  410. def test_should_call_park_with_bang_action
  411. class << @vehicle
  412. def park
  413. super && 1
  414. end
  415. end
  416. assert_equal 1, @vehicle.park!
  417. end
  418. def test_should_not_allow_idle
  419. assert !@vehicle.idle
  420. end
  421. def test_should_allow_shift_up
  422. assert @vehicle.shift_up
  423. end
  424. def test_should_not_allow_shift_down
  425. assert !@vehicle.shift_down
  426. end
  427. def test_should_not_allow_crash
  428. assert !@vehicle.crash
  429. end
  430. def test_should_not_allow_repair
  431. assert !@vehicle.repair
  432. end
  433. end
  434. class VehicleFirstGearTest < Test::Unit::TestCase
  435. def setup
  436. @vehicle = Vehicle.new
  437. @vehicle.ignite
  438. @vehicle.shift_up
  439. end
  440. def test_should_be_in_first_gear_state
  441. assert_equal 'first_gear', @vehicle.state
  442. end
  443. def test_should_be_first_gear
  444. assert @vehicle.first_gear?
  445. end
  446. def test_should_allow_park
  447. assert @vehicle.park
  448. end
  449. def test_should_allow_idle
  450. assert @vehicle.idle
  451. end
  452. def test_should_allow_shift_up
  453. assert @vehicle.shift_up
  454. end
  455. def test_should_not_allow_shift_down
  456. assert !@vehicle.shift_down
  457. end
  458. def test_should_allow_crash
  459. assert @vehicle.crash
  460. end
  461. def test_should_not_allow_repair
  462. assert !@vehicle.repair
  463. end
  464. end
  465. class VehicleSecondGearTest < Test::Unit::TestCase
  466. def setup
  467. @vehicle = Vehicle.new
  468. @vehicle.ignite
  469. 2.times {@vehicle.shift_up}
  470. end
  471. def test_should_be_in_second_gear_state
  472. assert_equal 'second_gear', @vehicle.state
  473. end
  474. def test_should_be_second_gear
  475. assert @vehicle.second_gear?
  476. end
  477. def test_should_not_allow_park
  478. assert !@vehicle.park
  479. end
  480. def test_should_not_allow_idle
  481. assert !@vehicle.idle
  482. end
  483. def test_should_allow_shift_up
  484. assert @vehicle.shift_up
  485. end
  486. def test_should_allow_shift_down
  487. assert @vehicle.shift_down
  488. end
  489. def test_should_allow_crash
  490. assert @vehicle.crash
  491. end
  492. def test_should_not_allow_repair
  493. assert !@vehicle.repair
  494. end
  495. end
  496. class VehicleThirdGearTest < Test::Unit::TestCase
  497. def setup
  498. @vehicle = Vehicle.new
  499. @vehicle.ignite
  500. 3.times {@vehicle.shift_up}
  501. end
  502. def test_should_be_in_third_gear_state
  503. assert_equal 'third_gear', @vehicle.state
  504. end
  505. def test_should_be_third_gear
  506. assert @vehicle.third_gear?
  507. end
  508. def test_should_not_allow_park
  509. assert !@vehicle.park
  510. end
  511. def test_should_not_allow_idle
  512. assert !@vehicle.idle
  513. end
  514. def test_should_not_allow_shift_up
  515. assert !@vehicle.shift_up
  516. end
  517. def test_should_allow_shift_down
  518. assert @vehicle.shift_down
  519. end
  520. def test_should_allow_crash
  521. assert @vehicle.crash
  522. end
  523. def test_should_not_allow_repair
  524. assert !@vehicle.repair
  525. end
  526. end
  527. class VehicleStalledTest < Test::Unit::TestCase
  528. def setup
  529. @vehicle = Vehicle.new
  530. @vehicle.ignite
  531. @vehicle.shift_up
  532. @vehicle.crash
  533. end
  534. def test_should_be_in_stalled_state
  535. assert_equal 'stalled', @vehicle.state
  536. end
  537. def test_should_be_stalled
  538. assert @vehicle.stalled?
  539. end
  540. def test_should_be_towed
  541. assert @vehicle.auto_shop.busy?
  542. assert_equal 1, @vehicle.auto_shop.num_customers
  543. end
  544. def test_should_have_an_increased_insurance_premium
  545. assert_equal 150, @vehicle.insurance_premium
  546. end
  547. def test_should_not_allow_park
  548. assert !@vehicle.park
  549. end
  550. def test_should_allow_ignite
  551. assert @vehicle.ignite
  552. end
  553. def test_should_not_change_state_when_ignited
  554. assert_equal 'stalled', @vehicle.state
  555. end
  556. def test_should_not_allow_idle
  557. assert !@vehicle.idle
  558. end
  559. def test_should_now_allow_shift_up
  560. assert !@vehicle.shift_up
  561. end
  562. def test_should_not_allow_shift_down
  563. assert !@vehicle.shift_down
  564. end
  565. def test_should_not_allow_crash
  566. assert !@vehicle.crash
  567. end
  568. def test_should_allow_repair_if_auto_shop_is_busy
  569. assert @vehicle.repair
  570. end
  571. def test_should_not_allow_repair_if_auto_shop_is_available
  572. @vehicle.auto_shop.fix_vehicle
  573. assert !@vehicle.repair
  574. end
  575. end
  576. class VehicleRepairedTest < Test::Unit::TestCase
  577. def setup
  578. @vehicle = Vehicle.new
  579. @vehicle.ignite
  580. @vehicle.shift_up
  581. @vehicle.crash
  582. @vehicle.repair
  583. end
  584. def test_should_be_in_parked_state
  585. assert_equal 'parked', @vehicle.state
  586. end
  587. def test_should_not_have_a_busy_auto_shop
  588. assert @vehicle.auto_shop.available?
  589. end
  590. end
  591. class VehicleLockedTest < Test::Unit::TestCase
  592. def setup
  593. @vehicle = Vehicle.new
  594. @vehicle.state = 'locked'
  595. end
  596. def test_should_be_parked_after_park
  597. @vehicle.park
  598. assert @vehicle.parked?
  599. end
  600. def test_should_be_parked_after_ignite
  601. @vehicle.ignite
  602. assert @vehicle.parked?
  603. end
  604. def test_should_be_parked_after_shift_up
  605. @vehicle.shift_up
  606. assert @vehicle.parked?
  607. end
  608. def test_should_be_parked_after_shift_down
  609. @vehicle.shift_down
  610. assert @vehicle.parked?
  611. end
  612. end
  613. class VehicleWithParallelEventsTest < Test::Unit::TestCase
  614. def setup
  615. @vehicle = Vehicle.new
  616. end
  617. def test_should_fail_if_any_event_cannot_transition
  618. assert !@vehicle.fire_events(:ignite, :cancel_insurance)
  619. end
  620. def test_should_be_successful_if_all_events_transition
  621. assert @vehicle.fire_events(:ignite, :buy_insurance)
  622. end
  623. def test_should_not_save_if_skipping_action
  624. assert @vehicle.fire_events(:ignite, :buy_insurance, false)
  625. assert !@vehicle.saved
  626. end
  627. def test_should_raise_exception_if_any_event_cannot_transition_on_bang
  628. exception = assert_raise(StateMachine::InvalidParallelTransition) { @vehicle.fire_events!(:ignite, :cancel_insurance) }
  629. assert_equal @vehicle, exception.object
  630. assert_equal [:ignite, :cancel_insurance], exception.events
  631. end
  632. def test_should_not_raise_exception_if_all_events_transition_on_bang
  633. assert @vehicle.fire_events!(:ignite, :buy_insurance)
  634. end
  635. def test_should_not_save_if_skipping_action_on_bang
  636. assert @vehicle.fire_events!(:ignite, :buy_insurance, false)
  637. assert !@vehicle.saved
  638. end
  639. end
  640. class VehicleWithEventAttributesTest < Test::Unit::TestCase
  641. def setup
  642. @vehicle = Vehicle.new
  643. @vehicle.state_event = 'ignite'
  644. end
  645. def test_should_fail_if_event_is_invalid
  646. @vehicle.state_event = 'invalid'
  647. assert !@vehicle.save
  648. assert_equal 'parked', @vehicle.state
  649. end
  650. def test_should_fail_if_event_has_no_transition
  651. @vehicle.state_event = 'park'
  652. assert !@vehicle.save
  653. assert_equal 'parked', @vehicle.state
  654. end
  655. def test_should_return_original_action_value_on_success
  656. assert_equal @vehicle, @vehicle.save
  657. end
  658. def test_should_transition_state_on_success
  659. @vehicle.save
  660. assert_equal 'idling', @vehicle.state
  661. end
  662. end
  663. class MotorcycleTest < Test::Unit::TestCase
  664. def setup
  665. @motorcycle = Motorcycle.new
  666. end
  667. def test_should_be_in_idling_state
  668. assert_equal 'idling', @motorcycle.state
  669. end
  670. def test_should_allow_park
  671. assert @motorcycle.park
  672. end
  673. def test_should_not_allow_ignite
  674. assert !@motorcycle.ignite
  675. end
  676. def test_should_allow_shift_up
  677. assert @motorcycle.shift_up
  678. end
  679. def test_should_not_allow_shift_down
  680. assert !@motorcycle.shift_down
  681. end
  682. def test_should_not_allow_crash
  683. assert !@motorcycle.crash
  684. end
  685. def test_should_not_allow_repair
  686. assert !@motorcycle.repair
  687. end
  688. def test_should_inherit_decibels_from_superclass
  689. @motorcycle.park
  690. assert_equal 0.0, @motorcycle.decibels
  691. end
  692. def test_should_use_decibels_defined_in_state
  693. @motorcycle.shift_up
  694. assert_equal 1.0, @motorcycle.decibels
  695. end
  696. end
  697. class CarTest < Test::Unit::TestCase
  698. def setup
  699. @car = Car.new
  700. end
  701. def test_should_be_in_parked_state
  702. assert_equal 'parked', @car.state
  703. end
  704. def test_should_not_have_the_seatbelt_on
  705. assert !@car.seatbelt_on
  706. end
  707. def test_should_not_allow_park
  708. assert !@car.park
  709. end
  710. def test_should_allow_ignite
  711. assert @car.ignite
  712. assert_equal 'idling', @car.state
  713. end
  714. def test_should_not_allow_idle
  715. assert !@car.idle
  716. end
  717. def test_should_not_allow_shift_up
  718. assert !@car.shift_up
  719. end
  720. def test_should_not_allow_shift_down
  721. assert !@car.shift_down
  722. end
  723. def test_should_not_allow_crash
  724. assert !@car.crash
  725. end
  726. def test_should_not_allow_repair
  727. assert !@car.repair
  728. end
  729. def test_should_allow_reverse
  730. assert @car.reverse
  731. end
  732. end
  733. class CarBackingUpTest < Test::Unit::TestCase
  734. def setup
  735. @car = Car.new
  736. @car.reverse
  737. end
  738. def test_should_be_in_backing_up_state
  739. assert_equal 'backing_up', @car.state
  740. end
  741. def test_should_allow_park
  742. assert @car.park
  743. end
  744. def test_should_not_allow_ignite
  745. assert !@car.ignite
  746. end
  747. def test_should_allow_idle
  748. assert @car.idle
  749. end
  750. def test_should_allow_shift_up
  751. assert @car.shift_up
  752. end
  753. def test_should_not_allow_shift_down
  754. assert !@car.shift_down
  755. end
  756. def test_should_not_allow_crash
  757. assert !@car.crash
  758. end
  759. def test_should_not_allow_repair
  760. assert !@car.repair
  761. end
  762. def test_should_not_allow_reverse
  763. assert !@car.reverse
  764. end
  765. end
  766. class AutoShopAvailableTest < Test::Unit::TestCase
  767. def setup
  768. @auto_shop = AutoShop.new
  769. end
  770. def test_should_be_in_available_state
  771. assert_equal 'available', @auto_shop.state
  772. end
  773. def test_should_allow_tow_vehicle
  774. assert @auto_shop.tow_vehicle
  775. end
  776. def test_should_not_allow_fix_vehicle
  777. assert !@auto_shop.fix_vehicle
  778. end
  779. end
  780. class AutoShopBusyTest < Test::Unit::TestCase
  781. def setup
  782. @auto_shop = AutoShop.new
  783. @auto_shop.tow_vehicle
  784. end
  785. def test_should_be_in_busy_state
  786. assert_equal 'busy', @auto_shop.state
  787. end
  788. def test_should_have_incremented_number_of_customers
  789. assert_equal 1, @auto_shop.num_customers
  790. end
  791. def test_should_not_allow_tow_vehicle
  792. assert !@auto_shop.tow_vehicle
  793. end
  794. def test_should_allow_fix_vehicle
  795. assert @auto_shop.fix_vehicle
  796. end
  797. end
  798. class TrafficLightStopTest < Test::Unit::TestCase
  799. def setup
  800. @light = TrafficLight.new
  801. @light.state = 'stop'
  802. end
  803. def test_should_use_stop_color
  804. assert_equal 'red', @light.color
  805. end
  806. def test_should_pass_arguments_through
  807. assert_equal 'RED', @light.color(:upcase!)
  808. end
  809. def test_should_pass_block_through
  810. color = @light.color {|value| value.upcase!}
  811. assert_equal 'RED', color
  812. end
  813. def test_should_use_stop_capture_violations
  814. assert_equal true, @light.capture_violations?
  815. end
  816. end
  817. class TrafficLightProceedTest < Test::Unit::TestCase
  818. def setup
  819. @light = TrafficLight.new
  820. @light.state = 'proceed'
  821. end
  822. def test_should_use_proceed_color
  823. assert_equal 'green', @light.color
  824. end
  825. def test_should_use_proceed_capture_violations
  826. assert_equal false, @light.capture_violations?
  827. end
  828. end
  829. class TrafficLightCautionTest < Test::Unit::TestCase
  830. def setup
  831. @light = TrafficLight.new
  832. @light.state = 'caution'
  833. end
  834. def test_should_use_caution_color
  835. assert_equal 'yellow', @light.color
  836. end
  837. def test_should_use_caution_capture_violations
  838. assert_equal true, @light.capture_violations?
  839. end
  840. end