rkoans 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (460) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/CURRICULUM.md +86 -0
  4. data/README.md +77 -0
  5. data/THIRD_PARTY_NOTICES.md +30 -0
  6. data/exercises/about-array-assignment/about_array_assignment.rb +45 -0
  7. data/exercises/about-array-assignment/brief.md +11 -0
  8. data/exercises/about-array-assignment/hint.md +11 -0
  9. data/exercises/about-arrays/about_arrays.rb +77 -0
  10. data/exercises/about-arrays/brief.md +16 -0
  11. data/exercises/about-arrays/hint.md +13 -0
  12. data/exercises/about-asserts/about_asserts.rb +22 -0
  13. data/exercises/about-asserts/brief.md +22 -0
  14. data/exercises/about-asserts/hint.md +10 -0
  15. data/exercises/about-blocks/about_blocks.rb +76 -0
  16. data/exercises/about-blocks/brief.md +44 -0
  17. data/exercises/about-blocks/hint.md +7 -0
  18. data/exercises/about-class-methods/about_class_methods.rb +105 -0
  19. data/exercises/about-class-methods/brief.md +73 -0
  20. data/exercises/about-class-methods/hint.md +8 -0
  21. data/exercises/about-classes/about_classes.rb +131 -0
  22. data/exercises/about-classes/brief.md +73 -0
  23. data/exercises/about-classes/hint.md +7 -0
  24. data/exercises/about-constants/about_constants.rb +49 -0
  25. data/exercises/about-constants/brief.md +51 -0
  26. data/exercises/about-constants/hint.md +7 -0
  27. data/exercises/about-control-statements/about_control_statements.rb +152 -0
  28. data/exercises/about-control-statements/brief.md +9 -0
  29. data/exercises/about-control-statements/hint.md +7 -0
  30. data/exercises/about-dice-project/about_dice_project.rb +27 -0
  31. data/exercises/about-dice-project/brief.md +12 -0
  32. data/exercises/about-dice-project/hint.md +5 -0
  33. data/exercises/about-exceptions/about_exceptions.rb +84 -0
  34. data/exercises/about-exceptions/brief.md +19 -0
  35. data/exercises/about-exceptions/hint.md +8 -0
  36. data/exercises/about-extra-credit/about_extra_credit.rb +117 -0
  37. data/exercises/about-extra-credit/brief.md +28 -0
  38. data/exercises/about-extra-credit/hint.md +5 -0
  39. data/exercises/about-hashes/about_hashes.rb +160 -0
  40. data/exercises/about-hashes/brief.md +9 -0
  41. data/exercises/about-hashes/hint.md +8 -0
  42. data/exercises/about-inheritance/about_inheritance.rb +63 -0
  43. data/exercises/about-inheritance/brief.md +50 -0
  44. data/exercises/about-inheritance/hint.md +8 -0
  45. data/exercises/about-iteration/about_iteration.rb +96 -0
  46. data/exercises/about-iteration/brief.md +26 -0
  47. data/exercises/about-iteration/hint.md +6 -0
  48. data/exercises/about-keyword-arguments/about_keyword_arguments.rb +56 -0
  49. data/exercises/about-keyword-arguments/brief.md +28 -0
  50. data/exercises/about-keyword-arguments/hint.md +7 -0
  51. data/exercises/about-message-passing/about_message_passing.rb +112 -0
  52. data/exercises/about-message-passing/brief.md +59 -0
  53. data/exercises/about-message-passing/hint.md +8 -0
  54. data/exercises/about-methods/about_methods.rb +104 -0
  55. data/exercises/about-methods/brief.md +55 -0
  56. data/exercises/about-methods/hint.md +8 -0
  57. data/exercises/about-modules/about_modules.rb +43 -0
  58. data/exercises/about-modules/brief.md +44 -0
  59. data/exercises/about-modules/hint.md +8 -0
  60. data/exercises/about-nil/about_nil.rb +29 -0
  61. data/exercises/about-nil/brief.md +12 -0
  62. data/exercises/about-nil/hint.md +11 -0
  63. data/exercises/about-objects/about_objects.rb +51 -0
  64. data/exercises/about-objects/brief.md +14 -0
  65. data/exercises/about-objects/hint.md +12 -0
  66. data/exercises/about-open-classes/about_open_classes.rb +38 -0
  67. data/exercises/about-open-classes/brief.md +34 -0
  68. data/exercises/about-open-classes/hint.md +7 -0
  69. data/exercises/about-pattern-matching/about_pattern_matching.rb +106 -0
  70. data/exercises/about-pattern-matching/brief.md +124 -0
  71. data/exercises/about-pattern-matching/hint.md +8 -0
  72. data/exercises/about-proxy-object-project/about_proxy_object_project.rb +43 -0
  73. data/exercises/about-proxy-object-project/brief.md +10 -0
  74. data/exercises/about-proxy-object-project/hint.md +5 -0
  75. data/exercises/about-regular-expressions/about_regular_expressions.rb +174 -0
  76. data/exercises/about-regular-expressions/brief.md +9 -0
  77. data/exercises/about-regular-expressions/hint.md +8 -0
  78. data/exercises/about-sandwich-code/about_sandwich_code.rb +58 -0
  79. data/exercises/about-sandwich-code/brief.md +14 -0
  80. data/exercises/about-sandwich-code/hint.md +5 -0
  81. data/exercises/about-scope/about_scope.rb +76 -0
  82. data/exercises/about-scope/brief.md +35 -0
  83. data/exercises/about-scope/hint.md +8 -0
  84. data/exercises/about-scoring-project/about_scoring_project.rb +16 -0
  85. data/exercises/about-scoring-project/brief.md +10 -0
  86. data/exercises/about-scoring-project/hint.md +5 -0
  87. data/exercises/about-strings/about_strings.rb +142 -0
  88. data/exercises/about-strings/brief.md +22 -0
  89. data/exercises/about-strings/hint.md +11 -0
  90. data/exercises/about-symbols/about_symbols.rb +53 -0
  91. data/exercises/about-symbols/brief.md +21 -0
  92. data/exercises/about-symbols/hint.md +12 -0
  93. data/exercises/about-to-str/about_to_str.rb +49 -0
  94. data/exercises/about-to-str/brief.md +37 -0
  95. data/exercises/about-to-str/hint.md +7 -0
  96. data/exercises/about-triangle-project/about_triangle_project.rb +15 -0
  97. data/exercises/about-triangle-project/brief.md +11 -0
  98. data/exercises/about-triangle-project/hint.md +5 -0
  99. data/exercises/about-triangle-project-two/about_triangle_project_two.rb +22 -0
  100. data/exercises/about-triangle-project-two/brief.md +10 -0
  101. data/exercises/about-triangle-project-two/hint.md +5 -0
  102. data/exercises/about-true-and-false/about_true_and_false.rb +26 -0
  103. data/exercises/about-true-and-false/brief.md +22 -0
  104. data/exercises/about-true-and-false/hint.md +7 -0
  105. data/exercises/blocks-and-methods/blocks_and_methods.rb +14 -0
  106. data/exercises/blocks-and-methods/brief.md +8 -0
  107. data/exercises/blocks-and-methods/hint.md +6 -0
  108. data/exercises/catalog.json +61 -0
  109. data/exercises/class-state/brief.md +8 -0
  110. data/exercises/class-state/class_state.rb +39 -0
  111. data/exercises/class-state/hint.md +5 -0
  112. data/exercises/closure-capture/brief.md +8 -0
  113. data/exercises/closure-capture/closure_capture.rb +21 -0
  114. data/exercises/closure-capture/hint.md +5 -0
  115. data/exercises/collection-basics/brief.md +8 -0
  116. data/exercises/collection-basics/collection_basics.rb +16 -0
  117. data/exercises/collection-basics/hint.md +6 -0
  118. data/exercises/constant-scope/brief.md +8 -0
  119. data/exercises/constant-scope/constant_scope.rb +18 -0
  120. data/exercises/constant-scope/hint.md +5 -0
  121. data/exercises/core-protocols/brief.md +8 -0
  122. data/exercises/core-protocols/core_protocols.rb +43 -0
  123. data/exercises/core-protocols/hint.md +5 -0
  124. data/exercises/delegation/brief.md +8 -0
  125. data/exercises/delegation/delegation.rb +20 -0
  126. data/exercises/delegation/hint.md +5 -0
  127. data/exercises/dynamic-methods/brief.md +8 -0
  128. data/exercises/dynamic-methods/dynamic_methods.rb +33 -0
  129. data/exercises/dynamic-methods/hint.md +5 -0
  130. data/exercises/exception-flow/brief.md +8 -0
  131. data/exercises/exception-flow/exception_flow.rb +27 -0
  132. data/exercises/exception-flow/hint.md +5 -0
  133. data/exercises/heredoc-layout/brief.md +14 -0
  134. data/exercises/heredoc-layout/heredoc_layout.rb +25 -0
  135. data/exercises/heredoc-layout/hint.md +9 -0
  136. data/exercises/keyword-forwarding/brief.md +8 -0
  137. data/exercises/keyword-forwarding/hint.md +5 -0
  138. data/exercises/keyword-forwarding/keyword_forwarding.rb +27 -0
  139. data/exercises/lazy-enumeration/brief.md +8 -0
  140. data/exercises/lazy-enumeration/hint.md +5 -0
  141. data/exercises/lazy-enumeration/lazy_enumeration.rb +16 -0
  142. data/exercises/literals-and-operators/brief.md +20 -0
  143. data/exercises/literals-and-operators/hint.md +5 -0
  144. data/exercises/literals-and-operators/literals_and_operators.rb +15 -0
  145. data/exercises/method-contracts/brief.md +8 -0
  146. data/exercises/method-contracts/hint.md +5 -0
  147. data/exercises/method-contracts/method_contracts.rb +22 -0
  148. data/exercises/method-lookup/brief.md +8 -0
  149. data/exercises/method-lookup/hint.md +5 -0
  150. data/exercises/method-lookup/method_lookup.rb +26 -0
  151. data/exercises/nonlocal-exit/brief.md +8 -0
  152. data/exercises/nonlocal-exit/hint.md +5 -0
  153. data/exercises/nonlocal-exit/nonlocal_exit.rb +29 -0
  154. data/exercises/numbered-parameters/brief.md +18 -0
  155. data/exercises/numbered-parameters/hint.md +5 -0
  156. data/exercises/numbered-parameters/numbered_parameters.rb +18 -0
  157. data/exercises/numeric-precision/brief.md +8 -0
  158. data/exercises/numeric-precision/hint.md +5 -0
  159. data/exercises/numeric-precision/numeric_precision.rb +17 -0
  160. data/exercises/pattern-matching/brief.md +8 -0
  161. data/exercises/pattern-matching/hint.md +5 -0
  162. data/exercises/pattern-matching/pattern_matching.rb +22 -0
  163. data/exercises/refinement-scope/brief.md +8 -0
  164. data/exercises/refinement-scope/hint.md +5 -0
  165. data/exercises/refinement-scope/refinement_scope.rb +33 -0
  166. data/exercises/regexp-captures/brief.md +8 -0
  167. data/exercises/regexp-captures/hint.md +5 -0
  168. data/exercises/regexp-captures/regexp_captures.rb +25 -0
  169. data/exercises/runtime-context/brief.md +20 -0
  170. data/exercises/runtime-context/hint.md +8 -0
  171. data/exercises/runtime-context/runtime_context.rb +11 -0
  172. data/exercises/shared-rows/brief.md +8 -0
  173. data/exercises/shared-rows/hint.md +7 -0
  174. data/exercises/shared-rows/shared_rows.rb +13 -0
  175. data/exercises/singleton-pattern/brief.md +8 -0
  176. data/exercises/singleton-pattern/hint.md +5 -0
  177. data/exercises/singleton-pattern/singleton_pattern.rb +20 -0
  178. data/exercises/time-and-date/brief.md +8 -0
  179. data/exercises/time-and-date/hint.md +5 -0
  180. data/exercises/time-and-date/time_and_date.rb +21 -0
  181. data/exercises/visibility/brief.md +8 -0
  182. data/exercises/visibility/hint.md +5 -0
  183. data/exercises/visibility/visibility.rb +32 -0
  184. data/lib/rkoans/catalog.rb +31 -0
  185. data/lib/rkoans/checker.rb +62 -0
  186. data/lib/rkoans/cli.rb +79 -0
  187. data/lib/rkoans/error.rb +6 -0
  188. data/lib/rkoans/exercise.rb +50 -0
  189. data/lib/rkoans/keyboard.rb +51 -0
  190. data/lib/rkoans/progress.rb +39 -0
  191. data/lib/rkoans/selection.rb +31 -0
  192. data/lib/rkoans/session.rb +127 -0
  193. data/lib/rkoans/terminal_view.rb +99 -0
  194. data/lib/rkoans/version.rb +1 -1
  195. data/lib/rkoans/watcher.rb +58 -0
  196. data/lib/rkoans.rb +13 -3
  197. data/sig/about_array_assignment_acceptance_test.rbs +3 -0
  198. data/sig/about_arrays_acceptance_test.rbs +3 -0
  199. data/sig/about_asserts_command_test.rbs +4 -0
  200. data/sig/about_blocks_acceptance_test.rbs +3 -0
  201. data/sig/about_class_methods_acceptance_test.rbs +3 -0
  202. data/sig/about_classes_acceptance_test.rbs +3 -0
  203. data/sig/about_constants_acceptance_test.rbs +3 -0
  204. data/sig/about_control_statements_acceptance_test.rbs +3 -0
  205. data/sig/about_dice_project_acceptance_test.rbs +3 -0
  206. data/sig/about_exceptions_acceptance_test.rbs +3 -0
  207. data/sig/about_extra_credit_acceptance_test.rbs +5 -0
  208. data/sig/about_hashes_acceptance_test.rbs +3 -0
  209. data/sig/about_inheritance_acceptance_test.rbs +3 -0
  210. data/sig/about_iteration_acceptance_test.rbs +3 -0
  211. data/sig/about_keyword_arguments_acceptance_test.rbs +3 -0
  212. data/sig/about_message_passing_acceptance_test.rbs +3 -0
  213. data/sig/about_methods_acceptance_test.rbs +3 -0
  214. data/sig/about_modules_acceptance_test.rbs +3 -0
  215. data/sig/about_nil_acceptance_test.rbs +3 -0
  216. data/sig/about_objects_acceptance_test.rbs +3 -0
  217. data/sig/about_open_classes_acceptance_test.rbs +3 -0
  218. data/sig/about_pattern_matching_acceptance_test.rbs +3 -0
  219. data/sig/about_proxy_object_project_acceptance_test.rbs +3 -0
  220. data/sig/about_regular_expressions_acceptance_test.rbs +3 -0
  221. data/sig/about_sandwich_code_acceptance_test.rbs +3 -0
  222. data/sig/about_scope_acceptance_test.rbs +3 -0
  223. data/sig/about_scoring_project_acceptance_test.rbs +3 -0
  224. data/sig/about_strings_acceptance_test.rbs +3 -0
  225. data/sig/about_symbols_acceptance_test.rbs +3 -0
  226. data/sig/about_to_str_acceptance_test.rbs +3 -0
  227. data/sig/about_triangle_project_acceptance_test.rbs +3 -0
  228. data/sig/about_triangle_project_two_acceptance_test.rbs +3 -0
  229. data/sig/about_true_and_false_command_test.rbs +4 -0
  230. data/sig/catalog_error_command_test.rbs +4 -0
  231. data/sig/checker_test.rbs +9 -0
  232. data/sig/class_state_acceptance_test.rbs +3 -0
  233. data/sig/closure_capture_acceptance_test.rbs +3 -0
  234. data/sig/command_support.rbs +18 -0
  235. data/sig/command_test.rbs +5 -0
  236. data/sig/constant_scope_acceptance_test.rbs +3 -0
  237. data/sig/core_protocols_acceptance_test.rbs +3 -0
  238. data/sig/curriculum_cop_test.rbs +9 -0
  239. data/sig/delegation_acceptance_test.rbs +3 -0
  240. data/sig/dynamic_methods_acceptance_test.rbs +3 -0
  241. data/sig/exception_flow_acceptance_test.rbs +3 -0
  242. data/sig/exercise_test.rbs +3 -0
  243. data/sig/exercises/about_array_assignment.rbs +36 -0
  244. data/sig/exercises/about_arrays.rbs +51 -0
  245. data/sig/exercises/about_asserts.rbs +23 -0
  246. data/sig/exercises/about_blocks.rbs +40 -0
  247. data/sig/exercises/about_class_methods.rbs +62 -0
  248. data/sig/exercises/about_classes.rbs +88 -0
  249. data/sig/exercises/about_constants.rbs +53 -0
  250. data/sig/exercises/about_control_statements.rbs +46 -0
  251. data/sig/exercises/about_dice_project.rbs +16 -0
  252. data/sig/exercises/about_exceptions.rbs +36 -0
  253. data/sig/exercises/about_extra_credit.rbs +36 -0
  254. data/sig/exercises/about_hashes.rbs +62 -0
  255. data/sig/exercises/about_inheritance.rbs +50 -0
  256. data/sig/exercises/about_iteration.rbs +37 -0
  257. data/sig/exercises/about_keyword_arguments.rbs +33 -0
  258. data/sig/exercises/about_message_passing.rbs +68 -0
  259. data/sig/exercises/about_methods.rbs +68 -0
  260. data/sig/exercises/about_modules.rbs +38 -0
  261. data/sig/exercises/about_nil.rbs +23 -0
  262. data/sig/exercises/about_objects.rbs +38 -0
  263. data/sig/exercises/about_open_classes.rbs +31 -0
  264. data/sig/exercises/about_pattern_matching.rbs +65 -0
  265. data/sig/exercises/about_proxy_object_project.rbs +31 -0
  266. data/sig/exercises/about_regular_expressions.rbs +83 -0
  267. data/sig/exercises/about_sandwich_code.rbs +17 -0
  268. data/sig/exercises/about_scope.rbs +59 -0
  269. data/sig/exercises/about_scoring_project.rbs +16 -0
  270. data/sig/exercises/about_strings.rbs +85 -0
  271. data/sig/exercises/about_symbols.rbs +46 -0
  272. data/sig/exercises/about_to_str.rbs +36 -0
  273. data/sig/exercises/about_triangle_project.rbs +11 -0
  274. data/sig/exercises/about_triangle_project_two.rbs +12 -0
  275. data/sig/exercises/about_true_and_false.rbs +27 -0
  276. data/sig/exercises/blocks_and_methods.rbs +11 -0
  277. data/sig/exercises/class_state.rbs +19 -0
  278. data/sig/exercises/closure_capture.rbs +10 -0
  279. data/sig/exercises/collection_basics.rbs +6 -0
  280. data/sig/exercises/collection_basics_test.rbs +4 -0
  281. data/sig/exercises/constant_scope.rbs +11 -0
  282. data/sig/exercises/core_protocols.rbs +20 -0
  283. data/sig/exercises/delegation.rbs +14 -0
  284. data/sig/exercises/dynamic_methods.rbs +13 -0
  285. data/sig/exercises/exception_flow.rbs +11 -0
  286. data/sig/exercises/heredoc_layout.rbs +11 -0
  287. data/sig/exercises/keyword_forwarding.rbs +12 -0
  288. data/sig/exercises/lazy_enumeration.rbs +10 -0
  289. data/sig/exercises/literals_and_operators.rbs +12 -0
  290. data/sig/exercises/method_contracts.rbs +11 -0
  291. data/sig/exercises/method_lookup.rbs +16 -0
  292. data/sig/exercises/nonlocal_exit.rbs +14 -0
  293. data/sig/exercises/numbered_parameters.rbs +11 -0
  294. data/sig/exercises/numeric_precision.rbs +11 -0
  295. data/sig/exercises/pattern_matching.rbs +10 -0
  296. data/sig/exercises/refinement_scope.rbs +18 -0
  297. data/sig/exercises/regexp_captures.rbs +11 -0
  298. data/sig/exercises/runtime_context.rbs +23 -0
  299. data/sig/exercises/shared_rows.rbs +11 -0
  300. data/sig/exercises/singleton_pattern.rbs +14 -0
  301. data/sig/exercises/time_and_date.rbs +11 -0
  302. data/sig/exercises/visibility.rbs +18 -0
  303. data/sig/fixture_support.rbs +11 -0
  304. data/sig/help_hint_command_test.rbs +8 -0
  305. data/sig/heredoc_layout_acceptance_test.rbs +3 -0
  306. data/sig/keyboard_session_test.rbs +9 -0
  307. data/sig/keyword_forwarding_acceptance_test.rbs +3 -0
  308. data/sig/lazy_enumeration_acceptance_test.rbs +3 -0
  309. data/sig/literals_and_operators_acceptance_test.rbs +3 -0
  310. data/sig/method_contracts_acceptance_test.rbs +3 -0
  311. data/sig/method_lookup_acceptance_test.rbs +3 -0
  312. data/sig/nonlocal_exit_acceptance_test.rbs +3 -0
  313. data/sig/numbered_parameters_acceptance_test.rbs +3 -0
  314. data/sig/numeric_precision_acceptance_test.rbs +4 -0
  315. data/sig/packaging_test.rbs +3 -0
  316. data/sig/pattern_matching_acceptance_test.rbs +3 -0
  317. data/sig/reference_solutions_test.rbs +3 -0
  318. data/sig/refinement_scope_acceptance_test.rbs +3 -0
  319. data/sig/regexp_captures_acceptance_test.rbs +4 -0
  320. data/sig/rkoans/catalog.rbs +11 -0
  321. data/sig/rkoans/checker.rbs +22 -0
  322. data/sig/rkoans/cli.rbs +21 -0
  323. data/sig/rkoans/exercise.rbs +18 -0
  324. data/sig/rkoans/keyboard.rbs +13 -0
  325. data/sig/rkoans/progress.rbs +9 -0
  326. data/sig/rkoans/selection.rbs +9 -0
  327. data/sig/rkoans/session.rbs +30 -0
  328. data/sig/rkoans/terminal_view.rbs +24 -0
  329. data/sig/rkoans/watcher.rbs +18 -0
  330. data/sig/rkoans.rbs +2 -0
  331. data/sig/runtime_context_command_test.rbs +4 -0
  332. data/sig/selection_command_test.rbs +5 -0
  333. data/sig/session_command_test.rbs +12 -0
  334. data/sig/session_edge_cases_test.rbs +4 -0
  335. data/sig/shared_rows_acceptance_test.rbs +3 -0
  336. data/sig/singleton_pattern_acceptance_test.rbs +3 -0
  337. data/sig/time_and_date_acceptance_test.rbs +4 -0
  338. data/sig/visibility_acceptance_test.rbs +4 -0
  339. data/sig/watcher_test.rbs +3 -0
  340. data/solutions/about-array-assignment/about_array_assignment.rb +36 -0
  341. data/solutions/about-arrays/about_arrays.rb +53 -0
  342. data/solutions/about-asserts/about_asserts.rb +22 -0
  343. data/solutions/about-blocks/about_blocks.rb +30 -0
  344. data/solutions/about-class-methods/about_class_methods.rb +36 -0
  345. data/solutions/about-classes/about_classes.rb +40 -0
  346. data/solutions/about-constants/about_constants.rb +26 -0
  347. data/solutions/about-control-statements/about_control_statements.rb +35 -0
  348. data/solutions/about-dice-project/about_dice_project.rb +27 -0
  349. data/solutions/about-exceptions/about_exceptions.rb +30 -0
  350. data/solutions/about-extra-credit/about_extra_credit.rb +114 -0
  351. data/solutions/about-hashes/about_hashes.rb +52 -0
  352. data/solutions/about-inheritance/about_inheritance.rb +27 -0
  353. data/solutions/about-iteration/about_iteration.rb +31 -0
  354. data/solutions/about-keyword-arguments/about_keyword_arguments.rb +28 -0
  355. data/solutions/about-message-passing/about_message_passing.rb +38 -0
  356. data/solutions/about-methods/about_methods.rb +39 -0
  357. data/solutions/about-modules/about_modules.rb +23 -0
  358. data/solutions/about-nil/about_nil.rb +23 -0
  359. data/solutions/about-objects/about_objects.rb +34 -0
  360. data/solutions/about-open-classes/about_open_classes.rb +23 -0
  361. data/solutions/about-pattern-matching/about_pattern_matching.rb +39 -0
  362. data/solutions/about-proxy-object-project/about_proxy_object_project.rb +44 -0
  363. data/solutions/about-regular-expressions/about_regular_expressions.rb +60 -0
  364. data/solutions/about-sandwich-code/about_sandwich_code.rb +60 -0
  365. data/solutions/about-scope/about_scope.rb +33 -0
  366. data/solutions/about-scoring-project/about_scoring_project.rb +19 -0
  367. data/solutions/about-strings/about_strings.rb +56 -0
  368. data/solutions/about-symbols/about_symbols.rb +35 -0
  369. data/solutions/about-to-str/about_to_str.rb +24 -0
  370. data/solutions/about-triangle-project/about_triangle_project.rb +19 -0
  371. data/solutions/about-triangle-project-two/about_triangle_project_two.rb +25 -0
  372. data/solutions/about-true-and-false/about_true_and_false.rb +25 -0
  373. data/solutions/blocks-and-methods/blocks_and_methods.rb +14 -0
  374. data/solutions/class-state/class_state.rb +33 -0
  375. data/solutions/closure-capture/closure_capture.rb +12 -0
  376. data/solutions/collection-basics/collection_basics.rb +14 -0
  377. data/solutions/constant-scope/constant_scope.rb +18 -0
  378. data/solutions/core-protocols/core_protocols.rb +44 -0
  379. data/solutions/delegation/delegation.rb +17 -0
  380. data/solutions/dynamic-methods/dynamic_methods.rb +32 -0
  381. data/solutions/exception-flow/exception_flow.rb +34 -0
  382. data/solutions/heredoc-layout/heredoc_layout.rb +24 -0
  383. data/solutions/keyword-forwarding/keyword_forwarding.rb +26 -0
  384. data/solutions/lazy-enumeration/lazy_enumeration.rb +11 -0
  385. data/solutions/literals-and-operators/literals_and_operators.rb +22 -0
  386. data/solutions/method-contracts/method_contracts.rb +18 -0
  387. data/solutions/method-lookup/method_lookup.rb +26 -0
  388. data/solutions/nonlocal-exit/nonlocal_exit.rb +46 -0
  389. data/solutions/numbered-parameters/numbered_parameters.rb +18 -0
  390. data/solutions/numeric-precision/numeric_precision.rb +17 -0
  391. data/solutions/pattern-matching/pattern_matching.rb +17 -0
  392. data/solutions/refinement-scope/refinement_scope.rb +34 -0
  393. data/solutions/regexp-captures/regexp_captures.rb +24 -0
  394. data/solutions/runtime-context/runtime_context.rb +19 -0
  395. data/solutions/shared-rows/shared_rows.rb +13 -0
  396. data/solutions/singleton-pattern/singleton_pattern.rb +19 -0
  397. data/solutions/time-and-date/time_and_date.rb +16 -0
  398. data/solutions/visibility/visibility.rb +34 -0
  399. data/test/exercises/about_array_assignment_test.rb +87 -0
  400. data/test/exercises/about_arrays_test.rb +119 -0
  401. data/test/exercises/about_asserts_test.rb +41 -0
  402. data/test/exercises/about_blocks_test.rb +140 -0
  403. data/test/exercises/about_class_methods_test.rb +232 -0
  404. data/test/exercises/about_classes_test.rb +261 -0
  405. data/test/exercises/about_constants_test.rb +111 -0
  406. data/test/exercises/about_control_statements_test.rb +188 -0
  407. data/test/exercises/about_dice_project_test.rb +40 -0
  408. data/test/exercises/about_exceptions_test.rb +98 -0
  409. data/test/exercises/about_extra_credit_test.rb +74 -0
  410. data/test/exercises/about_hashes_test.rb +163 -0
  411. data/test/exercises/about_inheritance_test.rb +121 -0
  412. data/test/exercises/about_iteration_test.rb +148 -0
  413. data/test/exercises/about_keyword_arguments_test.rb +80 -0
  414. data/test/exercises/about_message_passing_test.rb +230 -0
  415. data/test/exercises/about_methods_test.rb +208 -0
  416. data/test/exercises/about_modules_test.rb +98 -0
  417. data/test/exercises/about_nil_test.rb +35 -0
  418. data/test/exercises/about_objects_test.rb +74 -0
  419. data/test/exercises/about_open_classes_test.rb +60 -0
  420. data/test/exercises/about_pattern_matching_test.rb +257 -0
  421. data/test/exercises/about_proxy_object_project_test.rb +75 -0
  422. data/test/exercises/about_regular_expressions_test.rb +243 -0
  423. data/test/exercises/about_sandwich_code_test.rb +82 -0
  424. data/test/exercises/about_scope_test.rb +123 -0
  425. data/test/exercises/about_scoring_project_test.rb +62 -0
  426. data/test/exercises/about_strings_test.rb +255 -0
  427. data/test/exercises/about_symbols_test.rb +120 -0
  428. data/test/exercises/about_to_str_test.rb +89 -0
  429. data/test/exercises/about_triangle_project_test.rb +29 -0
  430. data/test/exercises/about_triangle_project_two_test.rb +28 -0
  431. data/test/exercises/about_true_and_false_test.rb +43 -0
  432. data/test/exercises/blocks_and_methods_test.rb +22 -0
  433. data/test/exercises/class_state_test.rb +29 -0
  434. data/test/exercises/closure_capture_test.rb +29 -0
  435. data/test/exercises/collection_basics_test.rb +18 -0
  436. data/test/exercises/constant_scope_test.rb +18 -0
  437. data/test/exercises/core_protocols_test.rb +28 -0
  438. data/test/exercises/delegation_test.rb +23 -0
  439. data/test/exercises/dynamic_methods_test.rb +28 -0
  440. data/test/exercises/exception_flow_test.rb +17 -0
  441. data/test/exercises/heredoc_layout_test.rb +18 -0
  442. data/test/exercises/keyword_forwarding_test.rb +22 -0
  443. data/test/exercises/lazy_enumeration_test.rb +15 -0
  444. data/test/exercises/literals_and_operators_test.rb +25 -0
  445. data/test/exercises/method_contracts_test.rb +28 -0
  446. data/test/exercises/method_lookup_test.rb +14 -0
  447. data/test/exercises/nonlocal_exit_test.rb +22 -0
  448. data/test/exercises/numbered_parameters_test.rb +15 -0
  449. data/test/exercises/numeric_precision_test.rb +24 -0
  450. data/test/exercises/pattern_matching_test.rb +18 -0
  451. data/test/exercises/refinement_scope_test.rb +14 -0
  452. data/test/exercises/regexp_captures_test.rb +20 -0
  453. data/test/exercises/runtime_context_test.rb +59 -0
  454. data/test/exercises/shared_rows_test.rb +34 -0
  455. data/test/exercises/singleton_pattern_test.rb +16 -0
  456. data/test/exercises/time_and_date_test.rb +22 -0
  457. data/test/exercises/visibility_test.rb +22 -0
  458. metadata +471 -4
  459. data/Rakefile +0 -12
  460. data/sig/test_rkoans.rbs +0 -3
@@ -0,0 +1,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The original descriptive check identifiers and example strings remain intact.
4
+ # An empty class demonstrates construction without custom methods.
5
+ # The example deliberately contrasts received arguments with values actually used.
6
+ # The direct method call is compared with send and __send__ in this chapter.
7
+ # The block name is observable through parameter metadata or the explicit forwarding example.
8
+ # The exercise makes positional, keyword, and block forwarding visible.
9
+ # This catcher deliberately demonstrates misleading introspection.
10
+ # The dynamic message example constructs a method name from separate strings.
11
+ # Explicit forwarding makes the missing-method and visibility arguments visible.
12
+ # rubocop:disable Layout/LineLength, Lint/EmptyClass, Lint/UnusedMethodArgument, Minitest/AssertPredicate, Naming/BlockForwarding, Style/ArgumentsForwarding, Style/MissingRespondToMissing, Style/StringConcatenation, Style/SuperArguments
13
+
14
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
15
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
16
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
17
+
18
+ require ARGV.shift
19
+ class AboutMessagePassingTest < Minitest::Test
20
+ class MessageCatcher
21
+ # Demonstrates caught?.
22
+ def caught?
23
+ true
24
+ end
25
+ end
26
+
27
+ # Checks methods can be called directly.
28
+ def test_methods_can_be_called_directly
29
+ mc = MessageCatcher.new
30
+
31
+ assert mc.caught?
32
+ end
33
+
34
+ # Checks methods can be invoked by sending the message.
35
+ def test_methods_can_be_invoked_by_sending_the_message
36
+ mc = MessageCatcher.new
37
+
38
+ assert mc.send(:caught?)
39
+ end
40
+
41
+ # Checks methods can be invoked more dynamically.
42
+ def test_methods_can_be_invoked_more_dynamically
43
+ mc = MessageCatcher.new
44
+
45
+ assert mc.send('caught?')
46
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:methods_can_be_invoked_more_dynamically_one), mc.send('caught' + '?') # What do you need to add to the first string?
47
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:methods_can_be_invoked_more_dynamically_two), mc.send('CAUGHT?'.downcase) # What would you need to do to the string?
48
+ end
49
+
50
+ # Checks send with underscores will also send messages.
51
+ def test_send_with_underscores_will_also_send_messages
52
+ mc = MessageCatcher.new
53
+
54
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:send_with_underscores_will_also_send_messages_one),
55
+ mc.__send__(:caught?)
56
+
57
+ # THINK ABOUT IT:
58
+ #
59
+ # Why does Ruby provide both send and __send__ ?
60
+ end
61
+
62
+ # Checks classes can be asked if they know how to respond.
63
+ def test_classes_can_be_asked_if_they_know_how_to_respond
64
+ mc = MessageCatcher.new
65
+
66
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:classes_can_be_asked_if_they_know_how_to_respond_one),
67
+ mc.respond_to?(:caught?)
68
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:classes_can_be_asked_if_they_know_how_to_respond_two),
69
+ mc.respond_to?(:does_not_exist)
70
+ end
71
+
72
+ # ------------------------------------------------------------------
73
+
74
+ class MessageCatcher
75
+ # Demonstrates add a payload.
76
+ def add_a_payload(*args)
77
+ args
78
+ end
79
+ end
80
+
81
+ # Checks sending a message with arguments.
82
+ def test_sending_a_message_with_arguments
83
+ mc = MessageCatcher.new
84
+
85
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:sending_a_message_with_arguments_one), mc.add_a_payload
86
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:sending_a_message_with_arguments_two),
87
+ mc.send(:add_a_payload)
88
+
89
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:sending_a_message_with_arguments_three),
90
+ mc.add_a_payload(3, 4, nil, 6)
91
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:sending_a_message_with_arguments_four),
92
+ mc.send(:add_a_payload, 3, 4, nil, 6)
93
+ end
94
+
95
+ # Message dispatch:
96
+ #
97
+ # Both obj.msg and obj.send(:msg) sends the message named :msg to
98
+ # the object. We use "send" when the name of the message can vary
99
+ # dynamically (e.g. calculated at run time), but by far the most
100
+ # common way of sending a message is just to say: obj.msg.
101
+
102
+ # ------------------------------------------------------------------
103
+
104
+ class TypicalObject
105
+ end
106
+
107
+ # Checks sending undefined messages to a typical object results in errors.
108
+ def test_sending_undefined_messages_to_a_typical_object_results_in_errors
109
+ typical = TypicalObject.new
110
+
111
+ exception = assert_predicted_error(:sending_undefined_messages_to_a_typical_object_results_in_errors_one,
112
+ ::NoMethodError) do
113
+ typical.foobar
114
+ end
115
+ assert_match(/foobar/, exception.message)
116
+ end
117
+
118
+ # Checks calling method missing causes the no method error.
119
+ def test_calling_method_missing_causes_the_no_method_error
120
+ typical = TypicalObject.new
121
+
122
+ exception = assert_predicted_error(:calling_method_missing_causes_the_no_method_error_one, ::NoMethodError) do
123
+ typical.__send__(:method_missing, :foobar)
124
+ end
125
+ assert_match(/foobar/, exception.message)
126
+
127
+ # THINK ABOUT IT:
128
+ #
129
+ # If the method :method_missing causes the NoMethodError, then
130
+ # what would happen if we redefine method_missing?
131
+ #
132
+ end
133
+
134
+ # ------------------------------------------------------------------
135
+
136
+ class AllMessageCatcher
137
+ # Demonstrates method missing.
138
+ def method_missing(method_name, *args, &block)
139
+ "Someone called #{method_name} with <#{args.join(', ')}>"
140
+ end
141
+ end
142
+
143
+ # Checks all messages are caught.
144
+ def test_all_messages_are_caught
145
+ catcher = AllMessageCatcher.new
146
+
147
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:all_messages_are_caught_one), catcher.foobar
148
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:all_messages_are_caught_two), catcher.foobaz(1)
149
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:all_messages_are_caught_three),
150
+ catcher.sum(1, 2, 3, 4, 5, 6)
151
+ end
152
+
153
+ # Checks catching messages makes respond to lie.
154
+ def test_catching_messages_makes_respond_to_lie
155
+ catcher = AllMessageCatcher.new
156
+
157
+ catcher.any_method
158
+
159
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:catching_messages_makes_respond_to_lie_one),
160
+ catcher.respond_to?(:any_method)
161
+ end
162
+
163
+ # ------------------------------------------------------------------
164
+
165
+ class WellBehavedFooCatcher
166
+ # Demonstrates method missing.
167
+ def method_missing(method_name, *args, &block)
168
+ if method_name.to_s[0, 3] == 'foo'
169
+ 'Foo to you too'
170
+ else
171
+ super(method_name, *args, &block)
172
+ end
173
+ end
174
+ end
175
+
176
+ # Checks foo method are caught.
177
+ def test_foo_method_are_caught
178
+ catcher = WellBehavedFooCatcher.new
179
+
180
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:foo_method_are_caught_one), catcher.foo_bar
181
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:foo_method_are_caught_two), catcher.foo_baz
182
+ end
183
+
184
+ # Checks non foo messages are treated normally.
185
+ def test_non_foo_messages_are_treated_normally
186
+ catcher = WellBehavedFooCatcher.new
187
+
188
+ assert_predicted_error(:non_foo_messages_are_treated_normally_one, ::NoMethodError) do
189
+ catcher.normal_undefined_method
190
+ end
191
+ end
192
+
193
+ # ------------------------------------------------------------------
194
+
195
+ # (note: just reopening class from above)
196
+ class WellBehavedFooCatcher
197
+ private
198
+
199
+ # Demonstrates respond to missing?.
200
+ def respond_to_missing?(method_name, include_private = false)
201
+ if method_name.to_s[0, 3] == 'foo'
202
+ true
203
+ else
204
+ super(method_name, include_private)
205
+ end
206
+ end
207
+ end
208
+
209
+ # Checks explicitly implementing respond to lets objects tell the truth.
210
+ def test_explicitly_implementing_respond_to_lets_objects_tell_the_truth
211
+ catcher = WellBehavedFooCatcher.new
212
+
213
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:explicitly_implementing_respond_to_lets_objects_tell_the_truth_one),
214
+ catcher.respond_to?(:foo_bar)
215
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(:explicitly_implementing_respond_to_lets_objects_tell_the_truth_two),
216
+ catcher.respond_to?(:something_else)
217
+ end
218
+
219
+ # Checks the predicted exception class while returning the captured error.
220
+ # @param key [Symbol] answer field
221
+ # @param klass [Class<Exception>] exception raised by the example
222
+ # @return [Exception]
223
+ def assert_predicted_error(key, ...)
224
+ error = assert_raises(...)
225
+ assert_equal Exercises::AboutMessagePassing.koans.fetch(key), error.class
226
+ error
227
+ end
228
+ end
229
+
230
+ # rubocop:enable Layout/LineLength, Lint/EmptyClass, Lint/UnusedMethodArgument, Minitest/AssertPredicate, Naming/BlockForwarding, Style/ArgumentsForwarding, Style/MissingRespondToMissing, Style/StringConcatenation, Style/SuperArguments
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The unreachable expression demonstrates the effect of explicit return.
4
+ # Non-returned expressions demonstrate method return behavior.
5
+ # Keep the related original chapter examples together.
6
+ # Short parameter names match the small arithmetic or assignment examples.
7
+ # The fixed literal expression is an isolated binding or syntax experiment.
8
+ # The explicit receiver is part of the method-call experiment.
9
+ # rubocop:disable Lint/UnreachableCode, Lint/Void, Metrics/ClassLength, Naming/MethodParameterName, Style/EvalWithLocation, Style/RedundantSelf
10
+
11
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
12
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
13
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
14
+
15
+ require ARGV.shift
16
+ # Demonstrates my global method.
17
+ def my_global_method(a, b)
18
+ a + b
19
+ end
20
+
21
+ class AboutMethodsTest < Minitest::Test
22
+ # Checks calling global methods.
23
+ def test_calling_global_methods
24
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_global_methods_one), my_global_method(2, 3)
25
+ end
26
+
27
+ # Checks calling global methods without parentheses.
28
+ def test_calling_global_methods_without_parentheses
29
+ result = my_global_method 2, 3
30
+
31
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_global_methods_without_parentheses_one), result
32
+ end
33
+
34
+ # Parentheses make the inner call's argument list explicit.
35
+ # Checks sometimes missing parentheses are ambiguous.
36
+ def test_sometimes_missing_parentheses_are_ambiguous
37
+ assert_equal Exercises::AboutMethods.koans.fetch(:sometimes_missing_parentheses_are_ambiguous_one),
38
+ eval('my_global_method(2, 3)')
39
+ end
40
+
41
+ # NOTE: wrong number of arguments is not a SYNTAX error, but a
42
+ # runtime error.
43
+ # Checks calling global methods with wrong number of arguments.
44
+ def test_calling_global_methods_with_wrong_number_of_arguments
45
+ exception = assert_predicted_error(:calling_global_methods_with_wrong_number_of_arguments_one, ::ArgumentError) do
46
+ my_global_method
47
+ end
48
+ assert_predicted_message(:calling_global_methods_with_wrong_number_of_arguments_two, exception.message)
49
+
50
+ exception = assert_predicted_error(:calling_global_methods_with_wrong_number_of_arguments_three, ::ArgumentError) do
51
+ my_global_method(1, 2, 3)
52
+ end
53
+ assert_predicted_message(:calling_global_methods_with_wrong_number_of_arguments_four, exception.message)
54
+ end
55
+
56
+ # ------------------------------------------------------------------
57
+
58
+ # Demonstrates method with defaults.
59
+ def method_with_defaults(a, b = :default_value)
60
+ [a, b]
61
+ end
62
+
63
+ # Checks calling with default values.
64
+ def test_calling_with_default_values
65
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_with_default_values_one), method_with_defaults(1)
66
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_with_default_values_two), method_with_defaults(1, 2)
67
+ end
68
+
69
+ # ------------------------------------------------------------------
70
+
71
+ # Demonstrates method with var args.
72
+ def method_with_var_args(*args)
73
+ args
74
+ end
75
+
76
+ # Checks calling with variable arguments.
77
+ def test_calling_with_variable_arguments
78
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_with_variable_arguments_one), method_with_var_args.class
79
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_with_variable_arguments_two), method_with_var_args
80
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_with_variable_arguments_three),
81
+ method_with_var_args(:one)
82
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_with_variable_arguments_four),
83
+ method_with_var_args(:one, :two)
84
+ end
85
+
86
+ # ------------------------------------------------------------------
87
+
88
+ # Demonstrates method with explicit return.
89
+ def method_with_explicit_return
90
+ :a_non_return_value
91
+ return :return_value
92
+ :another_non_return_value
93
+ end
94
+
95
+ # Checks method with explicit return.
96
+ def test_method_with_explicit_return
97
+ assert_equal Exercises::AboutMethods.koans.fetch(:method_with_explicit_return_one), method_with_explicit_return
98
+ end
99
+
100
+ # ------------------------------------------------------------------
101
+
102
+ # Demonstrates method without explicit return.
103
+ def method_without_explicit_return
104
+ :a_non_return_value
105
+ :return_value
106
+ end
107
+
108
+ # Checks method without explicit return.
109
+ def test_method_without_explicit_return
110
+ assert_equal Exercises::AboutMethods.koans.fetch(:method_without_explicit_return_one),
111
+ method_without_explicit_return
112
+ end
113
+
114
+ # ------------------------------------------------------------------
115
+
116
+ # Demonstrates my method in the same class.
117
+ def my_method_in_the_same_class(a, b)
118
+ a * b
119
+ end
120
+
121
+ # Checks calling methods in same class.
122
+ def test_calling_methods_in_same_class
123
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_methods_in_same_class_one),
124
+ my_method_in_the_same_class(3, 4)
125
+ end
126
+
127
+ # Checks calling methods in same class with explicit receiver.
128
+ def test_calling_methods_in_same_class_with_explicit_receiver
129
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_methods_in_same_class_with_explicit_receiver_one),
130
+ self.my_method_in_the_same_class(3, 4)
131
+ end
132
+
133
+ # ------------------------------------------------------------------
134
+
135
+ # Demonstrates my private method.
136
+ def my_private_method
137
+ 'a secret'
138
+ end
139
+ private :my_private_method
140
+
141
+ # Checks calling private methods without receiver.
142
+ def test_calling_private_methods_without_receiver
143
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_private_methods_without_receiver_one), my_private_method
144
+ end
145
+
146
+ # Modern Ruby permits self as the receiver of a private method.
147
+ # Checks calling private methods with an explicit receiver.
148
+ def test_calling_private_methods_with_an_explicit_receiver
149
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_private_methods_with_an_explicit_receiver_one),
150
+ self.my_private_method
151
+ end
152
+
153
+ # ------------------------------------------------------------------
154
+
155
+ class Dog
156
+ # Demonstrates name.
157
+ def name
158
+ 'Fido'
159
+ end
160
+
161
+ private
162
+
163
+ # Demonstrates tail.
164
+ def tail
165
+ 'tail'
166
+ end
167
+ end
168
+
169
+ # Checks calling methods in other objects require explicit receiver.
170
+ def test_calling_methods_in_other_objects_require_explicit_receiver
171
+ rover = Dog.new
172
+
173
+ assert_equal Exercises::AboutMethods.koans.fetch(:calling_methods_in_other_objects_require_explicit_receiver_one),
174
+ rover.name
175
+ end
176
+
177
+ # Checks calling private methods in other objects.
178
+ def test_calling_private_methods_in_other_objects
179
+ rover = Dog.new
180
+ assert_predicted_error(:calling_private_methods_in_other_objects_one, ::NoMethodError) do
181
+ rover.tail
182
+ end
183
+ end
184
+
185
+ # Checks the predicted exception class while returning the captured error.
186
+ # @param key [Symbol] answer field
187
+ # @param klass [Class<Exception>] exception raised by the example
188
+ # @return [Exception]
189
+ def assert_predicted_error(key, ...)
190
+ error = assert_raises(...)
191
+ assert_equal Exercises::AboutMethods.koans.fetch(key), error.class
192
+ error
193
+ end
194
+
195
+ # Checks a nonempty literal fragment without depending on full diagnostic formatting.
196
+ # @param key [Symbol] answer field
197
+ # @param message [String] observed exception message
198
+ # @return [void]
199
+ def assert_predicted_message(key, message)
200
+ fragment = Exercises::AboutMethods.koans.fetch(key)
201
+
202
+ assert_kind_of String, fragment
203
+ refute_empty fragment
204
+ assert_includes message, fragment
205
+ end
206
+ end
207
+
208
+ # rubocop:enable Lint/UnreachableCode, Lint/Void, Metrics/ClassLength, Naming/MethodParameterName, Style/EvalWithLocation, Style/RedundantSelf
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Explicit setters are compared with generated accessors in this chapter.
4
+ # rubocop:disable Naming/AccessorMethodName
5
+
6
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
7
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
8
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
9
+
10
+ require ARGV.shift
11
+ class AboutModulesTest < Minitest::Test
12
+ module Nameable
13
+ # Demonstrates set name.
14
+ def set_name(new_name)
15
+ @name = new_name
16
+ end
17
+
18
+ # Demonstrates here.
19
+ def here
20
+ :in_module
21
+ end
22
+ end
23
+
24
+ # Checks cant instantiate modules.
25
+ def test_cant_instantiate_modules
26
+ assert_predicted_error(:cant_instantiate_modules_one, ::NoMethodError) do
27
+ Nameable.new
28
+ end
29
+ end
30
+
31
+ # ------------------------------------------------------------------
32
+
33
+ class Dog
34
+ include Nameable
35
+
36
+ attr_reader :name
37
+
38
+ # Demonstrates initialize.
39
+ def initialize
40
+ @name = 'Fido'
41
+ end
42
+
43
+ # Demonstrates bark.
44
+ def bark
45
+ 'WOOF'
46
+ end
47
+
48
+ # Demonstrates here.
49
+ def here
50
+ :in_object
51
+ end
52
+ end
53
+
54
+ # Checks normal methods are available in the object.
55
+ def test_normal_methods_are_available_in_the_object
56
+ fido = Dog.new
57
+
58
+ assert_equal Exercises::AboutModules.koans.fetch(:normal_methods_are_available_in_the_object_one), fido.bark
59
+ end
60
+
61
+ # Checks module methods are also available in the object.
62
+ def test_module_methods_are_also_available_in_the_object
63
+ fido = Dog.new
64
+
65
+ fido.set_name('Rover')
66
+ end
67
+
68
+ # Checks module methods can affect instance variables in the object.
69
+ def test_module_methods_can_affect_instance_variables_in_the_object
70
+ fido = Dog.new
71
+
72
+ assert_equal Exercises::AboutModules.koans.fetch(:module_methods_can_affect_instance_variables_in_the_object_one),
73
+ fido.name
74
+ fido.set_name('Rover')
75
+
76
+ assert_equal Exercises::AboutModules.koans.fetch(:module_methods_can_affect_instance_variables_in_the_object_two),
77
+ fido.name
78
+ end
79
+
80
+ # Checks classes can override module methods.
81
+ def test_classes_can_override_module_methods
82
+ fido = Dog.new
83
+
84
+ assert_equal Exercises::AboutModules.koans.fetch(:classes_can_override_module_methods_one), fido.here
85
+ end
86
+
87
+ # Checks the predicted exception class while returning the captured error.
88
+ # @param key [Symbol] answer field
89
+ # @param klass [Class<Exception>] exception raised by the example
90
+ # @return [Exception]
91
+ def assert_predicted_error(key, ...)
92
+ error = assert_raises(...)
93
+ assert_equal Exercises::AboutModules.koans.fetch(key), error.class
94
+ error
95
+ end
96
+ end
97
+
98
+ # rubocop:enable Naming/AccessorMethodName
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ require ARGV.shift
8
+
9
+ # Observes nil as an object with methods and ordinary missing-method errors.
10
+ class AboutNilTest < Minitest::Test
11
+ # Nil is an object rather than an absent receiver.
12
+ def test_nil_is_an_object
13
+ assert_equal Exercises::AboutNil.koans[:nil_object], nil.is_a?(Object)
14
+ end
15
+
16
+ # Missing methods raise an error with an inspectable class and message.
17
+ def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil
18
+ error = assert_raises(NoMethodError) { nil.some_method_nil_doesnt_know_about }
19
+ answers = Exercises::AboutNil.koans
20
+
21
+ assert_equal answers[:missing_method_error], error.class
22
+ assert_kind_of String, answers[:message_fragment]
23
+ refute_empty answers[:message_fragment]
24
+ assert_includes error.message, answers[:message_fragment]
25
+ end
26
+
27
+ # Nil supports a predicate, string conversion, and inspection.
28
+ def test_nil_has_a_few_methods_defined_on_it
29
+ answers = Exercises::AboutNil.koans
30
+
31
+ assert_equal answers[:nil_predicate], nil.nil?
32
+ assert_equal answers[:string_value], nil.to_s
33
+ assert_equal answers[:inspected_value], nil.inspect
34
+ end
35
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ require ARGV.shift
8
+
9
+ # Observes object conversion, inspection, and identity.
10
+ class AboutObjectsTest < Minitest::Test
11
+ # These ordinary values, including nil and a class, are objects.
12
+ def test_everything_is_an_object
13
+ answers = Exercises::AboutObjects.koans
14
+
15
+ assert_equal answers[:integer_object], 1.is_a?(Object)
16
+ assert_equal answers[:float_object], 1.5.is_a?(Object)
17
+ assert_equal answers[:string_object], 'string'.is_a?(Object)
18
+ assert_equal answers[:nil_object], nil.is_a?(Object)
19
+ assert_equal answers[:class_object], Object.is_a?(Object)
20
+ end
21
+
22
+ # String conversion can produce an empty string.
23
+ def test_objects_can_be_converted_to_strings
24
+ answers = Exercises::AboutObjects.koans
25
+
26
+ assert_equal answers[:integer_string], 123.to_s
27
+ assert_equal answers[:nil_string], nil.to_s
28
+ end
29
+
30
+ # Inspection provides a diagnostic representation.
31
+ def test_objects_can_be_inspected
32
+ answers = Exercises::AboutObjects.koans
33
+
34
+ assert_equal answers[:integer_inspect], 123.inspect
35
+ assert_equal answers[:nil_inspect], nil.inspect
36
+ end
37
+
38
+ # An object identifier is an integer.
39
+ def test_every_object_has_an_id
40
+ obj = Object.new
41
+ answers = Exercises::AboutObjects.koans
42
+
43
+ assert_equal answers[:id_type], obj.object_id.class
44
+ end
45
+
46
+ # Two live objects have distinct identifiers.
47
+ def test_every_object_has_different_id
48
+ obj = Object.new
49
+ another_obj = Object.new
50
+ answers = Exercises::AboutObjects.koans
51
+
52
+ assert_equal answers[:distinct_ids], obj.object_id != another_obj.object_id # rubocop:disable Lint/IdentityComparison
53
+ end
54
+
55
+ # Observe the MRI representation of these small integers.
56
+ def test_small_integers_have_fixed_ids
57
+ answers = Exercises::AboutObjects.koans
58
+
59
+ assert_equal answers[:zero_id], 0.object_id
60
+ assert_equal answers[:one_id], 1.object_id
61
+ assert_equal answers[:two_id], 2.object_id
62
+ assert_equal answers[:hundred_id], 100.object_id
63
+ end
64
+
65
+ # Cloning a plain object creates a different object with a different ID.
66
+ def test_clone_creates_a_different_object
67
+ obj = Object.new
68
+ copy = obj.clone
69
+ answers = Exercises::AboutObjects.koans
70
+
71
+ assert_equal answers[:clone_unequal], obj != copy
72
+ assert_equal answers[:clone_distinct_id], obj.object_id != copy.object_id # rubocop:disable Lint/IdentityComparison
73
+ end
74
+ end