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,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
+ class AboutExtraCreditTest < Minitest::Test
10
+ # Entry requires 300 in one turn; after entry, smaller turns count too.
11
+ def test_entry_threshold_and_later_banking
12
+ player = Exercises::AboutExtraCredit::Player.new('Ruby')
13
+
14
+ assert_equal 0, player.bank(250)
15
+ assert_equal 300, player.bank(300)
16
+ assert_equal 350, player.bank(50)
17
+ end
18
+
19
+ # A zero-scoring roll forfeits this turn, but leaves earlier banked points intact.
20
+ def test_bust_discards_the_entire_turn
21
+ game = Exercises::AboutExtraCredit::Game.new(%w[Ruby Ada])
22
+
23
+ assert_equal 350, game.play_turn([[1, 5, 2, 3, 4], [2, 2, 2]])
24
+ assert_equal 0, game.play_turn([[2, 3, 4, 6, 2]])
25
+ assert_equal 350, game.play_turn([[1, 5, 2, 3, 4], [2, 3, 4]])
26
+ end
27
+
28
+ # All scoring dice allow five fresh dice; otherwise only non-scoring dice reroll.
29
+ def test_hot_dice_and_roll_validation
30
+ game = Exercises::AboutExtraCredit::Game.new(%w[Ruby Ada])
31
+
32
+ assert_equal 2400, game.play_turn([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1]])
33
+ assert_raises(ArgumentError) { game.play_turn([[1, 5, 2, 3, 4], [1, 1, 1, 1, 1]]) }
34
+ assert_raises(ArgumentError) { game.play_turn([[0, 1, 2, 3, 4]]) }
35
+ assert_raises(ArgumentError) { game.play_turn([[1.0, 1, 2, 3, 4]]) }
36
+ assert_raises(ArgumentError) { game.play_turn([]) }
37
+ assert_raises(ArgumentError) { game.play_turn([[2, 3, 4, 6, 2], [1, 1, 1, 1, 1]]) }
38
+ assert_equal 1, game.current
39
+ assert_equal [2400, 0], game.players.map(&:score)
40
+ end
41
+
42
+ # A leader starts one final round, even if a later player overtakes the leader.
43
+ def test_every_other_player_gets_one_final_turn
44
+ game = Exercises::AboutExtraCredit::Game.new(%w[Ruby Ada Matz])
45
+ all_ones = [1, 1, 1, 1, 1]
46
+
47
+ assert_equal 3600, game.play_turn([all_ones, all_ones, all_ones])
48
+ refute_predicate game, :finished?
49
+ assert_nil game.winner
50
+ assert_equal 4800, game.play_turn([all_ones, all_ones, all_ones, all_ones])
51
+ refute_predicate game, :finished?
52
+ assert_equal 0, game.play_turn([[2, 3, 4, 6, 2]])
53
+ assert_predicate game, :finished?
54
+ assert_equal 'Ada', game.winner.name
55
+ assert_raises(RuntimeError) { game.play_turn([all_ones]) }
56
+ assert_raises(ArgumentError) { Exercises::AboutExtraCredit::Game.new(['solo']) }
57
+ end
58
+
59
+ # Exactly 3000 starts the final round; the remaining turns wrap around the order.
60
+ def test_final_round_starts_at_3000_and_wraps_turn_order
61
+ game = Exercises::AboutExtraCredit::Game.new(%w[Ruby Ada Matz])
62
+ all_ones = [1, 1, 1, 1, 1]
63
+ threshold = [all_ones, all_ones, [6, 6, 6, 2, 3]]
64
+ game.play_turn([[2, 3, 4, 6, 2]])
65
+
66
+ assert_equal 3000, game.play_turn(threshold)
67
+ refute_predicate game, :finished?
68
+ assert_equal 0, game.play_turn([[2, 3, 4, 6, 2]])
69
+ refute_predicate game, :finished?
70
+ assert_equal 3000, game.play_turn(threshold)
71
+ assert_predicate game, :finished?
72
+ assert_equal 'Ruby', game.winner.name
73
+ end
74
+ end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Constructor and shared-default examples are deliberate observations.
4
+ # rubocop:disable Lint/SharedMutableDefault, Style/EmptyLiteral
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 AboutHashesTest < Minitest::Test
12
+ # Checks creating hashes.
13
+ def test_creating_hashes
14
+ empty_hash = Hash.new
15
+
16
+ assert_equal Exercises::AboutHashes.koans.fetch(:creating_hashes_one), empty_hash.class
17
+ assert_equal Exercises::AboutHashes.koans.fetch(:creating_hashes_two), empty_hash
18
+ assert_equal Exercises::AboutHashes.koans.fetch(:creating_hashes_three), empty_hash.size
19
+ end
20
+
21
+ # Checks hash literals.
22
+ def test_hash_literals
23
+ hash = { one: 'uno', two: 'dos' }
24
+
25
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_literals_one), hash.size
26
+ end
27
+
28
+ # Checks accessing hashes.
29
+ def test_accessing_hashes
30
+ hash = { one: 'uno', two: 'dos' }
31
+
32
+ assert_equal Exercises::AboutHashes.koans.fetch(:accessing_hashes_one), hash[:one]
33
+ assert_equal Exercises::AboutHashes.koans.fetch(:accessing_hashes_two), hash[:two]
34
+ assert_equal Exercises::AboutHashes.koans.fetch(:accessing_hashes_three), hash[:doesnt_exist]
35
+ end
36
+
37
+ # Checks accessing hashes with fetch.
38
+ def test_accessing_hashes_with_fetch
39
+ hash = { one: 'uno' }
40
+
41
+ assert_equal Exercises::AboutHashes.koans.fetch(:accessing_hashes_with_fetch_one), hash.fetch(:one)
42
+ assert_predicted_error(:accessing_hashes_with_fetch_two, ::KeyError) do
43
+ hash.fetch(:doesnt_exist)
44
+ end
45
+
46
+ # THINK ABOUT IT:
47
+ #
48
+ # Why might you want to use #fetch instead of #[] when accessing hash keys?
49
+ end
50
+
51
+ # Checks changing hashes.
52
+ def test_changing_hashes
53
+ hash = { one: 'uno', two: 'dos' }
54
+ hash[:one] = 'eins'
55
+
56
+ assert_equal Exercises::AboutHashes.koans.fetch(:changing_hashes_one), hash
57
+ end
58
+
59
+ # Checks hash is unordered.
60
+ def test_hash_is_unordered
61
+ hash1 = { one: 'uno', two: 'dos' }
62
+ hash2 = { two: 'dos', one: 'uno' }
63
+
64
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_is_unordered_one), (hash1 == hash2)
65
+ end
66
+
67
+ # Checks hash keys.
68
+ def test_hash_keys
69
+ hash = { one: 'uno', two: 'dos' }
70
+
71
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_keys_one), hash.keys.size
72
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_keys_two), hash.keys.include?(:one)
73
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_keys_three), hash.keys.include?(:two)
74
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_keys_four), hash.keys.class
75
+ end
76
+
77
+ # Checks hash values.
78
+ def test_hash_values
79
+ hash = { one: 'uno', two: 'dos' }
80
+
81
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_values_one), hash.values.size
82
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_values_two), hash.values.include?('uno')
83
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_values_three), hash.values.include?('dos')
84
+ assert_equal Exercises::AboutHashes.koans.fetch(:hash_values_four), hash.values.class
85
+ end
86
+
87
+ # Checks combining hashes.
88
+ def test_combining_hashes
89
+ hash = { 'jim' => 53, 'amy' => 20, 'dan' => 23 }
90
+ new_hash = hash.merge({ 'jim' => 54, 'jenny' => 26 })
91
+
92
+ assert_equal Exercises::AboutHashes.koans.fetch(:combining_hashes_one), (hash != new_hash)
93
+
94
+ expected = { 'jim' => 54, 'amy' => 20, 'dan' => 23, 'jenny' => 26 }
95
+
96
+ assert_equal Exercises::AboutHashes.koans.fetch(:combining_hashes_two), (expected == new_hash)
97
+ end
98
+
99
+ # Checks default value.
100
+ def test_default_value
101
+ hash1 = Hash.new
102
+ hash1[:one] = 1
103
+
104
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_one), hash1[:one]
105
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_two), hash1[:two]
106
+
107
+ hash2 = Hash.new('dos')
108
+ hash2[:one] = 1
109
+
110
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_three), hash2[:one]
111
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_four), hash2[:two]
112
+ end
113
+
114
+ # Checks default value is the same object.
115
+ def test_default_value_is_the_same_object
116
+ hash = Hash.new([])
117
+
118
+ hash[:one] << 'uno'
119
+ hash[:two] << 'dos'
120
+
121
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_is_the_same_object_one), hash[:one]
122
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_is_the_same_object_two), hash[:two]
123
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_is_the_same_object_three), hash[:three]
124
+
125
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_is_the_same_object_four),
126
+ hash[:one].equal?(hash[:two])
127
+ end
128
+
129
+ # Checks default value with block.
130
+ def test_default_value_with_block
131
+ hash = Hash.new { |hash, key| hash[key] = [] }
132
+
133
+ hash[:one] << 'uno'
134
+ hash[:two] << 'dos'
135
+
136
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_with_block_one), hash[:one]
137
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_with_block_two), hash[:two]
138
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_with_block_three), hash[:three]
139
+ end
140
+
141
+ # Checks default value attribute.
142
+ def test_default_value_attribute
143
+ hash = Hash.new
144
+
145
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_attribute_one), hash[:some_key]
146
+
147
+ hash.default = 'peanut'
148
+
149
+ assert_equal Exercises::AboutHashes.koans.fetch(:default_value_attribute_two), hash[:some_key]
150
+ end
151
+
152
+ # Checks the predicted exception class while returning the captured error.
153
+ # @param key [Symbol] answer field
154
+ # @param klass [Class<Exception>] exception raised by the example
155
+ # @return [Exception]
156
+ def assert_predicted_error(key, ...)
157
+ error = assert_raises(...)
158
+ assert_equal Exercises::AboutHashes.koans.fetch(key), error.class
159
+ error
160
+ end
161
+ end
162
+
163
+ # rubocop:enable Lint/SharedMutableDefault, Style/EmptyLiteral
@@ -0,0 +1,121 @@
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
+ class AboutInheritanceTest < Minitest::Test
9
+ class Dog
10
+ attr_reader :name
11
+
12
+ # Demonstrates initialize.
13
+ def initialize(name)
14
+ @name = name
15
+ end
16
+
17
+ # Demonstrates bark.
18
+ def bark
19
+ 'WOOF'
20
+ end
21
+ end
22
+
23
+ class Chihuahua < Dog
24
+ # Demonstrates wag.
25
+ def wag
26
+ :happy
27
+ end
28
+
29
+ # Demonstrates bark.
30
+ def bark
31
+ 'yip'
32
+ end
33
+ end
34
+
35
+ # Checks subclasses have the parent as an ancestor.
36
+ def test_subclasses_have_the_parent_as_an_ancestor
37
+ assert_equal Exercises::AboutInheritance.koans.fetch(:subclasses_have_the_parent_as_an_ancestor_one),
38
+ Chihuahua.ancestors.include?(Dog)
39
+ end
40
+
41
+ # Checks all classes ultimately inherit from object.
42
+ def test_all_classes_ultimately_inherit_from_object
43
+ assert_equal Exercises::AboutInheritance.koans.fetch(:all_classes_ultimately_inherit_from_object_one),
44
+ Chihuahua.ancestors.include?(Object)
45
+ end
46
+
47
+ # Checks subclasses inherit behavior from parent class.
48
+ def test_subclasses_inherit_behavior_from_parent_class
49
+ chico = Chihuahua.new('Chico')
50
+
51
+ assert_equal Exercises::AboutInheritance.koans.fetch(:subclasses_inherit_behavior_from_parent_class_one),
52
+ chico.name
53
+ end
54
+
55
+ # Checks subclasses add new behavior.
56
+ def test_subclasses_add_new_behavior
57
+ chico = Chihuahua.new('Chico')
58
+
59
+ assert_equal Exercises::AboutInheritance.koans.fetch(:subclasses_add_new_behavior_one), chico.wag
60
+
61
+ assert_predicted_error(:subclasses_add_new_behavior_two, ::NoMethodError) do
62
+ fido = Dog.new('Fido')
63
+ fido.wag
64
+ end
65
+ end
66
+
67
+ # Checks subclasses can modify existing behavior.
68
+ def test_subclasses_can_modify_existing_behavior
69
+ chico = Chihuahua.new('Chico')
70
+
71
+ assert_equal Exercises::AboutInheritance.koans.fetch(:subclasses_can_modify_existing_behavior_one), chico.bark
72
+
73
+ fido = Dog.new('Fido')
74
+
75
+ assert_equal Exercises::AboutInheritance.koans.fetch(:subclasses_can_modify_existing_behavior_two), fido.bark
76
+ end
77
+
78
+ # ------------------------------------------------------------------
79
+
80
+ class BullDog < Dog
81
+ # Demonstrates bark.
82
+ def bark
83
+ "#{super}, GROWL"
84
+ end
85
+ end
86
+
87
+ # Checks subclasses can invoke parent behavior via super.
88
+ def test_subclasses_can_invoke_parent_behavior_via_super
89
+ ralph = BullDog.new('Ralph')
90
+
91
+ assert_equal Exercises::AboutInheritance.koans.fetch(:subclasses_can_invoke_parent_behavior_via_super_one),
92
+ ralph.bark
93
+ end
94
+
95
+ # ------------------------------------------------------------------
96
+
97
+ class GreatDane < Dog
98
+ # Demonstrates growl.
99
+ def growl
100
+ "#{super.bark}, GROWL"
101
+ end
102
+ end
103
+
104
+ # Checks super does not work cross method.
105
+ def test_super_does_not_work_cross_method
106
+ george = GreatDane.new('George')
107
+ assert_predicted_error(:super_does_not_work_cross_method_one, ::NoMethodError) do
108
+ george.growl
109
+ end
110
+ end
111
+
112
+ # Checks the predicted exception class while returning the captured error.
113
+ # @param key [Symbol] answer field
114
+ # @param klass [Class<Exception>] exception raised by the example
115
+ # @return [Exception]
116
+ def assert_predicted_error(key, ...)
117
+ error = assert_raises(...)
118
+ assert_equal Exercises::AboutInheritance.koans.fetch(key), error.class
119
+ error
120
+ end
121
+ end
@@ -0,0 +1,148 @@
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
+ # Preserve the explicit block forms being taught.
8
+ # rubocop:disable Style/SymbolProc
9
+
10
+ require ARGV.shift
11
+ require 'tempfile'
12
+
13
+ class AboutIterationTest < Minitest::Test
14
+ # Checks each is a method on arrays.
15
+ def test_each_is_a_method_on_arrays
16
+ assert_equal Exercises::AboutIteration.koans.fetch(:each_is_a_method_on_arrays_one), [].methods.include?(:each)
17
+ end
18
+
19
+ # Checks iterating with each.
20
+ def test_iterating_with_each
21
+ array = [1, 2, 3]
22
+ sum = 0
23
+ array.each do |item|
24
+ sum += item
25
+ end
26
+
27
+ assert_equal Exercises::AboutIteration.koans.fetch(:iterating_with_each_one), sum
28
+ end
29
+
30
+ # Checks each can use curly brace blocks too.
31
+ def test_each_can_use_curly_brace_blocks_too
32
+ array = [1, 2, 3]
33
+ sum = 0
34
+ array.each { |item| sum += item }
35
+
36
+ assert_equal Exercises::AboutIteration.koans.fetch(:each_can_use_curly_brace_blocks_too_one), sum
37
+ end
38
+
39
+ # Checks break works with each style iterations.
40
+ def test_break_works_with_each_style_iterations
41
+ array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
42
+ sum = 0
43
+ array.each do |item|
44
+ break if item > 3
45
+
46
+ sum += item
47
+ end
48
+
49
+ assert_equal Exercises::AboutIteration.koans.fetch(:break_works_with_each_style_iterations_one), sum
50
+ end
51
+
52
+ # Checks collect transforms elements of an array.
53
+ def test_collect_transforms_elements_of_an_array
54
+ array = [1, 2, 3]
55
+ new_array = array.collect { |item| item + 10 }
56
+
57
+ assert_equal Exercises::AboutIteration.koans.fetch(:collect_transforms_elements_of_an_array_one), new_array
58
+
59
+ # NOTE: 'map' is another name for the 'collect' operation
60
+ another_array = array.map { |item| item + 10 }
61
+
62
+ assert_equal Exercises::AboutIteration.koans.fetch(:collect_transforms_elements_of_an_array_two), another_array
63
+ end
64
+
65
+ # Checks select selects certain items from an array.
66
+ def test_select_selects_certain_items_from_an_array
67
+ array = [1, 2, 3, 4, 5, 6]
68
+
69
+ even_numbers = array.select { |item| item.even? }
70
+
71
+ assert_equal Exercises::AboutIteration.koans.fetch(:select_selects_certain_items_from_an_array_one), even_numbers
72
+
73
+ # NOTE: 'find_all' is another name for the 'select' operation
74
+ more_even_numbers = array.find_all { |item| item.even? }
75
+
76
+ assert_equal Exercises::AboutIteration.koans.fetch(:select_selects_certain_items_from_an_array_two),
77
+ more_even_numbers
78
+ end
79
+
80
+ # Checks find locates the first element matching a criteria.
81
+ def test_find_locates_the_first_element_matching_a_criteria
82
+ array = %w[Jim Bill Clarence Doug Eli]
83
+
84
+ found = array.find { |item| item.size > 4 }
85
+
86
+ assert_equal Exercises::AboutIteration.koans.fetch(:find_locates_the_first_element_matching_a_criteria_one), found
87
+ end
88
+
89
+ # Checks inject will blow your mind.
90
+ def test_inject_will_blow_your_mind
91
+ result = [2, 3, 4].inject(0) { |sum, item| sum + item }
92
+
93
+ assert_equal Exercises::AboutIteration.koans.fetch(:inject_will_blow_your_mind_one), result
94
+
95
+ result2 = [2, 3, 4].inject(1) { |product, item| product * item }
96
+
97
+ assert_equal Exercises::AboutIteration.koans.fetch(:inject_will_blow_your_mind_two), result2
98
+
99
+ # Extra Credit:
100
+ # Describe in your own words what inject does.
101
+ end
102
+
103
+ # Checks all iteration methods work on any collection not just arrays.
104
+ def test_all_iteration_methods_work_on_any_collection_not_just_arrays
105
+ # Ranges act like a collection
106
+ result = (1..3).map { |item| item + 10 }
107
+
108
+ assert_equal Exercises::AboutIteration.koans.fetch(:all_iteration_methods_work_on_any_collection_not_just_arrays_one),
109
+ result
110
+
111
+ # Files act like a collection of lines
112
+ with_example_file do |file|
113
+ upcase_lines = file.map { |line| line.strip.upcase }
114
+
115
+ assert_equal Exercises::AboutIteration.koans.fetch(:all_iteration_methods_work_on_any_collection_not_just_arrays_two),
116
+ upcase_lines
117
+ end
118
+
119
+ # NOTE: You can create your own collections that work with each,
120
+ # map, select, etc.
121
+ end
122
+
123
+ # Bonus Question: In the previous koan, we saw the construct:
124
+ #
125
+ # File.open(filename) do |file|
126
+ # # code to read 'file'
127
+ # end
128
+ #
129
+ # Why did we do it that way instead of the following?
130
+ #
131
+ # file = File.open(filename)
132
+ # # code to read 'file'
133
+ #
134
+ # When you get to the "AboutSandwichCode" koan, recheck your answer.
135
+
136
+ # Supplies the original four-line example without relying on the working directory.
137
+ # @yieldparam file [File] rewound example file
138
+ # @return [Object] block result
139
+ def with_example_file
140
+ Tempfile.create('rkoans-iteration') do |file|
141
+ file.write("this\nis\na\ntest\n")
142
+ file.rewind
143
+ yield file
144
+ end
145
+ end
146
+ end
147
+
148
+ # rubocop:enable Style/SymbolProc
@@ -0,0 +1,80 @@
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
+ class AboutKeywordArgumentsTest < Minitest::Test
9
+ # Demonstrates method with keyword arguments.
10
+ def method_with_keyword_arguments(one: 1, two: 'two')
11
+ [one, two]
12
+ end
13
+
14
+ # Checks keyword arguments.
15
+ def test_keyword_arguments
16
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(:keyword_arguments_one),
17
+ method_with_keyword_arguments.class
18
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(:keyword_arguments_two), method_with_keyword_arguments
19
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(:keyword_arguments_three),
20
+ method_with_keyword_arguments(one: 'one')
21
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(:keyword_arguments_four),
22
+ method_with_keyword_arguments(two: 2)
23
+ end
24
+
25
+ # Demonstrates method with keyword arguments with mandatory argument.
26
+ def method_with_keyword_arguments_with_mandatory_argument(one, two: 2, three: 3)
27
+ [one, two, three]
28
+ end
29
+
30
+ # Checks keyword arguments with wrong number of arguments.
31
+ def test_keyword_arguments_with_wrong_number_of_arguments
32
+ exception = assert_predicted_error(:keyword_arguments_with_wrong_number_of_arguments_one, ::ArgumentError) do
33
+ method_with_keyword_arguments_with_mandatory_argument
34
+ end
35
+ assert_predicted_message(:keyword_arguments_with_wrong_number_of_arguments_two, exception.message)
36
+ end
37
+
38
+ # Demonstrates method with mandatory keyword arguments.
39
+ def method_with_mandatory_keyword_arguments(one:, two: 'two')
40
+ [one, two]
41
+ end
42
+
43
+ # Checks mandatory keyword arguments.
44
+ def test_mandatory_keyword_arguments
45
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(:mandatory_keyword_arguments_one),
46
+ method_with_mandatory_keyword_arguments(one: 'one')
47
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(:mandatory_keyword_arguments_two),
48
+ method_with_mandatory_keyword_arguments(two: 2, one: 1)
49
+ end
50
+
51
+ # Checks mandatory keyword arguments without mandatory argument.
52
+ def test_mandatory_keyword_arguments_without_mandatory_argument
53
+ exception = assert_predicted_error(:mandatory_keyword_arguments_without_mandatory_argument_one, ::ArgumentError) do
54
+ method_with_mandatory_keyword_arguments
55
+ end
56
+ assert_predicted_message(:mandatory_keyword_arguments_without_mandatory_argument_two, exception.message)
57
+ end
58
+
59
+ # Checks the predicted exception class while returning the captured error.
60
+ # @param key [Symbol] answer field
61
+ # @param klass [Class<Exception>] exception raised by the example
62
+ # @return [Exception]
63
+ def assert_predicted_error(key, ...)
64
+ error = assert_raises(...)
65
+ assert_equal Exercises::AboutKeywordArguments.koans.fetch(key), error.class
66
+ error
67
+ end
68
+
69
+ # Checks a nonempty literal fragment without depending on full diagnostic formatting.
70
+ # @param key [Symbol] answer field
71
+ # @param message [String] observed exception message
72
+ # @return [void]
73
+ def assert_predicted_message(key, message)
74
+ fragment = Exercises::AboutKeywordArguments.koans.fetch(key)
75
+
76
+ assert_kind_of String, fragment
77
+ refute_empty fragment
78
+ assert_includes message, fragment
79
+ end
80
+ end