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,89 @@
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
+ require 'tmpdir'
9
+
10
+ class AboutToStrTest < Minitest::Test
11
+ class CanNotBeTreatedAsString
12
+ # Demonstrates to s.
13
+ def to_s
14
+ 'non-string-like'
15
+ end
16
+ end
17
+
18
+ # Checks to s returns a string representation.
19
+ def test_to_s_returns_a_string_representation
20
+ not_like_a_string = CanNotBeTreatedAsString.new
21
+
22
+ assert_equal Exercises::AboutToStr.koans.fetch(:to_s_returns_a_string_representation_one), not_like_a_string.to_s
23
+ end
24
+
25
+ # Checks normally objects cannot be used where strings are expected.
26
+ def test_normally_objects_cannot_be_used_where_strings_are_expected
27
+ assert_predicted_error(:normally_objects_cannot_be_used_where_strings_are_expected_one, ::TypeError) do
28
+ File.exist?(CanNotBeTreatedAsString.new)
29
+ end
30
+ end
31
+
32
+ # ------------------------------------------------------------------
33
+
34
+ class CanBeTreatedAsString
35
+ # Demonstrates to s.
36
+ def to_s
37
+ 'string-like'
38
+ end
39
+
40
+ # Demonstrates to str.
41
+ def to_str
42
+ to_s
43
+ end
44
+ end
45
+
46
+ # Checks to str also returns a string representation.
47
+ def test_to_str_also_returns_a_string_representation
48
+ like_a_string = CanBeTreatedAsString.new
49
+
50
+ assert_equal Exercises::AboutToStr.koans.fetch(:to_str_also_returns_a_string_representation_one),
51
+ like_a_string.to_str
52
+ end
53
+
54
+ # Checks to str allows objects to be treated as strings.
55
+ def test_to_str_allows_objects_to_be_treated_as_strings
56
+ Dir.mktmpdir do |directory|
57
+ Dir.chdir(directory) do
58
+ assert_equal Exercises::AboutToStr.koans.fetch(:to_str_allows_objects_to_be_treated_as_strings_one),
59
+ File.exist?(CanBeTreatedAsString.new)
60
+ end
61
+ end
62
+ end
63
+
64
+ # ------------------------------------------------------------------
65
+
66
+ # Demonstrates acts like a string?.
67
+ def acts_like_a_string?(string)
68
+ string = string.to_str if string.respond_to?(:to_str)
69
+ string.is_a?(String)
70
+ end
71
+
72
+ # Checks user defined code can check for to str.
73
+ def test_user_defined_code_can_check_for_to_str
74
+ assert_equal Exercises::AboutToStr.koans.fetch(:user_defined_code_can_check_for_to_str_one),
75
+ acts_like_a_string?(CanNotBeTreatedAsString.new)
76
+ assert_equal Exercises::AboutToStr.koans.fetch(:user_defined_code_can_check_for_to_str_two),
77
+ acts_like_a_string?(CanBeTreatedAsString.new)
78
+ end
79
+
80
+ # Checks the predicted exception class while returning the captured error.
81
+ # @param key [Symbol] answer field
82
+ # @param klass [Class<Exception>] exception raised by the example
83
+ # @return [Exception]
84
+ def assert_predicted_error(key, ...)
85
+ error = assert_raises(...)
86
+ assert_equal Exercises::AboutToStr.koans.fetch(key), error.class
87
+ error
88
+ end
89
+ end
@@ -0,0 +1,29 @@
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
+ class AboutTriangleProjectTest < Minitest::Test
10
+ # All equal sides make an equilateral triangle, regardless of scale.
11
+ def test_equilateral_triangles_have_equal_sides
12
+ assert_equal :equilateral, Exercises::AboutTriangleProject.triangle(2, 2, 2)
13
+ assert_equal :equilateral, Exercises::AboutTriangleProject.triangle(10, 10, 10)
14
+ end
15
+
16
+ # The equal pair may appear in any positions.
17
+ def test_isosceles_triangles_have_exactly_two_sides_equal
18
+ [[3, 4, 4], [4, 3, 4], [4, 4, 3], [10, 10, 2]].each do |sides|
19
+ assert_equal :isosceles, Exercises::AboutTriangleProject.triangle(*sides)
20
+ end
21
+ end
22
+
23
+ # Distinct valid sides make a scalene triangle.
24
+ def test_scalene_triangles_have_no_equal_sides
25
+ [[3, 4, 5], [10, 11, 12], [5, 4, 2]].each do |sides|
26
+ assert_equal :scalene, Exercises::AboutTriangleProject.triangle(*sides)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
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
+ class AboutTriangleProjectTwoTest < Minitest::Test
10
+ # Reject nonpositive lengths and both sides of the triangle-inequality boundary.
11
+ def test_illegal_triangles_throw_exceptions
12
+ [[0, 0, 0], [3, 4, -5], [1, 1, 3], [2, 4, 2], [0, 1, 1]].each do |sides|
13
+ sides.permutation.to_a.uniq.each do |ordered|
14
+ assert_raises(Exercises::AboutTriangleProjectTwo::TriangleError) do
15
+ Exercises::AboutTriangleProjectTwo.triangle(*ordered)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ # Validation must preserve the classification behavior from part one.
22
+ def test_valid_triangles_keep_their_classification
23
+ assert_equal :equilateral, Exercises::AboutTriangleProjectTwo.triangle(2, 2, 2)
24
+ assert_equal :isosceles, Exercises::AboutTriangleProjectTwo.triangle(3, 4, 4)
25
+ assert_equal :scalene, Exercises::AboutTriangleProjectTwo.triangle(3, 4, 5)
26
+ assert_equal :isosceles, Exercises::AboutTriangleProjectTwo.triangle(1, 1, 1.5)
27
+ end
28
+ end
@@ -0,0 +1,43 @@
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
+ # Keeps the original truthiness examples and their independently evaluated branches.
10
+ class AboutTrueAndFalseTest < Minitest::Test
11
+ # @param condition [Object] value tested by Ruby's ordinary if statement
12
+ # @return [Symbol] branch selected by Ruby
13
+ def truth_value(condition)
14
+ if condition
15
+ :true_stuff
16
+ else
17
+ :false_stuff
18
+ end
19
+ end
20
+
21
+ # True selects the truthy branch.
22
+ def test_true_is_treated_as_true
23
+ assert_equal Exercises::AboutTrueAndFalse.koans[:true_value], truth_value(true)
24
+ end
25
+
26
+ # False selects the falsey branch.
27
+ def test_false_is_treated_as_false
28
+ assert_equal Exercises::AboutTrueAndFalse.koans[:false_value], truth_value(false)
29
+ end
30
+
31
+ # Nil selects the same branch as false.
32
+ def test_nil_is_treated_as_false_too
33
+ assert_equal Exercises::AboutTrueAndFalse.koans[:nil_value], truth_value(nil)
34
+ end
35
+
36
+ # Zero and empty containers are truthy, just like other ordinary objects.
37
+ def test_everything_else_is_treated_as_true
38
+ values = { one: 1, zero: 0, empty_array: [], empty_hash: {}, string: 'Strings', empty_string: '' }
39
+ answers = Exercises::AboutTrueAndFalse.koans
40
+
41
+ values.each { |key, value| assert_equal answers[key], truth_value(value), "Branch for #{key}" }
42
+ end
43
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+
5
+ # Checks the learner's sequence and the block invocation contract.
6
+ class BlocksAndMethodsTest < Minitest::Test
7
+ def test_block_koan
8
+ assert_equal [1, 2, 3], Exercises::BlocksAndMethods.koans[:sequence]
9
+ end
10
+
11
+ def test_apply_block
12
+ count = 0
13
+ result = Exercises::BlocksAndMethods.apply(5) do |number|
14
+ count += 1
15
+ number * 3
16
+ end
17
+
18
+ assert_equal 15, result
19
+ assert_equal 1, count
20
+ assert_raises(LocalJumpError) { Exercises::BlocksAndMethods.apply(5) }
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The examples contrast block forms and their behavior.
4
+ # rubocop:disable Style/BlockDelimiters
5
+
6
+ require ARGV.shift
7
+ class ClassStateTest < Minitest::Test
8
+ # Checks independent class instance state.
9
+ def test_independent_class_instance_state
10
+ Exercises::ClassState::Parent.reset
11
+ Exercises::ClassState::Child.reset
12
+ 2.times {
13
+ Exercises::ClassState::Parent.increment
14
+ }
15
+
16
+ Exercises::ClassState::Child.increment
17
+
18
+ assert_equal 2, Exercises::ClassState::Parent.count
19
+ assert_equal 1, Exercises::ClassState::Child.count
20
+ end
21
+
22
+ # Checks class inheritance and singleton.
23
+ def test_class_inheritance_and_singleton
24
+ assert_equal 'parent-child', Exercises::ClassState::Child.label
25
+ assert_equal Exercises::ClassState::Parent.singleton_class, Exercises::ClassState.singleton_owner
26
+ end
27
+ end
28
+
29
+ # rubocop:enable Style/BlockDelimiters
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The examples contrast block forms and their behavior.
4
+ # rubocop:disable Style/BlockDelimiters
5
+
6
+ require ARGV.shift
7
+ class ClosureCaptureTest < Minitest::Test
8
+ # Checks separate captures.
9
+ def test_separate_captures
10
+ functions = Exercises::ClosureCapture.multipliers([2, 3, 4])
11
+
12
+ assert_equal([10, 15, 20], functions.map { |f|
13
+ f.call(5)
14
+ })
15
+ end
16
+
17
+ # Checks lambda contract.
18
+ def test_lambda_contract
19
+ f = Exercises::ClosureCapture.multipliers([2]).first
20
+
21
+ assert_predicate f, :lambda?
22
+ assert_raises(ArgumentError) {
23
+ f.call(5, 6)
24
+ }
25
+ assert_equal [], Exercises::ClosureCapture.multipliers([])
26
+ end
27
+ end
28
+
29
+ # rubocop:enable Style/BlockDelimiters
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+
5
+ # Checks the learner's expectations and the double_odds contract.
6
+ class CollectionBasicsTest < Minitest::Test
7
+ def test_collection_koans
8
+ assert_equal({ mapped: [2, 4, 6], selected: [1, 3] }, Exercises::CollectionBasics.koans)
9
+ end
10
+
11
+ def test_double_odds
12
+ input = [1, 2, 3]
13
+
14
+ assert_equal [2, 6], Exercises::CollectionBasics.double_odds(input)
15
+ assert_equal [1, 2, 3], input
16
+ assert_empty Exercises::CollectionBasics.double_odds([])
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class ConstantScopeTest < Minitest::Test
5
+ # Checks scope predictions.
6
+ def test_scope_predictions
7
+ assert_equal({ lexical_label: 'item', shared_class_count: 1, new_block_local_visible: false }, Exercises::ConstantScope.predictions)
8
+ end
9
+
10
+ # Checks local closure state.
11
+ def test_local_closure_state
12
+ a = Exercises::ConstantScope.counter
13
+
14
+ b = Exercises::ConstantScope.counter
15
+
16
+ assert_equal [1, 2, 1], [a.call, a.call, b.call]
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The examples contrast block forms and their behavior.
4
+ # rubocop:disable Style/BlockDelimiters
5
+
6
+ require ARGV.shift
7
+ class CoreProtocolsTest < Minitest::Test
8
+ # Checks enumerable protocol.
9
+ def test_enumerable_protocol
10
+ p = Exercises::CoreProtocols::Packet.new([2, 3]); assert_equal([4, 6], p.map { |n|
11
+ n * 2
12
+ })
13
+ assert_equal [2, 3], p.each.to_a
14
+ assert_equal [true, true], Exercises::CoreProtocols.protocol(p)
15
+ end
16
+
17
+ # Checks comparable and conversion.
18
+ def test_comparable_and_conversion
19
+ a = Exercises::CoreProtocols::Packet.new([1])
20
+ b = Exercises::CoreProtocols::Packet.new([2, 3])
21
+
22
+ assert_operator a, :<, b
23
+ assert_equal 'Packet(5)', b.to_s
24
+ assert_equal [a, b], [b, a].sort
25
+ end
26
+ end
27
+
28
+ # rubocop:enable Style/BlockDelimiters
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class DelegationTest < Minitest::Test
5
+ # Checks delegation receiver.
6
+ def test_delegation_receiver
7
+ items = []
8
+ box = Exercises::Delegation::Mailbox.new(items)
9
+
10
+ assert_same items, box.push('ruby')
11
+ assert_equal ['ruby'], items
12
+ assert_equal 1, box.size
13
+ end
14
+
15
+ # Checks live receiver.
16
+ def test_live_receiver
17
+ items = []
18
+ box = Exercises::Delegation::Mailbox.new(items)
19
+ items << 'rails'
20
+
21
+ assert_equal 1, box.size
22
+ end
23
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class DynamicMethodsTest < Minitest::Test
5
+ # Checks defined reader closures.
6
+ def test_defined_reader_closures
7
+ klass = Exercises::DynamicMethods.readers(%i[left right])
8
+ obj = klass.new
9
+
10
+ obj.instance_variable_set(:@left, 10)
11
+ obj.instance_variable_set(:@right, 20)
12
+
13
+ assert_equal [10, 20], [obj.left, obj.right]
14
+ end
15
+
16
+ # Checks eval binding and reflection.
17
+ def test_eval_binding_and_reflection
18
+ assert_equal 8, Exercises::DynamicMethods.evaluate(4)
19
+ obj = Object.new
20
+
21
+ obj.instance_variable_set(:@token, :ruby)
22
+
23
+ assert_equal :ruby, Exercises::DynamicMethods.instance_value(obj, :token)
24
+ klass = Exercises::DynamicMethods.readers([])
25
+
26
+ assert_equal klass, Exercises::DynamicMethods.class_value(klass)
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class ExceptionFlowTest < Minitest::Test
5
+ # Checks ensure and else.
6
+ def test_ensure_and_else
7
+ assert_equal %w[work else ensure], Exercises::ExceptionFlow.trace(fail: false)
8
+
9
+ assert_equal %w[work rescue ensure], Exercises::ExceptionFlow.trace(fail: true)
10
+ end
11
+
12
+ # Checks reraise.
13
+ def test_reraise
14
+ error = assert_raises(ArgumentError) { Exercises::ExceptionFlow.reraises }
15
+ assert_equal 'original', error.message
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+
5
+ # Checks exact output bytes without deriving expectations from the learner's code.
6
+ class HeredocLayoutTest < Minitest::Test
7
+ # Common indentation is stripped; relative spaces and newlines remain intact.
8
+ def test_squiggly_indentation
9
+ assert_equal "Hello Ada\n Ruby\n", Exercises::HeredocLayout.render('Ada')
10
+ assert_equal "Hello Bea\n Ruby\n", Exercises::HeredocLayout.render('Bea')
11
+ assert_equal "Hello \n Ruby\n", Exercises::HeredocLayout.render('')
12
+ end
13
+
14
+ # Quoting the delimiter prevents interpolation without dropping the final newline.
15
+ def test_quoted_heredoc
16
+ assert_equal "Hello \#{name}\n", Exercises::HeredocLayout.literal
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Explicit callable arguments demonstrate block and proc behavior.
4
+ # rubocop:disable Style/SymbolProc
5
+
6
+ require ARGV.shift
7
+ class KeywordForwardingTest < Minitest::Test
8
+ # Checks keyword and block.
9
+ def test_keyword_and_block
10
+ assert_equal 'RUBY!', Exercises::KeywordForwarding.forward('ruby', suffix: '!') { |v|
11
+ v.upcase
12
+ }
13
+ assert_equal 'ruby?', Exercises::KeywordForwarding.forward('ruby')
14
+ end
15
+
16
+ # Checks positional hash.
17
+ def test_positional_hash
18
+ assert_equal 'rails!', Exercises::KeywordForwarding.forward({ name: 'rails' }, suffix: '!') { |payload| payload.fetch(:name) }
19
+ end
20
+ end
21
+
22
+ # rubocop:enable Style/SymbolProc
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class LazyEnumerationTest < Minitest::Test
5
+ # Checks lazy limit.
6
+ def test_lazy_limit
7
+ assert_equal [7, 14], Exercises::LazyEnumeration.first_multiples(2)
8
+ assert_equal [7, 14, 21, 28], Exercises::LazyEnumeration.first_multiples(4)
9
+ end
10
+
11
+ # Checks empty limit.
12
+ def test_empty_limit
13
+ assert_equal [], Exercises::LazyEnumeration.first_multiples(0)
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class LiteralsAndOperatorsTest < Minitest::Test
5
+ # Checks literals and precedence.
6
+ def test_literals_and_precedence
7
+ assert_equal({
8
+ zero_truthy: true,
9
+ integer_division: 2,
10
+ float_division: 2.5,
11
+ precedence: 7,
12
+ not_nil: true,
13
+ words: %w[ruby rails],
14
+ range: [1, 2, 3]
15
+ }, Exercises::LiteralsAndOperators.predictions)
16
+ end
17
+
18
+ # Checks short circuit default.
19
+ def test_short_circuit_default
20
+ assert_equal false, Exercises::LiteralsAndOperators.default_for_nil(false) # rubocop:disable Minitest/RefuteFalse
21
+
22
+ assert_equal 0, Exercises::LiteralsAndOperators.default_for_nil(0)
23
+ assert_equal 'missing', Exercises::LiteralsAndOperators.default_for_nil(nil)
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The original descriptive check identifiers and example strings remain intact.
4
+ # The examples contrast block forms and their behavior.
5
+ # Explicit callable arguments demonstrate block and proc behavior.
6
+ # rubocop:disable Layout/LineLength, Style/BlockDelimiters, Style/SymbolProc
7
+
8
+ require ARGV.shift
9
+ class MethodContractsTest < Minitest::Test
10
+ # Checks method defaults and block.
11
+ def test_method_defaults_and_block
12
+ assert_equal 'tea:1:box:0:normal', Exercises::MethodContracts.format_order('tea', unit: 'box')
13
+ assert_equal 'TEA:2:BOX:1:HIGH', Exercises::MethodContracts.format_order('tea', 2, :gift, unit: 'box', priority: 'high') { |v|
14
+ v.upcase
15
+ }
16
+ end
17
+
18
+ # Checks parameter metadata.
19
+ def test_parameter_metadata
20
+ assert_equal [%i[req name], %i[opt quantity], %i[rest extras], %i[keyreq unit], %i[keyrest options], %i[block block]],
21
+ Exercises::MethodContracts.parameters
22
+ assert_raises(ArgumentError) {
23
+ Exercises::MethodContracts.format_order('tea')
24
+ }
25
+ end
26
+ end
27
+
28
+ # rubocop:enable Layout/LineLength, Style/BlockDelimiters, Style/SymbolProc
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class MethodLookupTest < Minitest::Test
5
+ # Checks prepend wrapper.
6
+ def test_prepend_wrapper
7
+ assert_equal '[base]', Exercises::MethodLookup::Presenter.new.call
8
+ end
9
+
10
+ # Checks ancestor order.
11
+ def test_ancestor_order
12
+ assert_equal ['Exercises::MethodLookup::Wrapper', 'Exercises::MethodLookup::Presenter'], Exercises::MethodLookup.lookup
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class NonlocalExitTest < Minitest::Test
5
+ # Checks lambda return scope.
6
+ def test_lambda_return_scope
7
+ assert_equal %w[inside after], Exercises::NonlocalExit.lambda_trace
8
+ end
9
+
10
+ # Checks proc nonlocal return.
11
+ def test_proc_nonlocal_return
12
+ assert_raises(LocalJumpError) { Exercises::NonlocalExit.escaped_proc.call }
13
+ end
14
+
15
+ # Checks catch throw and next.
16
+ def test_catch_throw_and_next
17
+ assert_equal 4, Exercises::NonlocalExit.find_even([[1, 3], [4, 6]])
18
+ assert_nil Exercises::NonlocalExit.find_even([[1], [3]])
19
+
20
+ assert_equal [2, 4], Exercises::NonlocalExit.skip_odds([1, 2, 3, 4])
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class NumberedParametersTest < Minitest::Test
5
+ # Checks numbered pair input.
6
+ def test_numbered_pair_input
7
+ assert_equal [5, 9], Exercises::NumberedParameters.pair_sums([[2, 3], [4, 5]])
8
+ assert_equal [], Exercises::NumberedParameters.pair_sums([])
9
+ end
10
+
11
+ # Checks numbered syntax.
12
+ def test_numbered_syntax
13
+ assert_equal({ explicit_and_numbered: false, numbered_pair: true }, Exercises::NumberedParameters.predictions)
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class NumericPrecisionTest < Minitest::Test
5
+ # Checks numeric division.
6
+ def test_numeric_division
7
+ result = Exercises::NumericPrecision.ratios(1, 3)
8
+
9
+ assert_instance_of Integer, result[:integer]
10
+ assert_equal 0, result[:integer]
11
+ assert_instance_of Float, result[:floating]
12
+ assert_in_delta 1.0 / 3, result[:floating], 1e-12
13
+ assert_instance_of Rational, result[:rational]
14
+ assert_equal Rational(4, 3), result[:rational] + 1
15
+ end
16
+
17
+ # Checks complex product.
18
+ def test_complex_product
19
+ product = Exercises::NumericPrecision.imaginary_product(2, 3)
20
+
21
+ assert_instance_of Complex, product
22
+ assert_equal Complex(-6, 0), product
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class PatternMatchingTest < Minitest::Test
5
+ # Checks pinned kind.
6
+ def test_pinned_kind
7
+ assert_equal 5, Exercises::PatternMatching.amount({ type: 'sale', amount: 5, extra: true }, 'sale')
8
+ assert_nil Exercises::PatternMatching.amount({ type: 'refund', amount: 5 }, 'sale')
9
+ end
10
+
11
+ # Checks pattern guard.
12
+ def test_pattern_guard
13
+ assert_nil Exercises::PatternMatching.amount({ type: 'sale', amount: 0 }, 'sale')
14
+
15
+ assert_nil Exercises::PatternMatching.amount({ type: 'sale', amount: '5' }, 'sale')
16
+ assert_nil Exercises::PatternMatching.amount({}, 'sale')
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class RefinementScopeTest < Minitest::Test
5
+ # Checks lexical refinement.
6
+ def test_lexical_refinement
7
+ assert_equal 'local', Exercises::RefinementScope::Local.call
8
+ end
9
+
10
+ # Checks outside unchanged.
11
+ def test_outside_unchanged
12
+ assert_equal 'plain', Exercises::RefinementScope.outside
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require ARGV.shift
4
+ class RegexpCapturesTest < Minitest::Test
5
+ # Checks whole string and captures.
6
+ def test_whole_string_and_captures
7
+ parsed = Exercises::RegexpCaptures.parse('ruby:42')
8
+
9
+ assert_equal({ name: 'ruby', id: 42 }, parsed)
10
+ assert_instance_of Integer, parsed.fetch(:id)
11
+ assert_nil Exercises::RegexpCaptures.parse("ruby:42\n")
12
+ assert_nil Exercises::RegexpCaptures.parse('ruby:x')
13
+ end
14
+
15
+ # Checks match without global capture change.
16
+ def test_match_without_global_capture_change
17
+ assert_equal ['old', true], Exercises::RegexpCaptures.probe('ruby')
18
+ assert_equal ['old', false], Exercises::RegexpCaptures.probe('rails')
19
+ end
20
+ end