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,89 @@
|
|
|
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
|
+
require 'tmpdir'
|
|
9
|
+
|
|
10
|
+
class AboutToStrTest < Minitest::Test
|
|
11
|
+
class CanNotBeTreatedAsString
|
|
12
|
+
# Demonstrates to s.
|
|
13
|
+
def to_s
|
|
14
|
+
'non-string-like'
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks to s returns a string representation.
|
|
19
|
+
def test_to_s_returns_a_string_representation
|
|
20
|
+
not_like_a_string = CanNotBeTreatedAsString.new
|
|
21
|
+
|
|
22
|
+
assert_equal Exercises::AboutToStr.koans.fetch(:to_s_returns_a_string_representation_one), not_like_a_string.to_s
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Checks normally objects cannot be used where strings are expected.
|
|
26
|
+
def test_normally_objects_cannot_be_used_where_strings_are_expected
|
|
27
|
+
assert_predicted_error(:normally_objects_cannot_be_used_where_strings_are_expected_one, ::TypeError) do
|
|
28
|
+
File.exist?(CanNotBeTreatedAsString.new)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# ------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
class CanBeTreatedAsString
|
|
35
|
+
# Demonstrates to s.
|
|
36
|
+
def to_s
|
|
37
|
+
'string-like'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Demonstrates to str.
|
|
41
|
+
def to_str
|
|
42
|
+
to_s
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Checks to str also returns a string representation.
|
|
47
|
+
def test_to_str_also_returns_a_string_representation
|
|
48
|
+
like_a_string = CanBeTreatedAsString.new
|
|
49
|
+
|
|
50
|
+
assert_equal Exercises::AboutToStr.koans.fetch(:to_str_also_returns_a_string_representation_one),
|
|
51
|
+
like_a_string.to_str
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Checks to str allows objects to be treated as strings.
|
|
55
|
+
def test_to_str_allows_objects_to_be_treated_as_strings
|
|
56
|
+
Dir.mktmpdir do |directory|
|
|
57
|
+
Dir.chdir(directory) do
|
|
58
|
+
assert_equal Exercises::AboutToStr.koans.fetch(:to_str_allows_objects_to_be_treated_as_strings_one),
|
|
59
|
+
File.exist?(CanBeTreatedAsString.new)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# ------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
# Demonstrates acts like a string?.
|
|
67
|
+
def acts_like_a_string?(string)
|
|
68
|
+
string = string.to_str if string.respond_to?(:to_str)
|
|
69
|
+
string.is_a?(String)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Checks user defined code can check for to str.
|
|
73
|
+
def test_user_defined_code_can_check_for_to_str
|
|
74
|
+
assert_equal Exercises::AboutToStr.koans.fetch(:user_defined_code_can_check_for_to_str_one),
|
|
75
|
+
acts_like_a_string?(CanNotBeTreatedAsString.new)
|
|
76
|
+
assert_equal Exercises::AboutToStr.koans.fetch(:user_defined_code_can_check_for_to_str_two),
|
|
77
|
+
acts_like_a_string?(CanBeTreatedAsString.new)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Checks the predicted exception class while returning the captured error.
|
|
81
|
+
# @param key [Symbol] answer field
|
|
82
|
+
# @param klass [Class<Exception>] exception raised by the example
|
|
83
|
+
# @return [Exception]
|
|
84
|
+
def assert_predicted_error(key, ...)
|
|
85
|
+
error = assert_raises(...)
|
|
86
|
+
assert_equal Exercises::AboutToStr.koans.fetch(key), error.class
|
|
87
|
+
error
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
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 AboutTriangleProjectTest < Minitest::Test
|
|
10
|
+
# All equal sides make an equilateral triangle, regardless of scale.
|
|
11
|
+
def test_equilateral_triangles_have_equal_sides
|
|
12
|
+
assert_equal :equilateral, Exercises::AboutTriangleProject.triangle(2, 2, 2)
|
|
13
|
+
assert_equal :equilateral, Exercises::AboutTriangleProject.triangle(10, 10, 10)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# The equal pair may appear in any positions.
|
|
17
|
+
def test_isosceles_triangles_have_exactly_two_sides_equal
|
|
18
|
+
[[3, 4, 4], [4, 3, 4], [4, 4, 3], [10, 10, 2]].each do |sides|
|
|
19
|
+
assert_equal :isosceles, Exercises::AboutTriangleProject.triangle(*sides)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Distinct valid sides make a scalene triangle.
|
|
24
|
+
def test_scalene_triangles_have_no_equal_sides
|
|
25
|
+
[[3, 4, 5], [10, 11, 12], [5, 4, 2]].each do |sides|
|
|
26
|
+
assert_equal :scalene, Exercises::AboutTriangleProject.triangle(*sides)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
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 AboutTriangleProjectTwoTest < Minitest::Test
|
|
10
|
+
# Reject nonpositive lengths and both sides of the triangle-inequality boundary.
|
|
11
|
+
def test_illegal_triangles_throw_exceptions
|
|
12
|
+
[[0, 0, 0], [3, 4, -5], [1, 1, 3], [2, 4, 2], [0, 1, 1]].each do |sides|
|
|
13
|
+
sides.permutation.to_a.uniq.each do |ordered|
|
|
14
|
+
assert_raises(Exercises::AboutTriangleProjectTwo::TriangleError) do
|
|
15
|
+
Exercises::AboutTriangleProjectTwo.triangle(*ordered)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Validation must preserve the classification behavior from part one.
|
|
22
|
+
def test_valid_triangles_keep_their_classification
|
|
23
|
+
assert_equal :equilateral, Exercises::AboutTriangleProjectTwo.triangle(2, 2, 2)
|
|
24
|
+
assert_equal :isosceles, Exercises::AboutTriangleProjectTwo.triangle(3, 4, 4)
|
|
25
|
+
assert_equal :scalene, Exercises::AboutTriangleProjectTwo.triangle(3, 4, 5)
|
|
26
|
+
assert_equal :isosceles, Exercises::AboutTriangleProjectTwo.triangle(1, 1, 1.5)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
# Keeps the original truthiness examples and their independently evaluated branches.
|
|
10
|
+
class AboutTrueAndFalseTest < Minitest::Test
|
|
11
|
+
# @param condition [Object] value tested by Ruby's ordinary if statement
|
|
12
|
+
# @return [Symbol] branch selected by Ruby
|
|
13
|
+
def truth_value(condition)
|
|
14
|
+
if condition
|
|
15
|
+
:true_stuff
|
|
16
|
+
else
|
|
17
|
+
:false_stuff
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# True selects the truthy branch.
|
|
22
|
+
def test_true_is_treated_as_true
|
|
23
|
+
assert_equal Exercises::AboutTrueAndFalse.koans[:true_value], truth_value(true)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# False selects the falsey branch.
|
|
27
|
+
def test_false_is_treated_as_false
|
|
28
|
+
assert_equal Exercises::AboutTrueAndFalse.koans[:false_value], truth_value(false)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Nil selects the same branch as false.
|
|
32
|
+
def test_nil_is_treated_as_false_too
|
|
33
|
+
assert_equal Exercises::AboutTrueAndFalse.koans[:nil_value], truth_value(nil)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Zero and empty containers are truthy, just like other ordinary objects.
|
|
37
|
+
def test_everything_else_is_treated_as_true
|
|
38
|
+
values = { one: 1, zero: 0, empty_array: [], empty_hash: {}, string: 'Strings', empty_string: '' }
|
|
39
|
+
answers = Exercises::AboutTrueAndFalse.koans
|
|
40
|
+
|
|
41
|
+
values.each { |key, value| assert_equal answers[key], truth_value(value), "Branch for #{key}" }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
|
|
5
|
+
# Checks the learner's sequence and the block invocation contract.
|
|
6
|
+
class BlocksAndMethodsTest < Minitest::Test
|
|
7
|
+
def test_block_koan
|
|
8
|
+
assert_equal [1, 2, 3], Exercises::BlocksAndMethods.koans[:sequence]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_apply_block
|
|
12
|
+
count = 0
|
|
13
|
+
result = Exercises::BlocksAndMethods.apply(5) do |number|
|
|
14
|
+
count += 1
|
|
15
|
+
number * 3
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
assert_equal 15, result
|
|
19
|
+
assert_equal 1, count
|
|
20
|
+
assert_raises(LocalJumpError) { Exercises::BlocksAndMethods.apply(5) }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The examples contrast block forms and their behavior.
|
|
4
|
+
# rubocop:disable Style/BlockDelimiters
|
|
5
|
+
|
|
6
|
+
require ARGV.shift
|
|
7
|
+
class ClassStateTest < Minitest::Test
|
|
8
|
+
# Checks independent class instance state.
|
|
9
|
+
def test_independent_class_instance_state
|
|
10
|
+
Exercises::ClassState::Parent.reset
|
|
11
|
+
Exercises::ClassState::Child.reset
|
|
12
|
+
2.times {
|
|
13
|
+
Exercises::ClassState::Parent.increment
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
Exercises::ClassState::Child.increment
|
|
17
|
+
|
|
18
|
+
assert_equal 2, Exercises::ClassState::Parent.count
|
|
19
|
+
assert_equal 1, Exercises::ClassState::Child.count
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Checks class inheritance and singleton.
|
|
23
|
+
def test_class_inheritance_and_singleton
|
|
24
|
+
assert_equal 'parent-child', Exercises::ClassState::Child.label
|
|
25
|
+
assert_equal Exercises::ClassState::Parent.singleton_class, Exercises::ClassState.singleton_owner
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# rubocop:enable Style/BlockDelimiters
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The examples contrast block forms and their behavior.
|
|
4
|
+
# rubocop:disable Style/BlockDelimiters
|
|
5
|
+
|
|
6
|
+
require ARGV.shift
|
|
7
|
+
class ClosureCaptureTest < Minitest::Test
|
|
8
|
+
# Checks separate captures.
|
|
9
|
+
def test_separate_captures
|
|
10
|
+
functions = Exercises::ClosureCapture.multipliers([2, 3, 4])
|
|
11
|
+
|
|
12
|
+
assert_equal([10, 15, 20], functions.map { |f|
|
|
13
|
+
f.call(5)
|
|
14
|
+
})
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Checks lambda contract.
|
|
18
|
+
def test_lambda_contract
|
|
19
|
+
f = Exercises::ClosureCapture.multipliers([2]).first
|
|
20
|
+
|
|
21
|
+
assert_predicate f, :lambda?
|
|
22
|
+
assert_raises(ArgumentError) {
|
|
23
|
+
f.call(5, 6)
|
|
24
|
+
}
|
|
25
|
+
assert_equal [], Exercises::ClosureCapture.multipliers([])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# rubocop:enable Style/BlockDelimiters
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
|
|
5
|
+
# Checks the learner's expectations and the double_odds contract.
|
|
6
|
+
class CollectionBasicsTest < Minitest::Test
|
|
7
|
+
def test_collection_koans
|
|
8
|
+
assert_equal({ mapped: [2, 4, 6], selected: [1, 3] }, Exercises::CollectionBasics.koans)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_double_odds
|
|
12
|
+
input = [1, 2, 3]
|
|
13
|
+
|
|
14
|
+
assert_equal [2, 6], Exercises::CollectionBasics.double_odds(input)
|
|
15
|
+
assert_equal [1, 2, 3], input
|
|
16
|
+
assert_empty Exercises::CollectionBasics.double_odds([])
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class ConstantScopeTest < Minitest::Test
|
|
5
|
+
# Checks scope predictions.
|
|
6
|
+
def test_scope_predictions
|
|
7
|
+
assert_equal({ lexical_label: 'item', shared_class_count: 1, new_block_local_visible: false }, Exercises::ConstantScope.predictions)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Checks local closure state.
|
|
11
|
+
def test_local_closure_state
|
|
12
|
+
a = Exercises::ConstantScope.counter
|
|
13
|
+
|
|
14
|
+
b = Exercises::ConstantScope.counter
|
|
15
|
+
|
|
16
|
+
assert_equal [1, 2, 1], [a.call, a.call, b.call]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The examples contrast block forms and their behavior.
|
|
4
|
+
# rubocop:disable Style/BlockDelimiters
|
|
5
|
+
|
|
6
|
+
require ARGV.shift
|
|
7
|
+
class CoreProtocolsTest < Minitest::Test
|
|
8
|
+
# Checks enumerable protocol.
|
|
9
|
+
def test_enumerable_protocol
|
|
10
|
+
p = Exercises::CoreProtocols::Packet.new([2, 3]); assert_equal([4, 6], p.map { |n|
|
|
11
|
+
n * 2
|
|
12
|
+
})
|
|
13
|
+
assert_equal [2, 3], p.each.to_a
|
|
14
|
+
assert_equal [true, true], Exercises::CoreProtocols.protocol(p)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Checks comparable and conversion.
|
|
18
|
+
def test_comparable_and_conversion
|
|
19
|
+
a = Exercises::CoreProtocols::Packet.new([1])
|
|
20
|
+
b = Exercises::CoreProtocols::Packet.new([2, 3])
|
|
21
|
+
|
|
22
|
+
assert_operator a, :<, b
|
|
23
|
+
assert_equal 'Packet(5)', b.to_s
|
|
24
|
+
assert_equal [a, b], [b, a].sort
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# rubocop:enable Style/BlockDelimiters
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class DelegationTest < Minitest::Test
|
|
5
|
+
# Checks delegation receiver.
|
|
6
|
+
def test_delegation_receiver
|
|
7
|
+
items = []
|
|
8
|
+
box = Exercises::Delegation::Mailbox.new(items)
|
|
9
|
+
|
|
10
|
+
assert_same items, box.push('ruby')
|
|
11
|
+
assert_equal ['ruby'], items
|
|
12
|
+
assert_equal 1, box.size
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Checks live receiver.
|
|
16
|
+
def test_live_receiver
|
|
17
|
+
items = []
|
|
18
|
+
box = Exercises::Delegation::Mailbox.new(items)
|
|
19
|
+
items << 'rails'
|
|
20
|
+
|
|
21
|
+
assert_equal 1, box.size
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class DynamicMethodsTest < Minitest::Test
|
|
5
|
+
# Checks defined reader closures.
|
|
6
|
+
def test_defined_reader_closures
|
|
7
|
+
klass = Exercises::DynamicMethods.readers(%i[left right])
|
|
8
|
+
obj = klass.new
|
|
9
|
+
|
|
10
|
+
obj.instance_variable_set(:@left, 10)
|
|
11
|
+
obj.instance_variable_set(:@right, 20)
|
|
12
|
+
|
|
13
|
+
assert_equal [10, 20], [obj.left, obj.right]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Checks eval binding and reflection.
|
|
17
|
+
def test_eval_binding_and_reflection
|
|
18
|
+
assert_equal 8, Exercises::DynamicMethods.evaluate(4)
|
|
19
|
+
obj = Object.new
|
|
20
|
+
|
|
21
|
+
obj.instance_variable_set(:@token, :ruby)
|
|
22
|
+
|
|
23
|
+
assert_equal :ruby, Exercises::DynamicMethods.instance_value(obj, :token)
|
|
24
|
+
klass = Exercises::DynamicMethods.readers([])
|
|
25
|
+
|
|
26
|
+
assert_equal klass, Exercises::DynamicMethods.class_value(klass)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class ExceptionFlowTest < Minitest::Test
|
|
5
|
+
# Checks ensure and else.
|
|
6
|
+
def test_ensure_and_else
|
|
7
|
+
assert_equal %w[work else ensure], Exercises::ExceptionFlow.trace(fail: false)
|
|
8
|
+
|
|
9
|
+
assert_equal %w[work rescue ensure], Exercises::ExceptionFlow.trace(fail: true)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Checks reraise.
|
|
13
|
+
def test_reraise
|
|
14
|
+
error = assert_raises(ArgumentError) { Exercises::ExceptionFlow.reraises }
|
|
15
|
+
assert_equal 'original', error.message
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
|
|
5
|
+
# Checks exact output bytes without deriving expectations from the learner's code.
|
|
6
|
+
class HeredocLayoutTest < Minitest::Test
|
|
7
|
+
# Common indentation is stripped; relative spaces and newlines remain intact.
|
|
8
|
+
def test_squiggly_indentation
|
|
9
|
+
assert_equal "Hello Ada\n Ruby\n", Exercises::HeredocLayout.render('Ada')
|
|
10
|
+
assert_equal "Hello Bea\n Ruby\n", Exercises::HeredocLayout.render('Bea')
|
|
11
|
+
assert_equal "Hello \n Ruby\n", Exercises::HeredocLayout.render('')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Quoting the delimiter prevents interpolation without dropping the final newline.
|
|
15
|
+
def test_quoted_heredoc
|
|
16
|
+
assert_equal "Hello \#{name}\n", Exercises::HeredocLayout.literal
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Explicit callable arguments demonstrate block and proc behavior.
|
|
4
|
+
# rubocop:disable Style/SymbolProc
|
|
5
|
+
|
|
6
|
+
require ARGV.shift
|
|
7
|
+
class KeywordForwardingTest < Minitest::Test
|
|
8
|
+
# Checks keyword and block.
|
|
9
|
+
def test_keyword_and_block
|
|
10
|
+
assert_equal 'RUBY!', Exercises::KeywordForwarding.forward('ruby', suffix: '!') { |v|
|
|
11
|
+
v.upcase
|
|
12
|
+
}
|
|
13
|
+
assert_equal 'ruby?', Exercises::KeywordForwarding.forward('ruby')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Checks positional hash.
|
|
17
|
+
def test_positional_hash
|
|
18
|
+
assert_equal 'rails!', Exercises::KeywordForwarding.forward({ name: 'rails' }, suffix: '!') { |payload| payload.fetch(:name) }
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# rubocop:enable Style/SymbolProc
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class LazyEnumerationTest < Minitest::Test
|
|
5
|
+
# Checks lazy limit.
|
|
6
|
+
def test_lazy_limit
|
|
7
|
+
assert_equal [7, 14], Exercises::LazyEnumeration.first_multiples(2)
|
|
8
|
+
assert_equal [7, 14, 21, 28], Exercises::LazyEnumeration.first_multiples(4)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Checks empty limit.
|
|
12
|
+
def test_empty_limit
|
|
13
|
+
assert_equal [], Exercises::LazyEnumeration.first_multiples(0)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class LiteralsAndOperatorsTest < Minitest::Test
|
|
5
|
+
# Checks literals and precedence.
|
|
6
|
+
def test_literals_and_precedence
|
|
7
|
+
assert_equal({
|
|
8
|
+
zero_truthy: true,
|
|
9
|
+
integer_division: 2,
|
|
10
|
+
float_division: 2.5,
|
|
11
|
+
precedence: 7,
|
|
12
|
+
not_nil: true,
|
|
13
|
+
words: %w[ruby rails],
|
|
14
|
+
range: [1, 2, 3]
|
|
15
|
+
}, Exercises::LiteralsAndOperators.predictions)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks short circuit default.
|
|
19
|
+
def test_short_circuit_default
|
|
20
|
+
assert_equal false, Exercises::LiteralsAndOperators.default_for_nil(false) # rubocop:disable Minitest/RefuteFalse
|
|
21
|
+
|
|
22
|
+
assert_equal 0, Exercises::LiteralsAndOperators.default_for_nil(0)
|
|
23
|
+
assert_equal 'missing', Exercises::LiteralsAndOperators.default_for_nil(nil)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The original descriptive check identifiers and example strings remain intact.
|
|
4
|
+
# The examples contrast block forms and their behavior.
|
|
5
|
+
# Explicit callable arguments demonstrate block and proc behavior.
|
|
6
|
+
# rubocop:disable Layout/LineLength, Style/BlockDelimiters, Style/SymbolProc
|
|
7
|
+
|
|
8
|
+
require ARGV.shift
|
|
9
|
+
class MethodContractsTest < Minitest::Test
|
|
10
|
+
# Checks method defaults and block.
|
|
11
|
+
def test_method_defaults_and_block
|
|
12
|
+
assert_equal 'tea:1:box:0:normal', Exercises::MethodContracts.format_order('tea', unit: 'box')
|
|
13
|
+
assert_equal 'TEA:2:BOX:1:HIGH', Exercises::MethodContracts.format_order('tea', 2, :gift, unit: 'box', priority: 'high') { |v|
|
|
14
|
+
v.upcase
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks parameter metadata.
|
|
19
|
+
def test_parameter_metadata
|
|
20
|
+
assert_equal [%i[req name], %i[opt quantity], %i[rest extras], %i[keyreq unit], %i[keyrest options], %i[block block]],
|
|
21
|
+
Exercises::MethodContracts.parameters
|
|
22
|
+
assert_raises(ArgumentError) {
|
|
23
|
+
Exercises::MethodContracts.format_order('tea')
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# rubocop:enable Layout/LineLength, Style/BlockDelimiters, Style/SymbolProc
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class MethodLookupTest < Minitest::Test
|
|
5
|
+
# Checks prepend wrapper.
|
|
6
|
+
def test_prepend_wrapper
|
|
7
|
+
assert_equal '[base]', Exercises::MethodLookup::Presenter.new.call
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Checks ancestor order.
|
|
11
|
+
def test_ancestor_order
|
|
12
|
+
assert_equal ['Exercises::MethodLookup::Wrapper', 'Exercises::MethodLookup::Presenter'], Exercises::MethodLookup.lookup
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class NonlocalExitTest < Minitest::Test
|
|
5
|
+
# Checks lambda return scope.
|
|
6
|
+
def test_lambda_return_scope
|
|
7
|
+
assert_equal %w[inside after], Exercises::NonlocalExit.lambda_trace
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Checks proc nonlocal return.
|
|
11
|
+
def test_proc_nonlocal_return
|
|
12
|
+
assert_raises(LocalJumpError) { Exercises::NonlocalExit.escaped_proc.call }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Checks catch throw and next.
|
|
16
|
+
def test_catch_throw_and_next
|
|
17
|
+
assert_equal 4, Exercises::NonlocalExit.find_even([[1, 3], [4, 6]])
|
|
18
|
+
assert_nil Exercises::NonlocalExit.find_even([[1], [3]])
|
|
19
|
+
|
|
20
|
+
assert_equal [2, 4], Exercises::NonlocalExit.skip_odds([1, 2, 3, 4])
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class NumberedParametersTest < Minitest::Test
|
|
5
|
+
# Checks numbered pair input.
|
|
6
|
+
def test_numbered_pair_input
|
|
7
|
+
assert_equal [5, 9], Exercises::NumberedParameters.pair_sums([[2, 3], [4, 5]])
|
|
8
|
+
assert_equal [], Exercises::NumberedParameters.pair_sums([])
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Checks numbered syntax.
|
|
12
|
+
def test_numbered_syntax
|
|
13
|
+
assert_equal({ explicit_and_numbered: false, numbered_pair: true }, Exercises::NumberedParameters.predictions)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class NumericPrecisionTest < Minitest::Test
|
|
5
|
+
# Checks numeric division.
|
|
6
|
+
def test_numeric_division
|
|
7
|
+
result = Exercises::NumericPrecision.ratios(1, 3)
|
|
8
|
+
|
|
9
|
+
assert_instance_of Integer, result[:integer]
|
|
10
|
+
assert_equal 0, result[:integer]
|
|
11
|
+
assert_instance_of Float, result[:floating]
|
|
12
|
+
assert_in_delta 1.0 / 3, result[:floating], 1e-12
|
|
13
|
+
assert_instance_of Rational, result[:rational]
|
|
14
|
+
assert_equal Rational(4, 3), result[:rational] + 1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Checks complex product.
|
|
18
|
+
def test_complex_product
|
|
19
|
+
product = Exercises::NumericPrecision.imaginary_product(2, 3)
|
|
20
|
+
|
|
21
|
+
assert_instance_of Complex, product
|
|
22
|
+
assert_equal Complex(-6, 0), product
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class PatternMatchingTest < Minitest::Test
|
|
5
|
+
# Checks pinned kind.
|
|
6
|
+
def test_pinned_kind
|
|
7
|
+
assert_equal 5, Exercises::PatternMatching.amount({ type: 'sale', amount: 5, extra: true }, 'sale')
|
|
8
|
+
assert_nil Exercises::PatternMatching.amount({ type: 'refund', amount: 5 }, 'sale')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Checks pattern guard.
|
|
12
|
+
def test_pattern_guard
|
|
13
|
+
assert_nil Exercises::PatternMatching.amount({ type: 'sale', amount: 0 }, 'sale')
|
|
14
|
+
|
|
15
|
+
assert_nil Exercises::PatternMatching.amount({ type: 'sale', amount: '5' }, 'sale')
|
|
16
|
+
assert_nil Exercises::PatternMatching.amount({}, 'sale')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class RefinementScopeTest < Minitest::Test
|
|
5
|
+
# Checks lexical refinement.
|
|
6
|
+
def test_lexical_refinement
|
|
7
|
+
assert_equal 'local', Exercises::RefinementScope::Local.call
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Checks outside unchanged.
|
|
11
|
+
def test_outside_unchanged
|
|
12
|
+
assert_equal 'plain', Exercises::RefinementScope.outside
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require ARGV.shift
|
|
4
|
+
class RegexpCapturesTest < Minitest::Test
|
|
5
|
+
# Checks whole string and captures.
|
|
6
|
+
def test_whole_string_and_captures
|
|
7
|
+
parsed = Exercises::RegexpCaptures.parse('ruby:42')
|
|
8
|
+
|
|
9
|
+
assert_equal({ name: 'ruby', id: 42 }, parsed)
|
|
10
|
+
assert_instance_of Integer, parsed.fetch(:id)
|
|
11
|
+
assert_nil Exercises::RegexpCaptures.parse("ruby:42\n")
|
|
12
|
+
assert_nil Exercises::RegexpCaptures.parse('ruby:x')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Checks match without global capture change.
|
|
16
|
+
def test_match_without_global_capture_change
|
|
17
|
+
assert_equal ['old', true], Exercises::RegexpCaptures.probe('ruby')
|
|
18
|
+
assert_equal ['old', false], Exercises::RegexpCaptures.probe('rails')
|
|
19
|
+
end
|
|
20
|
+
end
|