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,82 @@
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
+ require 'tempfile'
10
+
11
+ class AboutSandwichCodeTest < Minitest::Test
12
+ # Count and search the original example through each version of the operation.
13
+ def test_counting_and_finding_lines
14
+ Tempfile.create('rkoans-lines') do |file|
15
+ file.write("this\nis\na\ntest\n")
16
+ file.flush
17
+ subject = Exercises::AboutSandwichCode
18
+
19
+ assert_equal 4, subject.count_lines(file.path)
20
+ assert_equal 4, subject.count_lines2(file.path)
21
+ assert_equal 4, subject.count_lines3(file.path)
22
+ assert_equal "test\n", subject.find_line(file.path)
23
+ assert_equal "test\n", subject.find_line2(file.path)
24
+ end
25
+ end
26
+
27
+ # Empty files, absent matches and a final unterminated line retain their meaning.
28
+ def test_empty_and_unterminated_files
29
+ Tempfile.create('rkoans-lines') do |file|
30
+ subject = Exercises::AboutSandwichCode
31
+
32
+ assert_equal 0, subject.count_lines2(file.path)
33
+ assert_nil subject.find_line2(file.path)
34
+ file.write('ruby')
35
+ file.flush
36
+
37
+ assert_equal 1, subject.count_lines3(file.path)
38
+ assert_nil subject.find_line2(file.path)
39
+ end
40
+ end
41
+
42
+ # The resource closes and the result survives both successful and failing blocks.
43
+ def test_file_sandwich_closes_on_success_and_exception
44
+ Tempfile.create('rkoans-cleanup') do |file|
45
+ captured = nil
46
+ result = Exercises::AboutSandwichCode.file_sandwich(file.path) do |opened|
47
+ captured = opened
48
+ :result
49
+ end
50
+
51
+ assert_equal :result, result
52
+ assert_predicate captured, :closed?
53
+ error = assert_raises(RuntimeError) do
54
+ Exercises::AboutSandwichCode.file_sandwich(file.path) do |opened|
55
+ captured = opened
56
+ raise 'operation failed'
57
+ end
58
+ end
59
+
60
+ assert_equal 'operation failed', error.message
61
+ assert_predicate captured, :closed?
62
+ ensure
63
+ captured&.close
64
+ end
65
+ end
66
+
67
+ # A block's early break must also release the open file.
68
+ def test_file_sandwich_closes_on_early_exit
69
+ Tempfile.create('rkoans-cleanup') do |file|
70
+ captured = nil
71
+ result = Exercises::AboutSandwichCode.file_sandwich(file.path) do |opened|
72
+ captured = opened
73
+ break :early
74
+ end
75
+
76
+ assert_equal :early, result
77
+ assert_predicate captured, :closed?
78
+ ensure
79
+ captured&.close
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ # An empty class demonstrates construction without custom methods.
4
+ # Class identity comparisons explicitly demonstrate lexical constant lookup.
5
+ # rubocop:disable Lint/EmptyClass, Style/ClassEqualityComparison
6
+
7
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
8
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
9
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
10
+
11
+ require ARGV.shift
12
+ class AboutScopeTest < Minitest::Test
13
+ module Jims
14
+ class Dog
15
+ # Demonstrates identify.
16
+ def identify
17
+ :jims_dog
18
+ end
19
+ end
20
+ end
21
+
22
+ module Joes
23
+ class Dog
24
+ # Demonstrates identify.
25
+ def identify
26
+ :joes_dog
27
+ end
28
+ end
29
+ end
30
+
31
+ # Checks dog is not available in the current scope.
32
+ def test_dog_is_not_available_in_the_current_scope
33
+ assert_predicted_error(:dog_is_not_available_in_the_current_scope_one, ::NameError) do
34
+ Dog.new
35
+ end
36
+ end
37
+
38
+ # Checks you can reference nested classes using the scope operator.
39
+ def test_you_can_reference_nested_classes_using_the_scope_operator
40
+ fido = Jims::Dog.new
41
+ rover = Joes::Dog.new
42
+
43
+ assert_equal Exercises::AboutScope.koans.fetch(:you_can_reference_nested_classes_using_the_scope_operator_one),
44
+ fido.identify
45
+ assert_equal Exercises::AboutScope.koans.fetch(:you_can_reference_nested_classes_using_the_scope_operator_two),
46
+ rover.identify
47
+
48
+ assert_equal Exercises::AboutScope.koans.fetch(:you_can_reference_nested_classes_using_the_scope_operator_three),
49
+ (fido.class != rover.class)
50
+ assert_equal Exercises::AboutScope.koans.fetch(:you_can_reference_nested_classes_using_the_scope_operator_four),
51
+ (Jims::Dog != Joes::Dog)
52
+ end
53
+
54
+ # ------------------------------------------------------------------
55
+
56
+ class String
57
+ end
58
+
59
+ # Checks bare bones class names assume the current scope.
60
+ def test_bare_bones_class_names_assume_the_current_scope
61
+ assert_equal Exercises::AboutScope.koans.fetch(:bare_bones_class_names_assume_the_current_scope_one),
62
+ (AboutScopeTest::String == String)
63
+ end
64
+
65
+ # Checks nested string is not the same as the system string.
66
+ def test_nested_string_is_not_the_same_as_the_system_string
67
+ assert_equal Exercises::AboutScope.koans.fetch(:nested_string_is_not_the_same_as_the_system_string_one),
68
+ ('HI'.class == String)
69
+ end
70
+
71
+ # Checks use the prefix scope operator to force the global scope.
72
+ def test_use_the_prefix_scope_operator_to_force_the_global_scope
73
+ assert_equal Exercises::AboutScope.koans.fetch(:use_the_prefix_scope_operator_to_force_the_global_scope_one),
74
+ ('HI'.class == ::String)
75
+ end
76
+
77
+ # ------------------------------------------------------------------
78
+
79
+ PI = 3.1416
80
+
81
+ # Checks constants are defined with an initial uppercase letter.
82
+ def test_constants_are_defined_with_an_initial_uppercase_letter
83
+ assert_equal Exercises::AboutScope.koans.fetch(:constants_are_defined_with_an_initial_uppercase_letter_one), PI
84
+ end
85
+
86
+ # ------------------------------------------------------------------
87
+
88
+ MyString = ::String
89
+
90
+ # Checks class names are just constants.
91
+ def test_class_names_are_just_constants
92
+ assert_equal Exercises::AboutScope.koans.fetch(:class_names_are_just_constants_one), (MyString == ::String)
93
+ assert_equal Exercises::AboutScope.koans.fetch(:class_names_are_just_constants_two), ('HI'.class == MyString)
94
+ end
95
+
96
+ # Checks constants can be looked up explicitly.
97
+ def test_constants_can_be_looked_up_explicitly
98
+ assert_equal Exercises::AboutScope.koans.fetch(:constants_can_be_looked_up_explicitly_one),
99
+ (AboutScopeTest.const_get('PI') == PI)
100
+ assert_equal Exercises::AboutScope.koans.fetch(:constants_can_be_looked_up_explicitly_two),
101
+ (AboutScopeTest.const_get('MyString') == MyString)
102
+ end
103
+
104
+ # Checks you can get a list of constants for any class or module.
105
+ def test_you_can_get_a_list_of_constants_for_any_class_or_module
106
+ assert_equal Exercises::AboutScope.koans.fetch(:you_can_get_a_list_of_constants_for_any_class_or_module_one),
107
+ Jims.constants
108
+ assert_equal Exercises::AboutScope.koans.fetch(:you_can_get_a_list_of_constants_for_any_class_or_module_two),
109
+ Object.constants.any?
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::AboutScope.koans.fetch(key), error.class
119
+ error
120
+ end
121
+ end
122
+
123
+ # rubocop:enable Lint/EmptyClass, Style/ClassEqualityComparison
@@ -0,0 +1,62 @@
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 original descriptive Koans check names.
8
+ # rubocop:disable Naming/VariableNumber
9
+
10
+ require ARGV.shift
11
+
12
+ class AboutScoringProjectTest < Minitest::Test
13
+ # Checks score of an empty list is zero.
14
+ def test_score_of_an_empty_list_is_zero
15
+ assert_equal 0, Exercises::AboutScoringProject.score([])
16
+ end
17
+
18
+ # Checks score of a single roll of 5 is 50.
19
+ def test_score_of_a_single_roll_of_5_is_50
20
+ assert_equal 50, Exercises::AboutScoringProject.score([5])
21
+ end
22
+
23
+ # Checks score of a single roll of 1 is 100.
24
+ def test_score_of_a_single_roll_of_1_is_100
25
+ assert_equal 100, Exercises::AboutScoringProject.score([1])
26
+ end
27
+
28
+ # Checks score of multiple 1s and 5s is the sum of individual scores.
29
+ def test_score_of_multiple_1s_and_5s_is_the_sum_of_individual_scores
30
+ assert_equal 300, Exercises::AboutScoringProject.score([1, 5, 5, 1])
31
+ end
32
+
33
+ # Checks score of single 2s 3s 4s and 6s are zero.
34
+ def test_score_of_single_2s_3s_4s_and_6s_are_zero
35
+ assert_equal 0, Exercises::AboutScoringProject.score([2, 3, 4, 6])
36
+ end
37
+
38
+ # Checks score of a triple 1 is 1000.
39
+ def test_score_of_a_triple_1_is_1000
40
+ assert_equal 1000, Exercises::AboutScoringProject.score([1, 1, 1])
41
+ end
42
+
43
+ # Checks score of other triples is 100x.
44
+ def test_score_of_other_triples_is_100x
45
+ assert_equal 200, Exercises::AboutScoringProject.score([2, 2, 2])
46
+ assert_equal 300, Exercises::AboutScoringProject.score([3, 3, 3])
47
+ assert_equal 400, Exercises::AboutScoringProject.score([4, 4, 4])
48
+ assert_equal 500, Exercises::AboutScoringProject.score([5, 5, 5])
49
+ assert_equal 600, Exercises::AboutScoringProject.score([6, 6, 6])
50
+ end
51
+
52
+ # Checks score of mixed is sum.
53
+ def test_score_of_mixed_is_sum
54
+ assert_equal 250, Exercises::AboutScoringProject.score([2, 5, 2, 2, 3])
55
+ assert_equal 550, Exercises::AboutScoringProject.score([5, 5, 5, 5])
56
+ assert_equal 1100, Exercises::AboutScoringProject.score([1, 1, 1, 1])
57
+ assert_equal 1200, Exercises::AboutScoringProject.score([1, 1, 1, 1, 1])
58
+ assert_equal 1150, Exercises::AboutScoringProject.score([1, 1, 1, 5, 1])
59
+ end
60
+ end
61
+
62
+ # rubocop:enable Naming/VariableNumber
@@ -0,0 +1,255 @@
1
+ # frozen_string_literal: false
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
+ # Literal quoting and character syntax are the subjects of these examples.
8
+ # Mutable literals also preserve the original mutation and identity experiments.
9
+ # rubocop:disable Style/StringLiterals, Style/PercentLiteralDelimiters, Style/CharacterLiteral
10
+ # rubocop:disable Style/StringConcatenation, Lint/UselessAssignment, Lint/InterpolationCheck
11
+ # rubocop:disable Minitest/LiteralAsActualArgument, Style/RedundantRegexpArgument, Lint/IdentityComparison
12
+ require ARGV.shift
13
+
14
+ class AboutStringsQuotingTest < Minitest::Test
15
+ # Checks double quoted strings are strings.
16
+ def test_double_quoted_strings_are_strings
17
+ string = "Hello, World"
18
+
19
+ assert_equal Exercises::AboutStrings.koans[:double_quoted_string], string.is_a?(String)
20
+ end
21
+
22
+ # Checks single quoted strings are also strings.
23
+ def test_single_quoted_strings_are_also_strings
24
+ string = 'Goodbye, World'
25
+
26
+ assert_equal Exercises::AboutStrings.koans[:single_quoted_string], string.is_a?(String)
27
+ end
28
+
29
+ # Checks use single quotes to create string with double quotes.
30
+ def test_use_single_quotes_to_create_string_with_double_quotes
31
+ string = 'He said, "Go Away."'
32
+
33
+ assert_equal Exercises::AboutStrings.koans[:quoted_speech], string
34
+ end
35
+
36
+ # Checks use double quotes to create strings with single quotes.
37
+ def test_use_double_quotes_to_create_strings_with_single_quotes
38
+ string = "Don't"
39
+
40
+ assert_equal Exercises::AboutStrings.koans[:apostrophe], string
41
+ end
42
+
43
+ # Checks use backslash for those hard cases.
44
+ def test_use_backslash_for_those_hard_cases
45
+ a = "He said, \"Don't\""
46
+ b = 'He said, "Don\'t"'
47
+
48
+ assert_equal Exercises::AboutStrings.koans[:escaped_quotes_equal], a == b
49
+ end
50
+
51
+ # Checks use flexible quoting to handle really hard cases.
52
+ def test_use_flexible_quoting_to_handle_really_hard_cases
53
+ a = %(flexible quotes can handle both ' and " characters)
54
+ b = %!flexible quotes can handle both ' and " characters!
55
+ c = %{flexible quotes can handle both ' and " characters}
56
+
57
+ assert_equal Exercises::AboutStrings.koans[:flexible_percent_equal], a == b
58
+ assert_equal Exercises::AboutStrings.koans[:flexible_braces_equal], a == c
59
+ end
60
+
61
+ # Checks flexible quotes can handle multiple lines.
62
+ def test_flexible_quotes_can_handle_multiple_lines
63
+ long_string = %{
64
+ It was the best of times,
65
+ It was the worst of times.
66
+ }
67
+
68
+ assert_equal Exercises::AboutStrings.koans[:multiline_length], long_string.length
69
+ assert_equal Exercises::AboutStrings.koans[:multiline_lines], long_string.lines.count
70
+ assert_equal Exercises::AboutStrings.koans[:multiline_first_character], long_string[0, 1]
71
+ end
72
+
73
+ # Checks here documents can also handle multiple lines.
74
+ def test_here_documents_can_also_handle_multiple_lines
75
+ long_string = <<~TEXT
76
+ It was the best of times,
77
+ It was the worst of times.
78
+ TEXT
79
+ assert_equal Exercises::AboutStrings.koans[:heredoc_length], long_string.length
80
+ assert_equal Exercises::AboutStrings.koans[:heredoc_lines], long_string.lines.count
81
+ assert_equal Exercises::AboutStrings.koans[:heredoc_first_character], long_string[0, 1]
82
+ end
83
+ end
84
+
85
+ class AboutStringsMutationTest < Minitest::Test
86
+ # Checks plus will concatenate two strings.
87
+ def test_plus_will_concatenate_two_strings
88
+ string = "Hello, " + "World"
89
+
90
+ assert_equal Exercises::AboutStrings.koans[:concatenated], string
91
+ end
92
+
93
+ # Checks plus concatenation will leave the original strings unmodified.
94
+ def test_plus_concatenation_will_leave_the_original_strings_unmodified
95
+ hi = "Hello, "
96
+ there = "World"
97
+ string = hi + there
98
+
99
+ assert_equal Exercises::AboutStrings.koans[:plus_original], hi
100
+ assert_equal Exercises::AboutStrings.koans[:plus_other], there
101
+ end
102
+
103
+ # Checks plus equals will concatenate to the end of a string.
104
+ def test_plus_equals_will_concatenate_to_the_end_of_a_string
105
+ hi = "Hello, "
106
+ there = "World"
107
+ hi += there
108
+
109
+ assert_equal Exercises::AboutStrings.koans[:plus_equals_result], hi
110
+ end
111
+
112
+ # Checks plus equals also will leave the original string unmodified.
113
+ def test_plus_equals_also_will_leave_the_original_string_unmodified
114
+ original_string = "Hello, "
115
+ hi = original_string
116
+ there = "World"
117
+ hi += there
118
+
119
+ assert_equal Exercises::AboutStrings.koans[:plus_equals_original], original_string
120
+ end
121
+
122
+ # Checks the shovel operator will also append content to a string.
123
+ def test_the_shovel_operator_will_also_append_content_to_a_string
124
+ hi = "Hello, "
125
+ there = "World"
126
+ hi << there
127
+
128
+ assert_equal Exercises::AboutStrings.koans[:append_result], hi
129
+ assert_equal Exercises::AboutStrings.koans[:append_other], there
130
+ end
131
+
132
+ # Checks the shovel operator modifies the original string.
133
+ def test_the_shovel_operator_modifies_the_original_string
134
+ original_string = "Hello, "
135
+ hi = original_string
136
+ there = "World"
137
+ hi << there
138
+
139
+ assert_equal Exercises::AboutStrings.koans[:appended_original], original_string
140
+
141
+ # THINK ABOUT IT:
142
+ #
143
+ # Ruby programmers tend to favor the shovel operator (<<) over the
144
+ # plus equals operator (+=) when building up strings. Why?
145
+ end
146
+ end
147
+
148
+ class AboutStringsValuesTest < Minitest::Test
149
+ # Checks double quoted string interpret escape characters.
150
+ def test_double_quoted_string_interpret_escape_characters
151
+ string = "\n"
152
+
153
+ assert_equal Exercises::AboutStrings.koans[:double_escape_length], string.size
154
+ end
155
+
156
+ # Checks single quoted string do not interpret escape characters.
157
+ def test_single_quoted_string_do_not_interpret_escape_characters
158
+ string = '\n'
159
+
160
+ assert_equal Exercises::AboutStrings.koans[:single_escape_length], string.size
161
+ end
162
+
163
+ # Checks single quotes sometimes interpret escape characters.
164
+ def test_single_quotes_sometimes_interpret_escape_characters
165
+ string = '\\\''
166
+
167
+ assert_equal Exercises::AboutStrings.koans[:quote_escape_length], string.size
168
+ assert_equal Exercises::AboutStrings.koans[:quote_escape_text], string
169
+ end
170
+
171
+ # Checks double quoted strings interpolate variables.
172
+ def test_double_quoted_strings_interpolate_variables
173
+ value = 123
174
+ string = "The value is #{value}"
175
+
176
+ assert_equal Exercises::AboutStrings.koans[:interpolated], string
177
+ end
178
+
179
+ # Checks single quoted strings do not interpolate.
180
+ def test_single_quoted_strings_do_not_interpolate
181
+ value = 123
182
+ string = 'The value is #{value}'
183
+
184
+ assert_equal Exercises::AboutStrings.koans[:not_interpolated], string
185
+ end
186
+
187
+ # Checks any ruby expression may be interpolated.
188
+ def test_any_ruby_expression_may_be_interpolated
189
+ string = "The square root of 5 is #{Math.sqrt(5)}"
190
+
191
+ assert_equal Exercises::AboutStrings.koans[:math_interpolation], string
192
+ end
193
+
194
+ # Checks you can get a substring from a string.
195
+ def test_you_can_get_a_substring_from_a_string
196
+ string = "Bacon, lettuce and tomato"
197
+
198
+ assert_equal Exercises::AboutStrings.koans[:substring_slice], string[7, 3]
199
+ assert_equal Exercises::AboutStrings.koans[:substring_range], string[7..9]
200
+ end
201
+
202
+ # Checks you can get a single character from a string.
203
+ def test_you_can_get_a_single_character_from_a_string
204
+ string = "Bacon, lettuce and tomato"
205
+
206
+ assert_equal Exercises::AboutStrings.koans[:single_character], string[1]
207
+
208
+ # Surprised?
209
+ end
210
+
211
+ # Checks in modern ruby single characters are represented by strings.
212
+ def test_in_modern_ruby_single_characters_are_represented_by_strings
213
+ assert_equal Exercises::AboutStrings.koans[:character_literal], ?a
214
+ assert_equal Exercises::AboutStrings.koans[:character_equals_integer], ?a == 97
215
+ end
216
+
217
+ # Checks strings can be split.
218
+ def test_strings_can_be_split
219
+ string = "Sausage Egg Cheese"
220
+ words = string.split
221
+
222
+ assert_equal Exercises::AboutStrings.koans[:split_words], words
223
+ end
224
+
225
+ # Checks strings can be split with different patterns.
226
+ def test_strings_can_be_split_with_different_patterns
227
+ string = "the:rain:in:spain"
228
+ words = string.split(/:/)
229
+
230
+ assert_equal Exercises::AboutStrings.koans[:pattern_words], words
231
+
232
+ # NOTE: Patterns are formed from Regular Expressions. Ruby has a
233
+ # powerful Regular Expression library.
234
+ end
235
+
236
+ # Checks strings can be joined.
237
+ def test_strings_can_be_joined
238
+ words = %w[Now is the time]
239
+
240
+ assert_equal Exercises::AboutStrings.koans[:joined_words], words.join(" ")
241
+ end
242
+
243
+ # Checks strings are unique objects.
244
+ def test_strings_are_unique_objects
245
+ a = "a string"
246
+ b = "a string"
247
+
248
+ assert_equal Exercises::AboutStrings.koans[:equal_strings], a == b
249
+ assert_equal Exercises::AboutStrings.koans[:same_object], a.object_id == b.object_id
250
+ end
251
+ end
252
+
253
+ # rubocop:enable Style/StringLiterals, Style/PercentLiteralDelimiters, Style/CharacterLiteral
254
+ # rubocop:enable Style/StringConcatenation, Lint/UselessAssignment, Lint/InterpolationCheck
255
+ # rubocop:enable Minitest/LiteralAsActualArgument, Style/RedundantRegexpArgument, Lint/IdentityComparison
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ # SPDX-License-Identifier: CC-BY-NC-SA-3.0
4
+ # Adapted from Ruby Koans by Jim Weirich and Joe O'Brien.
5
+ # See THIRD_PARTY_NOTICES.md for attribution and license terms.
6
+
7
+ require ARGV.shift
8
+
9
+ # Observes symbols without interning the names being searched for as expectations.
10
+ class AboutSymbolsTest < Minitest::Test
11
+ RUBY_CONSTANT = 'What is the sound of one hand clapping?'
12
+
13
+ # Symbols have their own type.
14
+ def test_symbols_are_symbols
15
+ symbol = :ruby
16
+
17
+ assert_equal Exercises::AboutSymbols.koans[:symbol_type], symbol.is_a?(Symbol)
18
+ end
19
+
20
+ # Equal names compare equally; different names do not.
21
+ def test_symbols_can_be_compared
22
+ symbol1 = :a_symbol
23
+ symbol2 = :a_symbol
24
+ symbol3 = :something_else
25
+ answers = Exercises::AboutSymbols.koans
26
+
27
+ assert_equal answers[:same_value], symbol1 == symbol2
28
+ assert_equal answers[:different_value], symbol1 == symbol3
29
+ end
30
+
31
+ # Identical symbols share identity as well as value.
32
+ def test_identical_symbols_are_a_single_internal_object
33
+ symbol1 = :a_symbol
34
+ symbol2 = :a_symbol
35
+ answers = Exercises::AboutSymbols.koans
36
+
37
+ assert_equal answers[:identical_value], symbol1 == symbol2
38
+ assert_equal answers[:same_object], symbol1.equal?(symbol2)
39
+ end
40
+
41
+ # Defined method names occur in the symbol table.
42
+ def test_method_names_become_symbols
43
+ names = Symbol.all_symbols.map(&:to_s)
44
+
45
+ assert_equal Exercises::AboutSymbols.koans[:method_name_registered],
46
+ names.include?('test_method_names_become_symbols')
47
+ end
48
+
49
+ # Constant names are compared as strings to avoid creating a searched-for symbol.
50
+ def test_constants_become_symbols
51
+ names = Symbol.all_symbols.map(&:to_s)
52
+ constant_name = self.class.constants(false).fetch(0).to_s
53
+ answers = Exercises::AboutSymbols.koans
54
+
55
+ assert_equal answers[:constant_name], constant_name
56
+ assert_equal answers[:constant_registered], names.include?(constant_name)
57
+ end
58
+
59
+ # Strings can be converted into symbols.
60
+ def test_symbols_can_be_made_from_strings
61
+ string = 'catsAndDogs'
62
+
63
+ assert_equal Exercises::AboutSymbols.koans[:from_string], string.to_sym
64
+ end
65
+
66
+ # Quoting permits spaces inside symbol names.
67
+ def test_symbols_with_spaces_can_be_built
68
+ symbol = :'cats and dogs'
69
+
70
+ assert_equal Exercises::AboutSymbols.koans[:with_spaces], symbol
71
+ end
72
+
73
+ # Double-quoted symbol syntax supports interpolation.
74
+ def test_symbols_with_interpolation_can_be_built
75
+ value = 'and'
76
+ symbol = :"cats #{value} dogs"
77
+
78
+ assert_equal Exercises::AboutSymbols.koans[:with_interpolation], symbol
79
+ end
80
+
81
+ # String interpolation calls a symbol's to_s.
82
+ def test_to_s_is_called_on_interpolated_symbols
83
+ symbol = :cats
84
+ string = "It is raining #{symbol} and dogs."
85
+
86
+ assert_equal Exercises::AboutSymbols.koans[:interpolated_text], string
87
+ end
88
+
89
+ # A symbol and a string with the same spelling are different values and types.
90
+ def test_symbols_are_not_strings
91
+ symbol = :ruby
92
+ answers = Exercises::AboutSymbols.koans
93
+
94
+ assert_equal answers[:string_type], symbol.is_a?(String)
95
+ assert_equal answers[:equals_string], symbol.eql?('ruby')
96
+ end
97
+
98
+ # Symbols do not provide these string operations.
99
+ def test_symbols_do_not_have_string_methods
100
+ symbol = :not_a_string
101
+ answers = Exercises::AboutSymbols.koans
102
+
103
+ assert_equal answers[:each_char], symbol.respond_to?(:each_char)
104
+ assert_equal answers[:reverse], symbol.respond_to?(:reverse)
105
+ end
106
+
107
+ # Unsupported concatenation raises an exception whose class can be predicted.
108
+ def test_symbols_cannot_be_concatenated
109
+ error = assert_raises(NoMethodError) { :cats + :dogs }
110
+
111
+ assert_equal Exercises::AboutSymbols.koans[:concatenation_error], error.class
112
+ end
113
+
114
+ # A constructed string can be converted to a symbol.
115
+ def test_symbols_can_be_dynamically_created
116
+ name = 'cats' + 'dogs' # rubocop:disable Style/StringConcatenation
117
+
118
+ assert_equal Exercises::AboutSymbols.koans[:dynamically_created], name.to_sym
119
+ end
120
+ end