PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/test/unit/path_test.rb

http://github.com/pluginaweek/state_machine
Ruby | 485 lines | 401 code | 84 blank | 0 comment | 0 complexity | 06d8bcf35fa0017f8d1ad519d5933bcc MD5 | raw file
  1. require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
  2. class PathByDefaultTest < Test::Unit::TestCase
  3. def setup
  4. @klass = Class.new
  5. @machine = StateMachine::Machine.new(@klass)
  6. @object = @klass.new
  7. @path = StateMachine::Path.new(@object, @machine)
  8. end
  9. def test_should_have_an_object
  10. assert_equal @object, @path.object
  11. end
  12. def test_should_have_a_machine
  13. assert_equal @machine, @path.machine
  14. end
  15. def test_should_not_have_walked_anywhere
  16. assert_equal [], @path
  17. end
  18. def test_should_not_have_a_from_name
  19. assert_nil @path.from_name
  20. end
  21. def test_should_have_no_from_states
  22. assert_equal [], @path.from_states
  23. end
  24. def test_should_not_have_a_to_name
  25. assert_nil @path.to_name
  26. end
  27. def test_should_have_no_to_states
  28. assert_equal [], @path.to_states
  29. end
  30. def test_should_have_no_events
  31. assert_equal [], @path.events
  32. end
  33. def test_should_not_be_able_to_walk_anywhere
  34. walked = false
  35. @path.walk { walked = true }
  36. assert_equal false, walked
  37. end
  38. def test_should_not_be_complete
  39. assert_equal false, @path.complete?
  40. end
  41. end
  42. class PathTest < Test::Unit::TestCase
  43. def setup
  44. @klass = Class.new
  45. @machine = StateMachine::Machine.new(@klass)
  46. @object = @klass.new
  47. end
  48. def test_should_raise_exception_if_invalid_option_specified
  49. exception = assert_raise(ArgumentError) {StateMachine::Path.new(@object, @machine, :invalid => true)}
  50. assert_equal 'Invalid key(s): invalid', exception.message
  51. end
  52. end
  53. class PathWithoutTransitionsTest < Test::Unit::TestCase
  54. def setup
  55. @klass = Class.new
  56. @machine = StateMachine::Machine.new(@klass)
  57. @machine.state :parked, :idling
  58. @machine.event :ignite
  59. @object = @klass.new
  60. @path = StateMachine::Path.new(@object, @machine)
  61. @path.concat([
  62. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  63. ])
  64. end
  65. def test_should_not_be_able_to_walk_anywhere
  66. walked = false
  67. @path.walk { walked = true }
  68. assert_equal false, walked
  69. end
  70. end
  71. class PathWithTransitionsTest < Test::Unit::TestCase
  72. def setup
  73. @klass = Class.new
  74. @machine = StateMachine::Machine.new(@klass)
  75. @machine.state :parked, :idling, :first_gear
  76. @machine.event :ignite, :shift_up
  77. @object = @klass.new
  78. @object.state = 'parked'
  79. @path = StateMachine::Path.new(@object, @machine)
  80. @path.concat([
  81. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  82. @shift_up_transition = StateMachine::Transition.new(@object, @machine, :shift_up, :idling, :first_gear)
  83. ])
  84. end
  85. def test_should_enumerate_transitions
  86. assert_equal [@ignite_transition, @shift_up_transition], @path
  87. end
  88. def test_should_have_a_from_name
  89. assert_equal :parked, @path.from_name
  90. end
  91. def test_should_have_from_states
  92. assert_equal [:parked, :idling], @path.from_states
  93. end
  94. def test_should_have_a_to_name
  95. assert_equal :first_gear, @path.to_name
  96. end
  97. def test_should_have_to_states
  98. assert_equal [:idling, :first_gear], @path.to_states
  99. end
  100. def test_should_have_events
  101. assert_equal [:ignite, :shift_up], @path.events
  102. end
  103. def test_should_not_be_able_to_walk_anywhere
  104. walked = false
  105. @path.walk { walked = true }
  106. assert_equal false, walked
  107. end
  108. def test_should_be_complete
  109. assert_equal true, @path.complete?
  110. end
  111. end
  112. class PathWithDuplicatesTest < Test::Unit::TestCase
  113. def setup
  114. @klass = Class.new
  115. @machine = StateMachine::Machine.new(@klass)
  116. @machine.state :parked, :idling
  117. @machine.event :park, :ignite
  118. @object = @klass.new
  119. @object.state = 'parked'
  120. @path = StateMachine::Path.new(@object, @machine)
  121. @path.concat([
  122. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  123. @park_transition = StateMachine::Transition.new(@object, @machine, :park, :idling, :parked),
  124. @ignite_again_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  125. ])
  126. end
  127. def test_should_not_include_duplicates_in_from_states
  128. assert_equal [:parked, :idling], @path.from_states
  129. end
  130. def test_should_not_include_duplicates_in_to_states
  131. assert_equal [:idling, :parked], @path.to_states
  132. end
  133. def test_should_not_include_duplicates_in_events
  134. assert_equal [:ignite, :park], @path.events
  135. end
  136. end
  137. class PathWithAvailableTransitionsTest < Test::Unit::TestCase
  138. def setup
  139. @klass = Class.new
  140. @machine = StateMachine::Machine.new(@klass)
  141. @machine.state :parked, :idling, :first_gear
  142. @machine.event :ignite
  143. @machine.event :shift_up do
  144. transition :idling => :first_gear
  145. end
  146. @machine.event :park do
  147. transition :idling => :parked
  148. end
  149. @object = @klass.new
  150. @object.state = 'parked'
  151. @path = StateMachine::Path.new(@object, @machine)
  152. @path.concat([
  153. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  154. ])
  155. end
  156. def test_should_not_be_complete
  157. assert !@path.complete?
  158. end
  159. def test_should_walk_each_available_transition
  160. paths = []
  161. @path.walk {|path| paths << path}
  162. assert_equal [
  163. [@ignite_transition, StateMachine::Transition.new(@object, @machine, :shift_up, :idling, :first_gear)],
  164. [@ignite_transition, StateMachine::Transition.new(@object, @machine, :park, :idling, :parked)]
  165. ], paths
  166. end
  167. def test_should_yield_path_instances_when_walking
  168. @path.walk do |path|
  169. assert_instance_of StateMachine::Path, path
  170. end
  171. end
  172. def test_should_not_modify_current_path_after_walking
  173. @path.walk {}
  174. assert_equal [@ignite_transition], @path
  175. end
  176. def test_should_not_modify_object_after_walking
  177. @path.walk {}
  178. assert_equal 'parked', @object.state
  179. end
  180. end
  181. class PathWithGuardedTransitionsTest < Test::Unit::TestCase
  182. def setup
  183. @klass = Class.new
  184. @machine = StateMachine::Machine.new(@klass)
  185. @machine.state :parked, :idling
  186. @machine.event :ignite
  187. @machine.event :shift_up do
  188. transition :idling => :first_gear, :if => lambda {false}
  189. end
  190. @object = @klass.new
  191. @object.state = 'parked'
  192. end
  193. def test_should_not_walk_transitions_if_guard_enabled
  194. path = StateMachine::Path.new(@object, @machine)
  195. path.concat([
  196. StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  197. ])
  198. paths = []
  199. path.walk {|next_path| paths << next_path}
  200. assert_equal [], paths
  201. end
  202. def test_should_not_walk_transitions_if_guard_disabled
  203. path = StateMachine::Path.new(@object, @machine, :guard => false)
  204. path.concat([
  205. ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  206. ])
  207. paths = []
  208. path.walk {|next_path| paths << next_path}
  209. assert_equal [
  210. [ignite_transition, StateMachine::Transition.new(@object, @machine, :shift_up, :idling, :first_gear)]
  211. ], paths
  212. end
  213. end
  214. class PathWithEncounteredTransitionsTest < Test::Unit::TestCase
  215. def setup
  216. @klass = Class.new
  217. @machine = StateMachine::Machine.new(@klass)
  218. @machine.state :parked, :idling, :first_gear
  219. @machine.event :ignite do
  220. transition :parked => :idling
  221. end
  222. @machine.event :park do
  223. transition :idling => :parked
  224. end
  225. @object = @klass.new
  226. @object.state = 'parked'
  227. @path = StateMachine::Path.new(@object, @machine)
  228. @path.concat([
  229. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  230. @park_transition = StateMachine::Transition.new(@object, @machine, :park, :idling, :parked)
  231. ])
  232. end
  233. def test_should_be_complete
  234. assert_equal true, @path.complete?
  235. end
  236. def test_should_not_be_able_to_walk
  237. walked = false
  238. @path.walk { walked = true }
  239. assert_equal false, walked
  240. end
  241. end
  242. class PathWithUnreachedTargetTest < Test::Unit::TestCase
  243. def setup
  244. @klass = Class.new
  245. @machine = StateMachine::Machine.new(@klass)
  246. @machine.state :parked, :idling
  247. @machine.event :ignite do
  248. transition :parked => :idling
  249. end
  250. @object = @klass.new
  251. @object.state = 'parked'
  252. @path = StateMachine::Path.new(@object, @machine, :target => :parked)
  253. @path.concat([
  254. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling)
  255. ])
  256. end
  257. def test_should_not_be_complete
  258. assert_equal false, @path.complete?
  259. end
  260. def test_should_not_be_able_to_walk
  261. walked = false
  262. @path.walk { walked = true }
  263. assert_equal false, walked
  264. end
  265. end
  266. class PathWithReachedTargetTest < Test::Unit::TestCase
  267. def setup
  268. @klass = Class.new
  269. @machine = StateMachine::Machine.new(@klass)
  270. @machine.state :parked, :idling
  271. @machine.event :ignite do
  272. transition :parked => :idling
  273. end
  274. @machine.event :park do
  275. transition :idling => :parked
  276. end
  277. @object = @klass.new
  278. @object.state = 'parked'
  279. @path = StateMachine::Path.new(@object, @machine, :target => :parked)
  280. @path.concat([
  281. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  282. @park_transition = StateMachine::Transition.new(@object, @machine, :park, :idling, :parked)
  283. ])
  284. end
  285. def test_should_be_complete
  286. assert_equal true, @path.complete?
  287. end
  288. def test_should_not_be_able_to_walk
  289. walked = false
  290. @path.walk { walked = true }
  291. assert_equal false, walked
  292. end
  293. end
  294. class PathWithAvailableTransitionsAfterReachingTargetTest < Test::Unit::TestCase
  295. def setup
  296. @klass = Class.new
  297. @machine = StateMachine::Machine.new(@klass)
  298. @machine.state :parked, :idling
  299. @machine.event :ignite do
  300. transition :parked => :idling
  301. end
  302. @machine.event :shift_up do
  303. transition :parked => :first_gear
  304. end
  305. @machine.event :park do
  306. transition [:idling, :first_gear] => :parked
  307. end
  308. @object = @klass.new
  309. @object.state = 'parked'
  310. @path = StateMachine::Path.new(@object, @machine, :target => :parked)
  311. @path.concat([
  312. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  313. @park_transition = StateMachine::Transition.new(@object, @machine, :park, :idling, :parked)
  314. ])
  315. end
  316. def test_should_be_complete
  317. assert_equal true, @path.complete?
  318. end
  319. def test_should_be_able_to_walk
  320. paths = []
  321. @path.walk {|path| paths << path}
  322. assert_equal [
  323. [@ignite_transition, @park_transition, StateMachine::Transition.new(@object, @machine, :shift_up, :parked, :first_gear)]
  324. ], paths
  325. end
  326. end
  327. class PathWithDeepTargetTest < Test::Unit::TestCase
  328. def setup
  329. @klass = Class.new
  330. @machine = StateMachine::Machine.new(@klass)
  331. @machine.state :parked, :idling
  332. @machine.event :ignite do
  333. transition :parked => :idling
  334. end
  335. @machine.event :shift_up do
  336. transition :parked => :first_gear
  337. end
  338. @machine.event :park do
  339. transition [:idling, :first_gear] => :parked
  340. end
  341. @object = @klass.new
  342. @object.state = 'parked'
  343. @path = StateMachine::Path.new(@object, @machine, :target => :parked)
  344. @path.concat([
  345. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  346. @park_transition = StateMachine::Transition.new(@object, @machine, :park, :idling, :parked),
  347. @shift_up_transition = StateMachine::Transition.new(@object, @machine, :shift_up, :parked, :first_gear)
  348. ])
  349. end
  350. def test_should_not_be_complete
  351. assert_equal false, @path.complete?
  352. end
  353. def test_should_be_able_to_walk
  354. paths = []
  355. @path.walk {|path| paths << path}
  356. assert_equal [
  357. [@ignite_transition, @park_transition, @shift_up_transition, StateMachine::Transition.new(@object, @machine, :park, :first_gear, :parked)]
  358. ], paths
  359. end
  360. end
  361. class PathWithDeepTargetReachedTest < Test::Unit::TestCase
  362. def setup
  363. @klass = Class.new
  364. @machine = StateMachine::Machine.new(@klass)
  365. @machine.state :parked, :idling
  366. @machine.event :ignite do
  367. transition :parked => :idling
  368. end
  369. @machine.event :shift_up do
  370. transition :parked => :first_gear
  371. end
  372. @machine.event :park do
  373. transition [:idling, :first_gear] => :parked
  374. end
  375. @object = @klass.new
  376. @object.state = 'parked'
  377. @path = StateMachine::Path.new(@object, @machine, :target => :parked)
  378. @path.concat([
  379. @ignite_transition = StateMachine::Transition.new(@object, @machine, :ignite, :parked, :idling),
  380. @park_transition = StateMachine::Transition.new(@object, @machine, :park, :idling, :parked),
  381. @shift_up_transition = StateMachine::Transition.new(@object, @machine, :shift_up, :parked, :first_gear),
  382. @park_transition_2 = StateMachine::Transition.new(@object, @machine, :park, :first_gear, :parked)
  383. ])
  384. end
  385. def test_should_be_complete
  386. assert_equal true, @path.complete?
  387. end
  388. def test_should_not_be_able_to_walk
  389. walked = false
  390. @path.walk { walked = true }
  391. assert_equal false, walked
  392. end
  393. def test_should_not_be_able_to_walk_with_available_transitions
  394. @machine.event :park do
  395. transition :parked => same
  396. end
  397. walked = false
  398. @path.walk { walked = true }
  399. assert_equal false, walked
  400. end
  401. end