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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/CURRICULUM.md +86 -0
- data/README.md +77 -0
- data/THIRD_PARTY_NOTICES.md +30 -0
- data/exercises/about-array-assignment/about_array_assignment.rb +45 -0
- data/exercises/about-array-assignment/brief.md +11 -0
- data/exercises/about-array-assignment/hint.md +11 -0
- data/exercises/about-arrays/about_arrays.rb +77 -0
- data/exercises/about-arrays/brief.md +16 -0
- data/exercises/about-arrays/hint.md +13 -0
- data/exercises/about-asserts/about_asserts.rb +22 -0
- data/exercises/about-asserts/brief.md +22 -0
- data/exercises/about-asserts/hint.md +10 -0
- data/exercises/about-blocks/about_blocks.rb +76 -0
- data/exercises/about-blocks/brief.md +44 -0
- data/exercises/about-blocks/hint.md +7 -0
- data/exercises/about-class-methods/about_class_methods.rb +105 -0
- data/exercises/about-class-methods/brief.md +73 -0
- data/exercises/about-class-methods/hint.md +8 -0
- data/exercises/about-classes/about_classes.rb +131 -0
- data/exercises/about-classes/brief.md +73 -0
- data/exercises/about-classes/hint.md +7 -0
- data/exercises/about-constants/about_constants.rb +49 -0
- data/exercises/about-constants/brief.md +51 -0
- data/exercises/about-constants/hint.md +7 -0
- data/exercises/about-control-statements/about_control_statements.rb +152 -0
- data/exercises/about-control-statements/brief.md +9 -0
- data/exercises/about-control-statements/hint.md +7 -0
- data/exercises/about-dice-project/about_dice_project.rb +27 -0
- data/exercises/about-dice-project/brief.md +12 -0
- data/exercises/about-dice-project/hint.md +5 -0
- data/exercises/about-exceptions/about_exceptions.rb +84 -0
- data/exercises/about-exceptions/brief.md +19 -0
- data/exercises/about-exceptions/hint.md +8 -0
- data/exercises/about-extra-credit/about_extra_credit.rb +117 -0
- data/exercises/about-extra-credit/brief.md +28 -0
- data/exercises/about-extra-credit/hint.md +5 -0
- data/exercises/about-hashes/about_hashes.rb +160 -0
- data/exercises/about-hashes/brief.md +9 -0
- data/exercises/about-hashes/hint.md +8 -0
- data/exercises/about-inheritance/about_inheritance.rb +63 -0
- data/exercises/about-inheritance/brief.md +50 -0
- data/exercises/about-inheritance/hint.md +8 -0
- data/exercises/about-iteration/about_iteration.rb +96 -0
- data/exercises/about-iteration/brief.md +26 -0
- data/exercises/about-iteration/hint.md +6 -0
- data/exercises/about-keyword-arguments/about_keyword_arguments.rb +56 -0
- data/exercises/about-keyword-arguments/brief.md +28 -0
- data/exercises/about-keyword-arguments/hint.md +7 -0
- data/exercises/about-message-passing/about_message_passing.rb +112 -0
- data/exercises/about-message-passing/brief.md +59 -0
- data/exercises/about-message-passing/hint.md +8 -0
- data/exercises/about-methods/about_methods.rb +104 -0
- data/exercises/about-methods/brief.md +55 -0
- data/exercises/about-methods/hint.md +8 -0
- data/exercises/about-modules/about_modules.rb +43 -0
- data/exercises/about-modules/brief.md +44 -0
- data/exercises/about-modules/hint.md +8 -0
- data/exercises/about-nil/about_nil.rb +29 -0
- data/exercises/about-nil/brief.md +12 -0
- data/exercises/about-nil/hint.md +11 -0
- data/exercises/about-objects/about_objects.rb +51 -0
- data/exercises/about-objects/brief.md +14 -0
- data/exercises/about-objects/hint.md +12 -0
- data/exercises/about-open-classes/about_open_classes.rb +38 -0
- data/exercises/about-open-classes/brief.md +34 -0
- data/exercises/about-open-classes/hint.md +7 -0
- data/exercises/about-pattern-matching/about_pattern_matching.rb +106 -0
- data/exercises/about-pattern-matching/brief.md +124 -0
- data/exercises/about-pattern-matching/hint.md +8 -0
- data/exercises/about-proxy-object-project/about_proxy_object_project.rb +43 -0
- data/exercises/about-proxy-object-project/brief.md +10 -0
- data/exercises/about-proxy-object-project/hint.md +5 -0
- data/exercises/about-regular-expressions/about_regular_expressions.rb +174 -0
- data/exercises/about-regular-expressions/brief.md +9 -0
- data/exercises/about-regular-expressions/hint.md +8 -0
- data/exercises/about-sandwich-code/about_sandwich_code.rb +58 -0
- data/exercises/about-sandwich-code/brief.md +14 -0
- data/exercises/about-sandwich-code/hint.md +5 -0
- data/exercises/about-scope/about_scope.rb +76 -0
- data/exercises/about-scope/brief.md +35 -0
- data/exercises/about-scope/hint.md +8 -0
- data/exercises/about-scoring-project/about_scoring_project.rb +16 -0
- data/exercises/about-scoring-project/brief.md +10 -0
- data/exercises/about-scoring-project/hint.md +5 -0
- data/exercises/about-strings/about_strings.rb +142 -0
- data/exercises/about-strings/brief.md +22 -0
- data/exercises/about-strings/hint.md +11 -0
- data/exercises/about-symbols/about_symbols.rb +53 -0
- data/exercises/about-symbols/brief.md +21 -0
- data/exercises/about-symbols/hint.md +12 -0
- data/exercises/about-to-str/about_to_str.rb +49 -0
- data/exercises/about-to-str/brief.md +37 -0
- data/exercises/about-to-str/hint.md +7 -0
- data/exercises/about-triangle-project/about_triangle_project.rb +15 -0
- data/exercises/about-triangle-project/brief.md +11 -0
- data/exercises/about-triangle-project/hint.md +5 -0
- data/exercises/about-triangle-project-two/about_triangle_project_two.rb +22 -0
- data/exercises/about-triangle-project-two/brief.md +10 -0
- data/exercises/about-triangle-project-two/hint.md +5 -0
- data/exercises/about-true-and-false/about_true_and_false.rb +26 -0
- data/exercises/about-true-and-false/brief.md +22 -0
- data/exercises/about-true-and-false/hint.md +7 -0
- data/exercises/blocks-and-methods/blocks_and_methods.rb +14 -0
- data/exercises/blocks-and-methods/brief.md +8 -0
- data/exercises/blocks-and-methods/hint.md +6 -0
- data/exercises/catalog.json +61 -0
- data/exercises/class-state/brief.md +8 -0
- data/exercises/class-state/class_state.rb +39 -0
- data/exercises/class-state/hint.md +5 -0
- data/exercises/closure-capture/brief.md +8 -0
- data/exercises/closure-capture/closure_capture.rb +21 -0
- data/exercises/closure-capture/hint.md +5 -0
- data/exercises/collection-basics/brief.md +8 -0
- data/exercises/collection-basics/collection_basics.rb +16 -0
- data/exercises/collection-basics/hint.md +6 -0
- data/exercises/constant-scope/brief.md +8 -0
- data/exercises/constant-scope/constant_scope.rb +18 -0
- data/exercises/constant-scope/hint.md +5 -0
- data/exercises/core-protocols/brief.md +8 -0
- data/exercises/core-protocols/core_protocols.rb +43 -0
- data/exercises/core-protocols/hint.md +5 -0
- data/exercises/delegation/brief.md +8 -0
- data/exercises/delegation/delegation.rb +20 -0
- data/exercises/delegation/hint.md +5 -0
- data/exercises/dynamic-methods/brief.md +8 -0
- data/exercises/dynamic-methods/dynamic_methods.rb +33 -0
- data/exercises/dynamic-methods/hint.md +5 -0
- data/exercises/exception-flow/brief.md +8 -0
- data/exercises/exception-flow/exception_flow.rb +27 -0
- data/exercises/exception-flow/hint.md +5 -0
- data/exercises/heredoc-layout/brief.md +14 -0
- data/exercises/heredoc-layout/heredoc_layout.rb +25 -0
- data/exercises/heredoc-layout/hint.md +9 -0
- data/exercises/keyword-forwarding/brief.md +8 -0
- data/exercises/keyword-forwarding/hint.md +5 -0
- data/exercises/keyword-forwarding/keyword_forwarding.rb +27 -0
- data/exercises/lazy-enumeration/brief.md +8 -0
- data/exercises/lazy-enumeration/hint.md +5 -0
- data/exercises/lazy-enumeration/lazy_enumeration.rb +16 -0
- data/exercises/literals-and-operators/brief.md +20 -0
- data/exercises/literals-and-operators/hint.md +5 -0
- data/exercises/literals-and-operators/literals_and_operators.rb +15 -0
- data/exercises/method-contracts/brief.md +8 -0
- data/exercises/method-contracts/hint.md +5 -0
- data/exercises/method-contracts/method_contracts.rb +22 -0
- data/exercises/method-lookup/brief.md +8 -0
- data/exercises/method-lookup/hint.md +5 -0
- data/exercises/method-lookup/method_lookup.rb +26 -0
- data/exercises/nonlocal-exit/brief.md +8 -0
- data/exercises/nonlocal-exit/hint.md +5 -0
- data/exercises/nonlocal-exit/nonlocal_exit.rb +29 -0
- data/exercises/numbered-parameters/brief.md +18 -0
- data/exercises/numbered-parameters/hint.md +5 -0
- data/exercises/numbered-parameters/numbered_parameters.rb +18 -0
- data/exercises/numeric-precision/brief.md +8 -0
- data/exercises/numeric-precision/hint.md +5 -0
- data/exercises/numeric-precision/numeric_precision.rb +17 -0
- data/exercises/pattern-matching/brief.md +8 -0
- data/exercises/pattern-matching/hint.md +5 -0
- data/exercises/pattern-matching/pattern_matching.rb +22 -0
- data/exercises/refinement-scope/brief.md +8 -0
- data/exercises/refinement-scope/hint.md +5 -0
- data/exercises/refinement-scope/refinement_scope.rb +33 -0
- data/exercises/regexp-captures/brief.md +8 -0
- data/exercises/regexp-captures/hint.md +5 -0
- data/exercises/regexp-captures/regexp_captures.rb +25 -0
- data/exercises/runtime-context/brief.md +20 -0
- data/exercises/runtime-context/hint.md +8 -0
- data/exercises/runtime-context/runtime_context.rb +11 -0
- data/exercises/shared-rows/brief.md +8 -0
- data/exercises/shared-rows/hint.md +7 -0
- data/exercises/shared-rows/shared_rows.rb +13 -0
- data/exercises/singleton-pattern/brief.md +8 -0
- data/exercises/singleton-pattern/hint.md +5 -0
- data/exercises/singleton-pattern/singleton_pattern.rb +20 -0
- data/exercises/time-and-date/brief.md +8 -0
- data/exercises/time-and-date/hint.md +5 -0
- data/exercises/time-and-date/time_and_date.rb +21 -0
- data/exercises/visibility/brief.md +8 -0
- data/exercises/visibility/hint.md +5 -0
- data/exercises/visibility/visibility.rb +32 -0
- data/lib/rkoans/catalog.rb +31 -0
- data/lib/rkoans/checker.rb +62 -0
- data/lib/rkoans/cli.rb +79 -0
- data/lib/rkoans/error.rb +6 -0
- data/lib/rkoans/exercise.rb +50 -0
- data/lib/rkoans/keyboard.rb +51 -0
- data/lib/rkoans/progress.rb +39 -0
- data/lib/rkoans/selection.rb +31 -0
- data/lib/rkoans/session.rb +127 -0
- data/lib/rkoans/terminal_view.rb +99 -0
- data/lib/rkoans/version.rb +1 -1
- data/lib/rkoans/watcher.rb +58 -0
- data/lib/rkoans.rb +13 -3
- data/sig/about_array_assignment_acceptance_test.rbs +3 -0
- data/sig/about_arrays_acceptance_test.rbs +3 -0
- data/sig/about_asserts_command_test.rbs +4 -0
- data/sig/about_blocks_acceptance_test.rbs +3 -0
- data/sig/about_class_methods_acceptance_test.rbs +3 -0
- data/sig/about_classes_acceptance_test.rbs +3 -0
- data/sig/about_constants_acceptance_test.rbs +3 -0
- data/sig/about_control_statements_acceptance_test.rbs +3 -0
- data/sig/about_dice_project_acceptance_test.rbs +3 -0
- data/sig/about_exceptions_acceptance_test.rbs +3 -0
- data/sig/about_extra_credit_acceptance_test.rbs +5 -0
- data/sig/about_hashes_acceptance_test.rbs +3 -0
- data/sig/about_inheritance_acceptance_test.rbs +3 -0
- data/sig/about_iteration_acceptance_test.rbs +3 -0
- data/sig/about_keyword_arguments_acceptance_test.rbs +3 -0
- data/sig/about_message_passing_acceptance_test.rbs +3 -0
- data/sig/about_methods_acceptance_test.rbs +3 -0
- data/sig/about_modules_acceptance_test.rbs +3 -0
- data/sig/about_nil_acceptance_test.rbs +3 -0
- data/sig/about_objects_acceptance_test.rbs +3 -0
- data/sig/about_open_classes_acceptance_test.rbs +3 -0
- data/sig/about_pattern_matching_acceptance_test.rbs +3 -0
- data/sig/about_proxy_object_project_acceptance_test.rbs +3 -0
- data/sig/about_regular_expressions_acceptance_test.rbs +3 -0
- data/sig/about_sandwich_code_acceptance_test.rbs +3 -0
- data/sig/about_scope_acceptance_test.rbs +3 -0
- data/sig/about_scoring_project_acceptance_test.rbs +3 -0
- data/sig/about_strings_acceptance_test.rbs +3 -0
- data/sig/about_symbols_acceptance_test.rbs +3 -0
- data/sig/about_to_str_acceptance_test.rbs +3 -0
- data/sig/about_triangle_project_acceptance_test.rbs +3 -0
- data/sig/about_triangle_project_two_acceptance_test.rbs +3 -0
- data/sig/about_true_and_false_command_test.rbs +4 -0
- data/sig/catalog_error_command_test.rbs +4 -0
- data/sig/checker_test.rbs +9 -0
- data/sig/class_state_acceptance_test.rbs +3 -0
- data/sig/closure_capture_acceptance_test.rbs +3 -0
- data/sig/command_support.rbs +18 -0
- data/sig/command_test.rbs +5 -0
- data/sig/constant_scope_acceptance_test.rbs +3 -0
- data/sig/core_protocols_acceptance_test.rbs +3 -0
- data/sig/curriculum_cop_test.rbs +9 -0
- data/sig/delegation_acceptance_test.rbs +3 -0
- data/sig/dynamic_methods_acceptance_test.rbs +3 -0
- data/sig/exception_flow_acceptance_test.rbs +3 -0
- data/sig/exercise_test.rbs +3 -0
- data/sig/exercises/about_array_assignment.rbs +36 -0
- data/sig/exercises/about_arrays.rbs +51 -0
- data/sig/exercises/about_asserts.rbs +23 -0
- data/sig/exercises/about_blocks.rbs +40 -0
- data/sig/exercises/about_class_methods.rbs +62 -0
- data/sig/exercises/about_classes.rbs +88 -0
- data/sig/exercises/about_constants.rbs +53 -0
- data/sig/exercises/about_control_statements.rbs +46 -0
- data/sig/exercises/about_dice_project.rbs +16 -0
- data/sig/exercises/about_exceptions.rbs +36 -0
- data/sig/exercises/about_extra_credit.rbs +36 -0
- data/sig/exercises/about_hashes.rbs +62 -0
- data/sig/exercises/about_inheritance.rbs +50 -0
- data/sig/exercises/about_iteration.rbs +37 -0
- data/sig/exercises/about_keyword_arguments.rbs +33 -0
- data/sig/exercises/about_message_passing.rbs +68 -0
- data/sig/exercises/about_methods.rbs +68 -0
- data/sig/exercises/about_modules.rbs +38 -0
- data/sig/exercises/about_nil.rbs +23 -0
- data/sig/exercises/about_objects.rbs +38 -0
- data/sig/exercises/about_open_classes.rbs +31 -0
- data/sig/exercises/about_pattern_matching.rbs +65 -0
- data/sig/exercises/about_proxy_object_project.rbs +31 -0
- data/sig/exercises/about_regular_expressions.rbs +83 -0
- data/sig/exercises/about_sandwich_code.rbs +17 -0
- data/sig/exercises/about_scope.rbs +59 -0
- data/sig/exercises/about_scoring_project.rbs +16 -0
- data/sig/exercises/about_strings.rbs +85 -0
- data/sig/exercises/about_symbols.rbs +46 -0
- data/sig/exercises/about_to_str.rbs +36 -0
- data/sig/exercises/about_triangle_project.rbs +11 -0
- data/sig/exercises/about_triangle_project_two.rbs +12 -0
- data/sig/exercises/about_true_and_false.rbs +27 -0
- data/sig/exercises/blocks_and_methods.rbs +11 -0
- data/sig/exercises/class_state.rbs +19 -0
- data/sig/exercises/closure_capture.rbs +10 -0
- data/sig/exercises/collection_basics.rbs +6 -0
- data/sig/exercises/collection_basics_test.rbs +4 -0
- data/sig/exercises/constant_scope.rbs +11 -0
- data/sig/exercises/core_protocols.rbs +20 -0
- data/sig/exercises/delegation.rbs +14 -0
- data/sig/exercises/dynamic_methods.rbs +13 -0
- data/sig/exercises/exception_flow.rbs +11 -0
- data/sig/exercises/heredoc_layout.rbs +11 -0
- data/sig/exercises/keyword_forwarding.rbs +12 -0
- data/sig/exercises/lazy_enumeration.rbs +10 -0
- data/sig/exercises/literals_and_operators.rbs +12 -0
- data/sig/exercises/method_contracts.rbs +11 -0
- data/sig/exercises/method_lookup.rbs +16 -0
- data/sig/exercises/nonlocal_exit.rbs +14 -0
- data/sig/exercises/numbered_parameters.rbs +11 -0
- data/sig/exercises/numeric_precision.rbs +11 -0
- data/sig/exercises/pattern_matching.rbs +10 -0
- data/sig/exercises/refinement_scope.rbs +18 -0
- data/sig/exercises/regexp_captures.rbs +11 -0
- data/sig/exercises/runtime_context.rbs +23 -0
- data/sig/exercises/shared_rows.rbs +11 -0
- data/sig/exercises/singleton_pattern.rbs +14 -0
- data/sig/exercises/time_and_date.rbs +11 -0
- data/sig/exercises/visibility.rbs +18 -0
- data/sig/fixture_support.rbs +11 -0
- data/sig/help_hint_command_test.rbs +8 -0
- data/sig/heredoc_layout_acceptance_test.rbs +3 -0
- data/sig/keyboard_session_test.rbs +9 -0
- data/sig/keyword_forwarding_acceptance_test.rbs +3 -0
- data/sig/lazy_enumeration_acceptance_test.rbs +3 -0
- data/sig/literals_and_operators_acceptance_test.rbs +3 -0
- data/sig/method_contracts_acceptance_test.rbs +3 -0
- data/sig/method_lookup_acceptance_test.rbs +3 -0
- data/sig/nonlocal_exit_acceptance_test.rbs +3 -0
- data/sig/numbered_parameters_acceptance_test.rbs +3 -0
- data/sig/numeric_precision_acceptance_test.rbs +4 -0
- data/sig/packaging_test.rbs +3 -0
- data/sig/pattern_matching_acceptance_test.rbs +3 -0
- data/sig/reference_solutions_test.rbs +3 -0
- data/sig/refinement_scope_acceptance_test.rbs +3 -0
- data/sig/regexp_captures_acceptance_test.rbs +4 -0
- data/sig/rkoans/catalog.rbs +11 -0
- data/sig/rkoans/checker.rbs +22 -0
- data/sig/rkoans/cli.rbs +21 -0
- data/sig/rkoans/exercise.rbs +18 -0
- data/sig/rkoans/keyboard.rbs +13 -0
- data/sig/rkoans/progress.rbs +9 -0
- data/sig/rkoans/selection.rbs +9 -0
- data/sig/rkoans/session.rbs +30 -0
- data/sig/rkoans/terminal_view.rbs +24 -0
- data/sig/rkoans/watcher.rbs +18 -0
- data/sig/rkoans.rbs +2 -0
- data/sig/runtime_context_command_test.rbs +4 -0
- data/sig/selection_command_test.rbs +5 -0
- data/sig/session_command_test.rbs +12 -0
- data/sig/session_edge_cases_test.rbs +4 -0
- data/sig/shared_rows_acceptance_test.rbs +3 -0
- data/sig/singleton_pattern_acceptance_test.rbs +3 -0
- data/sig/time_and_date_acceptance_test.rbs +4 -0
- data/sig/visibility_acceptance_test.rbs +4 -0
- data/sig/watcher_test.rbs +3 -0
- data/solutions/about-array-assignment/about_array_assignment.rb +36 -0
- data/solutions/about-arrays/about_arrays.rb +53 -0
- data/solutions/about-asserts/about_asserts.rb +22 -0
- data/solutions/about-blocks/about_blocks.rb +30 -0
- data/solutions/about-class-methods/about_class_methods.rb +36 -0
- data/solutions/about-classes/about_classes.rb +40 -0
- data/solutions/about-constants/about_constants.rb +26 -0
- data/solutions/about-control-statements/about_control_statements.rb +35 -0
- data/solutions/about-dice-project/about_dice_project.rb +27 -0
- data/solutions/about-exceptions/about_exceptions.rb +30 -0
- data/solutions/about-extra-credit/about_extra_credit.rb +114 -0
- data/solutions/about-hashes/about_hashes.rb +52 -0
- data/solutions/about-inheritance/about_inheritance.rb +27 -0
- data/solutions/about-iteration/about_iteration.rb +31 -0
- data/solutions/about-keyword-arguments/about_keyword_arguments.rb +28 -0
- data/solutions/about-message-passing/about_message_passing.rb +38 -0
- data/solutions/about-methods/about_methods.rb +39 -0
- data/solutions/about-modules/about_modules.rb +23 -0
- data/solutions/about-nil/about_nil.rb +23 -0
- data/solutions/about-objects/about_objects.rb +34 -0
- data/solutions/about-open-classes/about_open_classes.rb +23 -0
- data/solutions/about-pattern-matching/about_pattern_matching.rb +39 -0
- data/solutions/about-proxy-object-project/about_proxy_object_project.rb +44 -0
- data/solutions/about-regular-expressions/about_regular_expressions.rb +60 -0
- data/solutions/about-sandwich-code/about_sandwich_code.rb +60 -0
- data/solutions/about-scope/about_scope.rb +33 -0
- data/solutions/about-scoring-project/about_scoring_project.rb +19 -0
- data/solutions/about-strings/about_strings.rb +56 -0
- data/solutions/about-symbols/about_symbols.rb +35 -0
- data/solutions/about-to-str/about_to_str.rb +24 -0
- data/solutions/about-triangle-project/about_triangle_project.rb +19 -0
- data/solutions/about-triangle-project-two/about_triangle_project_two.rb +25 -0
- data/solutions/about-true-and-false/about_true_and_false.rb +25 -0
- data/solutions/blocks-and-methods/blocks_and_methods.rb +14 -0
- data/solutions/class-state/class_state.rb +33 -0
- data/solutions/closure-capture/closure_capture.rb +12 -0
- data/solutions/collection-basics/collection_basics.rb +14 -0
- data/solutions/constant-scope/constant_scope.rb +18 -0
- data/solutions/core-protocols/core_protocols.rb +44 -0
- data/solutions/delegation/delegation.rb +17 -0
- data/solutions/dynamic-methods/dynamic_methods.rb +32 -0
- data/solutions/exception-flow/exception_flow.rb +34 -0
- data/solutions/heredoc-layout/heredoc_layout.rb +24 -0
- data/solutions/keyword-forwarding/keyword_forwarding.rb +26 -0
- data/solutions/lazy-enumeration/lazy_enumeration.rb +11 -0
- data/solutions/literals-and-operators/literals_and_operators.rb +22 -0
- data/solutions/method-contracts/method_contracts.rb +18 -0
- data/solutions/method-lookup/method_lookup.rb +26 -0
- data/solutions/nonlocal-exit/nonlocal_exit.rb +46 -0
- data/solutions/numbered-parameters/numbered_parameters.rb +18 -0
- data/solutions/numeric-precision/numeric_precision.rb +17 -0
- data/solutions/pattern-matching/pattern_matching.rb +17 -0
- data/solutions/refinement-scope/refinement_scope.rb +34 -0
- data/solutions/regexp-captures/regexp_captures.rb +24 -0
- data/solutions/runtime-context/runtime_context.rb +19 -0
- data/solutions/shared-rows/shared_rows.rb +13 -0
- data/solutions/singleton-pattern/singleton_pattern.rb +19 -0
- data/solutions/time-and-date/time_and_date.rb +16 -0
- data/solutions/visibility/visibility.rb +34 -0
- data/test/exercises/about_array_assignment_test.rb +87 -0
- data/test/exercises/about_arrays_test.rb +119 -0
- data/test/exercises/about_asserts_test.rb +41 -0
- data/test/exercises/about_blocks_test.rb +140 -0
- data/test/exercises/about_class_methods_test.rb +232 -0
- data/test/exercises/about_classes_test.rb +261 -0
- data/test/exercises/about_constants_test.rb +111 -0
- data/test/exercises/about_control_statements_test.rb +188 -0
- data/test/exercises/about_dice_project_test.rb +40 -0
- data/test/exercises/about_exceptions_test.rb +98 -0
- data/test/exercises/about_extra_credit_test.rb +74 -0
- data/test/exercises/about_hashes_test.rb +163 -0
- data/test/exercises/about_inheritance_test.rb +121 -0
- data/test/exercises/about_iteration_test.rb +148 -0
- data/test/exercises/about_keyword_arguments_test.rb +80 -0
- data/test/exercises/about_message_passing_test.rb +230 -0
- data/test/exercises/about_methods_test.rb +208 -0
- data/test/exercises/about_modules_test.rb +98 -0
- data/test/exercises/about_nil_test.rb +35 -0
- data/test/exercises/about_objects_test.rb +74 -0
- data/test/exercises/about_open_classes_test.rb +60 -0
- data/test/exercises/about_pattern_matching_test.rb +257 -0
- data/test/exercises/about_proxy_object_project_test.rb +75 -0
- data/test/exercises/about_regular_expressions_test.rb +243 -0
- data/test/exercises/about_sandwich_code_test.rb +82 -0
- data/test/exercises/about_scope_test.rb +123 -0
- data/test/exercises/about_scoring_project_test.rb +62 -0
- data/test/exercises/about_strings_test.rb +255 -0
- data/test/exercises/about_symbols_test.rb +120 -0
- data/test/exercises/about_to_str_test.rb +89 -0
- data/test/exercises/about_triangle_project_test.rb +29 -0
- data/test/exercises/about_triangle_project_two_test.rb +28 -0
- data/test/exercises/about_true_and_false_test.rb +43 -0
- data/test/exercises/blocks_and_methods_test.rb +22 -0
- data/test/exercises/class_state_test.rb +29 -0
- data/test/exercises/closure_capture_test.rb +29 -0
- data/test/exercises/collection_basics_test.rb +18 -0
- data/test/exercises/constant_scope_test.rb +18 -0
- data/test/exercises/core_protocols_test.rb +28 -0
- data/test/exercises/delegation_test.rb +23 -0
- data/test/exercises/dynamic_methods_test.rb +28 -0
- data/test/exercises/exception_flow_test.rb +17 -0
- data/test/exercises/heredoc_layout_test.rb +18 -0
- data/test/exercises/keyword_forwarding_test.rb +22 -0
- data/test/exercises/lazy_enumeration_test.rb +15 -0
- data/test/exercises/literals_and_operators_test.rb +25 -0
- data/test/exercises/method_contracts_test.rb +28 -0
- data/test/exercises/method_lookup_test.rb +14 -0
- data/test/exercises/nonlocal_exit_test.rb +22 -0
- data/test/exercises/numbered_parameters_test.rb +15 -0
- data/test/exercises/numeric_precision_test.rb +24 -0
- data/test/exercises/pattern_matching_test.rb +18 -0
- data/test/exercises/refinement_scope_test.rb +14 -0
- data/test/exercises/regexp_captures_test.rb +20 -0
- data/test/exercises/runtime_context_test.rb +59 -0
- data/test/exercises/shared_rows_test.rb +34 -0
- data/test/exercises/singleton_pattern_test.rb +16 -0
- data/test/exercises/time_and_date_test.rb +22 -0
- data/test/exercises/visibility_test.rb +22 -0
- metadata +471 -4
- data/Rakefile +0 -12
- 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
|