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