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,60 @@
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 AboutOpenClassesTest < Minitest::Test
9
+ class Dog
10
+ # Demonstrates bark.
11
+ def bark
12
+ 'WOOF'
13
+ end
14
+ end
15
+
16
+ # Checks as defined dogs do bark.
17
+ def test_as_defined_dogs_do_bark
18
+ fido = Dog.new
19
+
20
+ assert_equal Exercises::AboutOpenClasses.koans.fetch(:as_defined_dogs_do_bark_one), fido.bark
21
+ end
22
+
23
+ # ------------------------------------------------------------------
24
+
25
+ # Open the existing Dog class and add a new method.
26
+ class Dog
27
+ # Demonstrates wag.
28
+ def wag
29
+ 'HAPPY'
30
+ end
31
+ end
32
+
33
+ # Checks after reopening dogs can both wag and bark.
34
+ def test_after_reopening_dogs_can_both_wag_and_bark
35
+ fido = Dog.new
36
+
37
+ assert_equal Exercises::AboutOpenClasses.koans.fetch(:after_reopening_dogs_can_both_wag_and_bark_one), fido.wag
38
+ assert_equal Exercises::AboutOpenClasses.koans.fetch(:after_reopening_dogs_can_both_wag_and_bark_two), fido.bark
39
+ end
40
+
41
+ # ------------------------------------------------------------------
42
+
43
+ class ::Integer
44
+ # Demonstrates answer to life universe and everything?.
45
+ def answer_to_life_universe_and_everything?
46
+ self == 42
47
+ end
48
+ end
49
+
50
+ # Checks even existing built in classes can be reopened.
51
+ def test_even_existing_built_in_classes_can_be_reopened
52
+ assert_equal Exercises::AboutOpenClasses.koans.fetch(:even_existing_built_in_classes_can_be_reopened_one),
53
+ 1.answer_to_life_universe_and_everything?
54
+ assert_equal Exercises::AboutOpenClasses.koans.fetch(:even_existing_built_in_classes_can_be_reopened_two),
55
+ 42.answer_to_life_universe_and_everything?
56
+ end
57
+
58
+ # NOTE: To understand why we need the :: before Integer, you need to
59
+ # become enlightened about scope.
60
+ end
@@ -0,0 +1,257 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Literal conditions isolate the control-flow behavior being predicted.
4
+ # The example demonstrates that an unpinned variable pattern always binds the subject.
5
+ # Keep the related original chapter examples together.
6
+ # rubocop:disable Lint/LiteralAsCondition, Lint/UnreachablePatternBranch, Metrics/ClassLength
7
+
8
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
9
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
10
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
11
+
12
+ require ARGV.shift
13
+ class AboutPatternMatchingTest < Minitest::Test
14
+ # Checks pattern may not match.
15
+ def test_pattern_may_not_match
16
+ case [true, false]
17
+ in [a, b] if a == b # The condition after pattern is called guard.
18
+ :match
19
+ end
20
+ rescue NoMatchingPatternError => e
21
+ # What exception has been caught?
22
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:pattern_may_not_match_one), (e.class)
23
+ end
24
+
25
+ # Checks we can use else.
26
+ def test_we_can_use_else
27
+ result = case [true, false]
28
+ in [a, b] if a == b
29
+ :match
30
+ else
31
+ :no_match
32
+ end
33
+
34
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:we_can_use_else_one), result
35
+ end
36
+
37
+ # ------------------------------------------------------------------
38
+
39
+ # Demonstrates value pattern.
40
+ def value_pattern(variable)
41
+ case variable
42
+ in 0
43
+ :match_exact_value
44
+ in 1..10
45
+ :match_in_range
46
+ in Integer
47
+ :match_with_class
48
+ else
49
+ :no_match
50
+ end
51
+ end
52
+
53
+ # Checks value pattern.
54
+ def test_value_pattern
55
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:value_pattern_one), value_pattern(0)
56
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:value_pattern_two), value_pattern(5)
57
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:value_pattern_three), value_pattern(100)
58
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:value_pattern_four), value_pattern('Not a Number!')
59
+ end
60
+
61
+ # ------------------------------------------------------------------
62
+ # This pattern will bind variable to the value
63
+
64
+ # Demonstrates variable pattern with binding.
65
+ def variable_pattern_with_binding(variable)
66
+ case 0
67
+ in variable
68
+ variable
69
+ else
70
+ :no_match
71
+ end
72
+ end
73
+
74
+ # Checks variable pattern with binding.
75
+ def test_variable_pattern_with_binding
76
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:variable_pattern_with_binding_one),
77
+ variable_pattern_with_binding(1)
78
+ end
79
+
80
+ # ------------------------------------------------------------------
81
+
82
+ # We can pin the value of the variable with ^
83
+
84
+ # Demonstrates variable pattern with pin.
85
+ def variable_pattern_with_pin(variable)
86
+ case 0
87
+ in ^variable
88
+ variable
89
+ else
90
+ :no_match
91
+ end
92
+ end
93
+
94
+ # Checks variable pattern with pin.
95
+ def test_variable_pattern_with_pin
96
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:variable_pattern_with_pin_one),
97
+ variable_pattern_with_pin(1)
98
+ end
99
+
100
+ # ------------------------------------------------------------------
101
+
102
+ # We can drop values from pattern
103
+
104
+ # Demonstrates pattern with dropping.
105
+ def pattern_with_dropping(variable)
106
+ case variable
107
+ in [_, 2]
108
+ :match
109
+ else
110
+ :no_match
111
+ end
112
+ end
113
+
114
+ # Checks pattern with dropping.
115
+ def test_pattern_with_dropping
116
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:pattern_with_dropping_one),
117
+ pattern_with_dropping(['I will not be checked', 2])
118
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:pattern_with_dropping_two),
119
+ pattern_with_dropping(['I will not be checked', 'But I will!'])
120
+ end
121
+
122
+ # ------------------------------------------------------------------
123
+
124
+ # We can use logical *or* in patterns
125
+
126
+ # Demonstrates alternative pattern.
127
+ def alternative_pattern(variable)
128
+ case variable
129
+ in 0 | false | nil
130
+ :match
131
+ else
132
+ :no_match
133
+ end
134
+ end
135
+
136
+ # Checks alternative pattern.
137
+ def test_alternative_pattern
138
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:alternative_pattern_one), alternative_pattern(0)
139
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:alternative_pattern_two), alternative_pattern(false)
140
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:alternative_pattern_three), alternative_pattern(nil)
141
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:alternative_pattern_four), alternative_pattern(4)
142
+ end
143
+
144
+ # ------------------------------------------------------------------
145
+
146
+ # As pattern binds the variable to the value if pattern matches
147
+ # pat: pat => var
148
+
149
+ # Demonstrates as pattern.
150
+ def as_pattern
151
+ a = 'First I was afraid'
152
+
153
+ case 'I was petrified'
154
+ in String => a
155
+ a
156
+ else
157
+ :no_match
158
+ end
159
+ end
160
+
161
+ # Checks as pattern.
162
+ def test_as_pattern
163
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:as_pattern_one), as_pattern
164
+ end
165
+
166
+ # ------------------------------------------------------------------
167
+
168
+ # Array pattern works with all objects that have #deconstruct method that returns Array
169
+ # It is useful to cut needed parts from Array-ish objects
170
+
171
+ class Deconstructible
172
+ # Demonstrates initialize.
173
+ def initialize(str)
174
+ @data = str
175
+ end
176
+
177
+ # Demonstrates deconstruct.
178
+ def deconstruct
179
+ @data&.chars
180
+ end
181
+ end
182
+
183
+ # Demonstrates array pattern.
184
+ def array_pattern(deconstructible)
185
+ case deconstructible
186
+ in 'a', *res, 'd'
187
+ res
188
+ else
189
+ :no_match
190
+ end
191
+ end
192
+
193
+ # Checks array pattern.
194
+ def test_array_pattern
195
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:array_pattern_one),
196
+ array_pattern(Deconstructible.new('abcd'))
197
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:array_pattern_two),
198
+ array_pattern(Deconstructible.new('123'))
199
+ end
200
+
201
+ # ------------------------------------------------------------------
202
+
203
+ # Hash pattern is quite the same as Array pattern, but it expects #deconsturct_keys(keys) method
204
+ # It works with symbol keys for now
205
+
206
+ class LetterAccountant
207
+ # Demonstrates initialize.
208
+ def initialize(str)
209
+ @data = str
210
+ end
211
+
212
+ # Demonstrates deconstruct keys.
213
+ def deconstruct_keys(keys)
214
+ # we will count number of occurrences of each key in our data
215
+ keys.to_h { |key| [key, @data.count(key.to_s)] }
216
+ end
217
+ end
218
+
219
+ # Demonstrates hash pattern.
220
+ def hash_pattern(deconstructible_as_hash)
221
+ case deconstructible_as_hash
222
+ in { a: a, b: b }
223
+ [a, b]
224
+ else
225
+ :no_match
226
+ end
227
+ end
228
+
229
+ # Checks hash pattern.
230
+ def test_hash_pattern
231
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:hash_pattern_one),
232
+ hash_pattern(LetterAccountant.new('aaabbc'))
233
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:hash_pattern_two),
234
+ hash_pattern(LetterAccountant.new('xyz'))
235
+ end
236
+
237
+ # we can write it even shorter
238
+ # Demonstrates hash pattern with sugar.
239
+ def hash_pattern_with_sugar(deconstructible_as_hash)
240
+ case deconstructible_as_hash
241
+ in a:, b:
242
+ [a, b]
243
+ else
244
+ :no_match
245
+ end
246
+ end
247
+
248
+ # Checks hash pattern with sugar.
249
+ def test_hash_pattern_with_sugar
250
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:hash_pattern_with_sugar_one),
251
+ hash_pattern_with_sugar(LetterAccountant.new('aaabbc'))
252
+ assert_equal Exercises::AboutPatternMatching.koans.fetch(:hash_pattern_with_sugar_two),
253
+ hash_pattern_with_sugar(LetterAccountant.new('xyz'))
254
+ end
255
+ end
256
+
257
+ # rubocop:enable Lint/LiteralAsCondition, Lint/UnreachablePatternBranch, Metrics/ClassLength
@@ -0,0 +1,75 @@
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 AboutProxyObjectProjectTest < Minitest::Test
10
+ # A receiver with state, arguments, keywords and a block.
11
+ class Television
12
+ attr_accessor :channel
13
+
14
+ # Toggle the current power state.
15
+ def power
16
+ @on = !@on
17
+ end
18
+
19
+ # @return [Boolean] current power state
20
+ def on?
21
+ !!@on
22
+ end
23
+
24
+ # Yield a formatted payload, keeping positional and keyword arguments distinct.
25
+ def broadcast(message, suffix: '!')
26
+ text = "#{message}#{suffix}"
27
+ block_given? ? yield(text) : text
28
+ end
29
+
30
+ private
31
+
32
+ # Private target behavior must stay inaccessible through the proxy.
33
+ def secret
34
+ :private
35
+ end
36
+ end
37
+
38
+ # State changes and exact message order must reach the real target.
39
+ def test_tv_methods_and_recorded_messages
40
+ tv = Exercises::AboutProxyObjectProject::Proxy.new(Television.new)
41
+ tv.power
42
+ tv.channel = 10
43
+
44
+ assert_equal %i[power channel=], tv.messages
45
+ assert_equal 10, tv.channel
46
+ assert_predicate tv, :on?
47
+ tv.power
48
+
49
+ assert tv.called?(:power)
50
+ refute tv.called?(:unseen)
51
+ assert_equal 2, tv.number_of_times_called(:power)
52
+ assert_equal 0, tv.number_of_times_called(:unseen)
53
+ assert_respond_to tv, :channel
54
+ refute_respond_to tv, :no_such_method
55
+ assert_raises(NoMethodError) { tv.no_such_method }
56
+ refute_respond_to tv, :secret
57
+ assert_raises(NoMethodError) { tv.secret }
58
+ end
59
+
60
+ # A proxy must work with other targets and propagate return values.
61
+ def test_string_target_and_return_values
62
+ proxy = Exercises::AboutProxyObjectProject::Proxy.new(+'Code Mash 2009')
63
+ proxy.upcase!
64
+
65
+ assert_equal %w[CODE MASH 2009], proxy.split
66
+ assert_equal %i[upcase! split], proxy.messages
67
+ end
68
+
69
+ # Forward keywords and the caller's block without treating keywords as a hash.
70
+ def test_keywords_and_blocks_reach_the_target
71
+ proxy = Exercises::AboutProxyObjectProject::Proxy.new(Television.new)
72
+
73
+ assert_equal 'RUBY?', proxy.broadcast('ruby', suffix: '?', &:upcase)
74
+ end
75
+ end
@@ -0,0 +1,243 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The original descriptive check identifiers and example strings remain intact.
4
+ # Keep the related original chapter examples together.
5
+ # The examples contrast block forms and their behavior.
6
+ # The examples explicitly demonstrate numbered regular-expression capture variables.
7
+ # rubocop:disable Layout/LineLength, Metrics/ClassLength, Style/BlockDelimiters, Style/PerlBackrefs
8
+
9
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
10
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
11
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
12
+
13
+ require ARGV.shift
14
+
15
+ class AboutRegularExpressionsTest < Minitest::Test
16
+ # Checks a pattern is a regular expression.
17
+ def test_a_pattern_is_a_regular_expression
18
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_pattern_is_a_regular_expression_one),
19
+ /pattern/.class
20
+ end
21
+
22
+ # Checks a regexp can search a string for matching content.
23
+ def test_a_regexp_can_search_a_string_for_matching_content
24
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_regexp_can_search_a_string_for_matching_content_one),
25
+ 'some matching content'[/match/]
26
+ end
27
+
28
+ # Checks a failed match returns nil.
29
+ def test_a_failed_match_returns_nil
30
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_failed_match_returns_nil_one),
31
+ 'some matching content'[/missing/]
32
+ end
33
+
34
+ # ------------------------------------------------------------------
35
+
36
+ # Checks question mark means optional.
37
+ def test_question_mark_means_optional
38
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:question_mark_means_optional_one),
39
+ 'abbcccddddeeeee'[/ab?/]
40
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:question_mark_means_optional_two),
41
+ 'abbcccddddeeeee'[/az?/]
42
+ end
43
+
44
+ # Checks plus means one or more.
45
+ def test_plus_means_one_or_more
46
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:plus_means_one_or_more_one), 'abbcccddddeeeee'[/bc+/]
47
+ end
48
+
49
+ # Checks asterisk means zero or more.
50
+ def test_asterisk_means_zero_or_more
51
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:asterisk_means_zero_or_more_one),
52
+ 'abbcccddddeeeee'[/ab*/]
53
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:asterisk_means_zero_or_more_two),
54
+ 'abbcccddddeeeee'[/az*/]
55
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:asterisk_means_zero_or_more_three),
56
+ 'abbcccddddeeeee'[/z*/]
57
+
58
+ # THINK ABOUT IT:
59
+ #
60
+ # When would * fail to match?
61
+ end
62
+
63
+ # THINK ABOUT IT:
64
+ #
65
+ # We say that the repetition operators above are "greedy."
66
+ #
67
+ # Why?
68
+
69
+ # ------------------------------------------------------------------
70
+
71
+ # Checks the left most match wins.
72
+ def test_the_left_most_match_wins
73
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:the_left_most_match_wins_one), 'abbccc az'[/az*/]
74
+ end
75
+
76
+ # ------------------------------------------------------------------
77
+
78
+ # Checks character classes give options for a character.
79
+ def test_character_classes_give_options_for_a_character
80
+ animals = %w[cat bat rat zat]
81
+
82
+ assert_equal(Exercises::AboutRegularExpressions.koans.fetch(:character_classes_give_options_for_a_character_one), animals.select { |a|
83
+ a[/[cbr]at/]
84
+ })
85
+ end
86
+
87
+ # Checks slash d is a shortcut for a digit character class.
88
+ def test_slash_d_is_a_shortcut_for_a_digit_character_class
89
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_d_is_a_shortcut_for_a_digit_character_class_one),
90
+ 'the number is 42'[/[0123456789]+/]
91
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_d_is_a_shortcut_for_a_digit_character_class_two),
92
+ 'the number is 42'[/\d+/]
93
+ end
94
+
95
+ # Checks character classes can include ranges.
96
+ def test_character_classes_can_include_ranges
97
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:character_classes_can_include_ranges_one),
98
+ 'the number is 42'[/[0-9]+/]
99
+ end
100
+
101
+ # Checks slash s is a shortcut for a whitespace character class.
102
+ def test_slash_s_is_a_shortcut_for_a_whitespace_character_class
103
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_s_is_a_shortcut_for_a_whitespace_character_class_one),
104
+ "space: \t\n"[/\s+/]
105
+ end
106
+
107
+ # Checks slash w is a shortcut for a word character class.
108
+ def test_slash_w_is_a_shortcut_for_a_word_character_class
109
+ # NOTE: This is more like how a programmer might define a word.
110
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_w_is_a_shortcut_for_a_word_character_class_one),
111
+ 'variable_1 = 42'[/[a-zA-Z0-9_]+/]
112
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_w_is_a_shortcut_for_a_word_character_class_two),
113
+ 'variable_1 = 42'[/\w+/]
114
+ end
115
+
116
+ # Checks period is a shortcut for any non newline character.
117
+ def test_period_is_a_shortcut_for_any_non_newline_character
118
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:period_is_a_shortcut_for_any_non_newline_character_one),
119
+ "abc\n123"[/a.+/]
120
+ end
121
+
122
+ # Checks a character class can be negated.
123
+ def test_a_character_class_can_be_negated
124
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_character_class_can_be_negated_one),
125
+ 'the number is 42'[/[^0-9]+/]
126
+ end
127
+
128
+ # Checks shortcut character classes are negated with capitals.
129
+ def test_shortcut_character_classes_are_negated_with_capitals
130
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:shortcut_character_classes_are_negated_with_capitals_one),
131
+ 'the number is 42'[/\D+/]
132
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:shortcut_character_classes_are_negated_with_capitals_two),
133
+ "space: \t\n"[/\S+/]
134
+ # ... a programmer would most likely do
135
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:shortcut_character_classes_are_negated_with_capitals_three),
136
+ 'variable_1 = 42'[/[^a-zA-Z0-9_]+/]
137
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:shortcut_character_classes_are_negated_with_capitals_four),
138
+ 'variable_1 = 42'[/\W+/]
139
+ end
140
+
141
+ # ------------------------------------------------------------------
142
+
143
+ # Checks slash a anchors to the start of the string.
144
+ def test_slash_a_anchors_to_the_start_of_the_string
145
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_a_anchors_to_the_start_of_the_string_one),
146
+ 'start end'[/\Astart/]
147
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_a_anchors_to_the_start_of_the_string_two),
148
+ 'start end'[/\Aend/]
149
+ end
150
+
151
+ # Checks slash z anchors to the end of the string.
152
+ def test_slash_z_anchors_to_the_end_of_the_string
153
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_z_anchors_to_the_end_of_the_string_one),
154
+ 'start end'[/end\z/]
155
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_z_anchors_to_the_end_of_the_string_two),
156
+ 'start end'[/start\z/]
157
+ end
158
+
159
+ # Checks caret anchors to the start of lines.
160
+ def test_caret_anchors_to_the_start_of_lines
161
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:caret_anchors_to_the_start_of_lines_one),
162
+ "num 42\n2 lines"[/^\d+/]
163
+ end
164
+
165
+ # Checks dollar sign anchors to the end of lines.
166
+ def test_dollar_sign_anchors_to_the_end_of_lines
167
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:dollar_sign_anchors_to_the_end_of_lines_one),
168
+ "2 lines\nnum 42"[/\d+$/]
169
+ end
170
+
171
+ # Checks slash b anchors to a word boundary.
172
+ def test_slash_b_anchors_to_a_word_boundary
173
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:slash_b_anchors_to_a_word_boundary_one),
174
+ 'bovine vines'[/\bvine./]
175
+ end
176
+
177
+ # ------------------------------------------------------------------
178
+
179
+ # Checks parentheses group contents.
180
+ def test_parentheses_group_contents
181
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:parentheses_group_contents_one), 'ahahaha'[/(ha)+/]
182
+ end
183
+
184
+ # ------------------------------------------------------------------
185
+
186
+ # Checks parentheses also capture matched content by number.
187
+ def test_parentheses_also_capture_matched_content_by_number
188
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:parentheses_also_capture_matched_content_by_number_one),
189
+ 'Gray, James'[/(\w+), (\w+)/, 1]
190
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:parentheses_also_capture_matched_content_by_number_two),
191
+ 'Gray, James'[/(\w+), (\w+)/, 2]
192
+ end
193
+
194
+ # Checks variables can also be used to access captures.
195
+ def test_variables_can_also_be_used_to_access_captures
196
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:variables_can_also_be_used_to_access_captures_one),
197
+ 'Name: Gray, James'[/(\w+), (\w+)/]
198
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:variables_can_also_be_used_to_access_captures_two),
199
+ ($1)
200
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:variables_can_also_be_used_to_access_captures_three),
201
+ ($2)
202
+ end
203
+
204
+ # ------------------------------------------------------------------
205
+
206
+ # Checks a vertical pipe means or.
207
+ def test_a_vertical_pipe_means_or
208
+ grays = /(James|Dana|Summer) Gray/
209
+
210
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_vertical_pipe_means_or_one), 'James Gray'[grays]
211
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_vertical_pipe_means_or_two),
212
+ 'Summer Gray'[grays, 1]
213
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:a_vertical_pipe_means_or_three), 'Jim Gray'[grays, 1]
214
+ end
215
+
216
+ # THINK ABOUT IT:
217
+ #
218
+ # Explain the difference between a character class ([...]) and alternation (|).
219
+
220
+ # ------------------------------------------------------------------
221
+
222
+ # Checks scan is like find all.
223
+ def test_scan_is_like_find_all
224
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:scan_is_like_find_all_one),
225
+ 'one two-three'.scan(/\w+/)
226
+ end
227
+
228
+ # Checks sub is like find and replace.
229
+ def test_sub_is_like_find_and_replace
230
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:sub_is_like_find_and_replace_one), 'one two-three'.sub(/(t\w*)/) {
231
+ $1[0, 1]
232
+ }
233
+ end
234
+
235
+ # Checks gsub is like find and replace all.
236
+ def test_gsub_is_like_find_and_replace_all
237
+ assert_equal Exercises::AboutRegularExpressions.koans.fetch(:gsub_is_like_find_and_replace_all_one), 'one two-three'.gsub(/(t\w*)/) {
238
+ $1[0, 1]
239
+ }
240
+ end
241
+ end
242
+
243
+ # rubocop:enable Layout/LineLength, Metrics/ClassLength, Style/BlockDelimiters, Style/PerlBackrefs