diff --git a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Extensions.md b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Extensions.md index 565b7d0cc1a4..542c6b793655 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Extensions.md +++ b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Extensions.md @@ -2,65 +2,65 @@ ## module Standard.Test.Extensions - Standard.Base.Any.Any.should_be_a self typ:Standard.Base.Any.Any -> Standard.Base.Any.Any - Standard.Base.Any.Any.should_be_a self typ:Standard.Base.Any.Any -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_end_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_end_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_equal_ignoring_order self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_equal_ignoring_order self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_fail_with self matcher:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_fail_with self matcher:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_not_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_not_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_not_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_not_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_not_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_not_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_only_contain_elements_in self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_only_contain_elements_in self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_start_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_start_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_succeed self frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Any.Any.should_succeed self frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_end_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_end_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_equal_ignoring_order self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_equal_ignoring_order self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_fail_with self matcher:Standard.Base.Any.Any unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_fail_with self matcher:Standard.Base.Any.Any unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_not_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_not_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_not_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_not_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_not_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_not_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_only_contain_elements_in self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_only_contain_elements_in self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_start_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_start_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_succeed self -> Standard.Base.Any.Any +- Standard.Base.Any.Any.should_succeed self -> Standard.Base.Any.Any - Standard.Base.Data.Boolean.Boolean.should_be_false self -> Standard.Base.Any.Any - Standard.Base.Data.Boolean.Boolean.should_be_false self -> Standard.Base.Any.Any - Standard.Base.Data.Boolean.Boolean.should_be_true self -> Standard.Base.Any.Any - Standard.Base.Data.Boolean.Boolean.should_be_true self -> Standard.Base.Any.Any -- Standard.Base.Data.Decimal.Decimal.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Data.Decimal.Decimal.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_be_a self typ:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_be_a self typ:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Data.Decimal.Decimal.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Data.Decimal.Decimal.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_be_a self typ:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_be_a self typ:Standard.Base.Any.Any -> Standard.Base.Any.Any - Standard.Base.Error.Error.should_be_false self -> Standard.Base.Any.Any - Standard.Base.Error.Error.should_be_false self -> Standard.Base.Any.Any - Standard.Base.Error.Error.should_be_true self -> Standard.Base.Any.Any - Standard.Base.Error.Error.should_be_true self -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_end_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_end_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_equal_ignoring_order self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_equal_ignoring_order self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_fail_with self matcher:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_fail_with self matcher:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_not_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_not_contain self element:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_not_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_not_equal self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_not_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_not_equal_type self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_only_contain_elements_in self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_only_contain_elements_in self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_start_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_start_with self that:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_succeed self frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Error.Error.should_succeed self frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Data.Numbers.Number.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any -- Standard.Base.Data.Numbers.Number.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_end_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_end_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_equal_ignoring_order self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_equal_ignoring_order self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_fail_with self matcher:Standard.Base.Any.Any unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_fail_with self matcher:Standard.Base.Any.Any unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_not_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_not_contain self element:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_not_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_not_equal self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_not_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_not_equal_type self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_only_contain_elements_in self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_only_contain_elements_in self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_start_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_start_with self that:Standard.Base.Any.Any -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_succeed self -> Standard.Base.Any.Any +- Standard.Base.Error.Error.should_succeed self -> Standard.Base.Any.Any +- Standard.Base.Data.Numbers.Number.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- Standard.Base.Data.Numbers.Number.should_equal self that:Standard.Base.Any.Any epsilon:Standard.Base.Any.Any= -> Standard.Base.Any.Any diff --git a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Frame_Hider.md b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Frame_Hider.md new file mode 100644 index 000000000000..5f06b2630a26 --- /dev/null +++ b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Frame_Hider.md @@ -0,0 +1,8 @@ +## Enso Signatures 1.0 +## module Standard.Test.Frame_Hider +- type Frame_Hider + - get_top_stack_frame -> Standard.Base.Data.Text.Text + - hide ~action:Standard.Base.Any.Any -> Standard.Base.Any.Any + - unhide ~action:Standard.Base.Any.Any -> Standard.Base.Any.Any + - unhide_1 f:Standard.Base.Any.Any x:Standard.Base.Any.Any -> Standard.Base.Any.Any + - unhide_2 f:Standard.Base.Any.Any x:Standard.Base.Any.Any y:Standard.Base.Any.Any -> Standard.Base.Any.Any diff --git a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Problems.md b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Problems.md index 42681c90de8c..969fa0fe101b 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Problems.md +++ b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Problems.md @@ -5,5 +5,5 @@ - expect_warning expected_warning:Standard.Base.Any.Any result:Standard.Base.Any.Any unwrap_errors:Standard.Base.Any.Any= -> Standard.Base.Any.Any - get_attached_warnings v:Standard.Base.Any.Any -> Standard.Base.Any.Any - not_expect_warning expected_warning_type:Standard.Base.Any.Any result:Standard.Base.Any.Any -> Standard.Base.Any.Any -- test_advanced_problem_handling action:Standard.Base.Any.Any error_checker:Standard.Base.Any.Any warnings_checker:Standard.Base.Any.Any result_checker:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any +- test_advanced_problem_handling action:Standard.Base.Any.Any error_checker:Standard.Base.Any.Any warnings_checker:Standard.Base.Any.Any result_checker:Standard.Base.Any.Any -> Standard.Base.Any.Any - test_problem_handling action:Standard.Base.Any.Any expected_problems:Standard.Base.Any.Any result_checker:Standard.Base.Any.Any unwrap_errors:Standard.Base.Data.Boolean.Boolean= ignore_warning_cardinality:Standard.Base.Data.Boolean.Boolean= -> Standard.Base.Any.Any diff --git a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Should_Reach.md b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Should_Reach.md index 3afcfab9e932..90f7d4ad8726 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Should_Reach.md +++ b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Should_Reach.md @@ -3,4 +3,4 @@ - type Should_Reach - new -> Standard.Base.Any.Any - reached self -> Standard.Base.Nothing.Nothing - - should_have_reached self frames_to_skip:Standard.Base.Data.Numbers.Integer= -> Standard.Test.Spec_Result.Spec_Result + - should_have_reached self -> Standard.Test.Spec_Result.Spec_Result diff --git a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Test.md b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Test.md index 15805f15579e..d3bd5d925bb4 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Test.md +++ b/distribution/lib/Standard/Test/0.0.0-dev/docs/api/Test.md @@ -1,13 +1,12 @@ ## Enso Signatures 1.0 ## module Standard.Test.Test - type Test - - assert_no_problems value:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any + - assert_no_problems value:Standard.Base.Any.Any -> Standard.Base.Any.Any - build fn:Standard.Base.Any.Any -> Standard.Base.Any.Any - enrich_message_with_clue message:Standard.Base.Any.Any -> Standard.Base.Any.Any - expect_panic matcher:Standard.Base.Any.Any ~action:Standard.Base.Any.Any -> Standard.Base.Any.Any - - expect_panic_with ~action:Standard.Base.Any.Any matcher:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any= -> Standard.Base.Any.Any + - expect_panic_with ~action:Standard.Base.Any.Any matcher:Standard.Base.Any.Any -> Standard.Base.Any.Any - fail message:Standard.Base.Any.Any details:Standard.Base.Any.Any= -> Standard.Base.Any.Any - - fail_match_on_unexpected_error error:Standard.Base.Any.Any frames_to_skip:Standard.Base.Any.Any -> Standard.Base.Any.Any - - get_source_location skip_frames:Standard.Base.Data.Numbers.Integer -> Standard.Base.Data.Text.Text + - fail_match_on_unexpected_error error:Standard.Base.Any.Any -> Standard.Base.Any.Any - with_clue ~clue:Standard.Base.Any.Any ~behavior:Standard.Base.Any.Any -> Standard.Base.Any.Any - with_retries ~action:Standard.Base.Any.Any -> Standard.Base.Any.Any diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Extensions.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Extensions.enso index a440a3a3a48d..5c87eaae06d3 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Extensions.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Extensions.enso @@ -3,6 +3,7 @@ import Standard.Base.Errors.Common.Incomparable_Values import Standard.Base.Errors.Common.No_Such_Method import Standard.Base.Errors.Illegal_Argument.Illegal_Argument +import project.Frame_Hider.Frame_Hider import project.Spec_Result.Spec_Result import project.Test.Test from project.Extensions_Helpers import rhs_error_check @@ -11,8 +12,6 @@ from project.Extensions_Helpers import rhs_error_check Arguments: - matcher: The expected type of dataflow error contained in `self`. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. - unwrap_errors: If true, remove any wrapping errors from the result before checking against the expected warning. @@ -24,19 +23,16 @@ from project.Extensions_Helpers import rhs_error_check example_should_fail_with = Examples.throw_error . should_fail_with Examples.My_Error -Any.should_fail_with : Any -> Integer -> Boolean -> Spec_Result -Any.should_fail_with self matcher frames_to_skip=0 unwrap_errors=True = +Any.should_fail_with : Any -> Boolean -> Spec_Result +Any.should_fail_with self matcher unwrap_errors=True = Frame_Hider.hide <| _ = unwrap_errors - loc = Test.get_source_location 1+frames_to_skip matcher_text = matcher . to_text - Test.fail ("Expected an error " + matcher_text + " but no error occurred, instead got: " + self.to_text + " (at " + loc + ").") + Test.fail ("Expected an error " + matcher_text + " but no error occurred, instead got: " + self.to_text + " (at " + Frame_Hider.get_top_stack_frame + ").") ## Expect a function to fail with the provided dataflow error. Arguments: - matcher: The expected type of dataflow error contained in `self`. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. - unwrap_errors: If true, remove any wrapping errors from the result before checking against the expected warning. @@ -48,21 +44,18 @@ Any.should_fail_with self matcher frames_to_skip=0 unwrap_errors=True = example_should_fail_with = Examples.throw_error . should_fail_with Examples.My_Error -Error.should_fail_with : Any -> Integer -> Boolean -> Spec_Result -Error.should_fail_with self matcher frames_to_skip=0 unwrap_errors=True = +Error.should_fail_with : Any -> Boolean -> Spec_Result +Error.should_fail_with self matcher unwrap_errors=True = Frame_Hider.hide <| unwrap_maybe error = if unwrap_errors then Error.unwrap error else error caught = unwrap_maybe self.catch if caught == matcher || caught.is_a matcher then Nothing else - loc = Test.get_source_location 2+frames_to_skip matcher_text = matcher . to_text - Test.fail ("Expected error "+matcher_text+", but error " + caught.to_text + " has been returned (at " + loc + ").") details='The error had the following stack trace:\n'+self.get_stack_trace_text + Test.fail ("Expected error "+matcher_text+", but error " + caught.to_text + " has been returned (at " + Frame_Hider.get_top_stack_frame + ").") details='The error had the following stack trace:\n'+self.get_stack_trace_text ## Asserts that `self` value is equal to the expected value. Arguments: - that: The value to check `self` for equality with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one value should equal another, @@ -71,10 +64,9 @@ Error.should_fail_with self matcher frames_to_skip=0 unwrap_errors=True = from Standard.Test import Test example_should_equal = Examples.add_1_to 1 . should_equal 2 -Any.should_equal : Any -> Integer -> Spec_Result -Any.should_equal self that frames_to_skip=0 = +Any.should_equal : Any -> Spec_Result +Any.should_equal self that = Frame_Hider.hide <| rhs_error_check that - loc = Test.get_source_location 1+frames_to_skip case self == that of True -> Spec_Result.Success False -> @@ -89,15 +81,13 @@ Any.should_equal self that frames_to_skip=0 = False -> "; lengths differ (" + self.length.to_text + " != " + that.length.to_text + ") " _ -> "" _ -> "" - msg = self.pretty + " did not equal " + that.pretty + additional_comment + " (at " + loc + ")." + msg = self.pretty + " did not equal " + that.pretty + additional_comment + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Asserts that `self` value is equal to the expected type value. Arguments: - that: The type to check `self` for equality with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that some type is equal to another., @@ -106,25 +96,22 @@ Any.should_equal self that frames_to_skip=0 = from Standard.Test import Test example_should_equal = Examples.some_type . should_equal_type Vector -Any.should_equal_type : Any -> Integer -> Spec_Result -Any.should_equal_type self that frames_to_skip=0 = case (self.is_same_object_as that) of +Any.should_equal_type : Any -> Spec_Result +Any.should_equal_type self that = Frame_Hider.hide <| case (self.is_same_object_as that) of True -> Spec_Result.Success False -> - loc = Test.get_source_location 2+frames_to_skip - msg = self.to_text + " did not equal type " + that.to_text + " (at " + loc + ")." + msg = self.to_text + " did not equal type " + that.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Added so that dataflow errors are not silently lost. -Error.should_equal_type self that frames_to_skip=0 = +Error.should_equal_type self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value is not equal to the expected value. Arguments: - that: The value to check `self` for equality with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one value should equal another, @@ -133,26 +120,23 @@ Error.should_equal_type self that frames_to_skip=0 = from Standard.Test import Test example_should_not_equal = Examples.add_1_to 1 . should_not_equal 2 -Any.should_not_equal : Any -> Integer -> Spec_Result -Any.should_not_equal self that frames_to_skip=0 = if that.is_error then (Panic.throw (Illegal_Argument.Error "Expected value provided as `that` for `should_not_equal` cannot be an error, but got: "+that.to_display_text)) else - loc = Test.get_source_location 2+frames_to_skip +Any.should_not_equal : Any -> Spec_Result +Any.should_not_equal self that = Frame_Hider.hide <| if that.is_error then (Panic.throw (Illegal_Argument.Error "Expected value provided as `that` for `should_not_equal` cannot be an error, but got: "+that.to_display_text)) else case self != that of True -> Spec_Result.Success False -> - msg = self.to_text + " did equal " + that.to_text + " (at " + loc + ")." + msg = self.to_text + " did equal " + that.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Added so that dataflow errors are not silently lost. -Error.should_not_equal self that frames_to_skip=0 = +Error.should_not_equal self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value is not equal to the expected type value. Arguments: - that: The type to check `self` for equality with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that some type is equal to another., @@ -161,25 +145,22 @@ Error.should_not_equal self that frames_to_skip=0 = from Standard.Test import Test example_should_not_equal = Examples.some_type . should_not_equal_type Vector -Any.should_not_equal_type : Any -> Integer -> Spec_Result -Any.should_not_equal_type self that frames_to_skip=0 = case (self.is_same_object_as that . not) of +Any.should_not_equal_type : Any -> Spec_Result +Any.should_not_equal_type self that = Frame_Hider.hide <| case (self.is_same_object_as that . not) of True -> Spec_Result.Success False -> - loc = Test.get_source_location 2+frames_to_skip - msg = self.to_text + " did equal type " + that.to_text + " (at " + loc + ")." + msg = self.to_text + " did equal type " + that.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Added so that dataflow errors are not silently lost. -Error.should_not_equal_type self that frames_to_skip=0 = +Error.should_not_equal_type self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value is a Text value and starts with `that`. Arguments: - that: The value to check `self` starts with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one value should start with another. @@ -187,24 +168,21 @@ Error.should_not_equal_type self that frames_to_skip=0 = from Standard.Test import Test example_should_start_with = "Hello World!" . should_start_with "Hello" -Any.should_start_with : Text -> Integer -> Spec_Result -Any.should_start_with self that frames_to_skip=0 = +Any.should_start_with : Text -> Spec_Result +Any.should_start_with self that = Frame_Hider.hide <| rhs_error_check that - loc = Test.get_source_location 1+frames_to_skip case self of _ : Text -> if self.starts_with that then Spec_Result.Success else - msg = self.to_text + " does not start with " + that.to_text + " (at " + loc + ")." + msg = self.to_text + " does not start with " + that.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg _ -> - msg = self.to_text + " is not a `Text` value (at " + loc + ")." + msg = self.to_text + " is not a `Text` value (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Asserts that `self` value is a Text value and ends with `that`. Arguments: - that: The value to check `self` ends with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one value should end with another. @@ -212,24 +190,21 @@ Any.should_start_with self that frames_to_skip=0 = from Standard.Test import Test example_should_end_with = "Hello World!" . should_end_with "ld!" -Any.should_end_with : Text -> Integer -> Spec_Result -Any.should_end_with self that frames_to_skip=0 = +Any.should_end_with : Text -> Spec_Result +Any.should_end_with self that = Frame_Hider.hide <| rhs_error_check that - loc = Test.get_source_location 1+frames_to_skip case self of _ : Text -> if self.ends_with that then Spec_Result.Success else - msg = self.to_text + " does not end with " + that.to_text + " (at " + loc + ")." + msg = self.to_text + " does not end with " + that.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg _ -> - msg = self.to_text + " is not a `Text` value (at " + loc + ")." + msg = self.to_text + " is not a `Text` value (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Asserts that `self` value is a Text value and starts with `that`. Arguments: - that: The value to check `self` starts with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one value should start with another. @@ -237,17 +212,15 @@ Any.should_end_with self that frames_to_skip=0 = from Standard.Test import Test example_should_start_with = "Hello World!" . should_start_with "Hello" -Error.should_start_with : Any -> Integer -> Spec_Result -Error.should_start_with self that frames_to_skip=0 = +Error.should_start_with : Any -> Spec_Result +Error.should_start_with self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value is a Text value and ends with `that`. Arguments: - that: The value to check `self` ends with. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one value should end with another. @@ -255,10 +228,10 @@ Error.should_start_with self that frames_to_skip=0 = from Standard.Test import Test example_should_end_with = "Hello World!" . should_end_with "ld!" -Error.should_end_with : Any -> Integer -> Spec_Result -Error.should_end_with self that frames_to_skip=0 = +Error.should_end_with : Any -> Spec_Result +Error.should_end_with self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value is equal to the expected value. @@ -272,18 +245,16 @@ Error.should_end_with self that frames_to_skip=0 = from Standard.Test import Test example_should_equal = Examples.add_1_to 1 . should_equal 2 -Error.should_equal : Any -> Integer -> Spec_Result -Error.should_equal self that frames_to_skip=0 = +Error.should_equal : Any -> Spec_Result +Error.should_equal self that = Frame_Hider.hide <| rhs_error_check that - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` is within `epsilon` from `that`. Arguments: - that: The value to compare `self` for equality with. - epsilon: The epsilon for comparing two float numbers. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Compare two float values. @@ -299,10 +270,9 @@ Error.should_equal self that frames_to_skip=0 = example_should_equal = 1.00000001 . should_equal 1.00000002 epsilon=0.0001 -Number.should_equal : Float -> Float -> Integer -> Spec_Result -Number.should_equal self that epsilon=0 frames_to_skip=0 = +Number.should_equal : Float -> Float -> Spec_Result +Number.should_equal self that epsilon=0 = Frame_Hider.hide <| rhs_error_check that - loc = Test.get_source_location 1+frames_to_skip matches = case that of n : Number -> self.equals n epsilon . catch Incomparable_Values _-> ## Incomparable_Values is thrown if one of the values is NaN. @@ -313,7 +283,7 @@ Number.should_equal self that epsilon=0 frames_to_skip=0 = case matches of True -> Spec_Result.Success False -> - msg = self.to_text + " did not equal " + that.to_text + " (at " + loc + ")." + msg = self.to_text + " did not equal " + that.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Asserts that `self` is within `epsilon` from `that`. @@ -321,51 +291,40 @@ Number.should_equal self that epsilon=0 frames_to_skip=0 = Arguments: - that: The value to compare `self` for equality with. - epsilon: The epsilon for comparing two float numbers. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. -Decimal.should_equal : Number -> Float-> Float -> Integer -> Spec_Result -Decimal.should_equal self that epsilon=0 frames_to_skip=0 = +Decimal.should_equal : Number -> Float-> Float -> Spec_Result +Decimal.should_equal self that epsilon=0 = Frame_Hider.hide <| rhs_error_check that - self.to_float . should_equal that.to_float epsilon frames_to_skip+1 + self.to_float . should_equal that.to_float epsilon ## Asserts that `self` value is not an error. It returns the original value, so that it can be inspected further. - Arguments: - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. - > Example Assert that a given action did not result in errors or warnings. "foobar".write (enso_project.data / "f.txt") . should_succeed -Any.should_succeed : Integer -> Any -Any.should_succeed self frames_to_skip=0 = - _ = frames_to_skip +Any.should_succeed : Any +Any.should_succeed self = self ## Asserts that `self` value is not an error. It returns the original value, so that it can be inspected further. - Arguments: - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. - > Example Assert that a given action did not result in errors or warnings. "foobar".write (enso_project.data / "f.txt") . should_succeed -Error.should_succeed : Integer -> Any -Error.should_succeed self frames_to_skip=0 = - Test.fail_match_on_unexpected_error self 1+frames_to_skip +Error.should_succeed : Any +Error.should_succeed self = Frame_Hider.hide <| + Test.fail_match_on_unexpected_error self ## Handles an unexpected dataflow error. -Error.should_be_a : Any -> Integer -> Any -Error.should_be_a self typ frames_to_skip=0 = +Error.should_be_a : Any -> Any +Error.should_be_a self typ = Frame_Hider.hide <| _ = typ - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that the given `Boolean` is `True` @@ -377,11 +336,10 @@ Error.should_be_a self typ frames_to_skip=0 = example_should_be_true = Examples.get_boolean . should_be_true Boolean.should_be_true : Spec_Result -Boolean.should_be_true self = case self of +Boolean.should_be_true self = Frame_Hider.hide <| case self of True -> Spec_Result.Success False -> - loc = Test.get_source_location 2 - Test.fail "Expected False to be True (at "+loc+")." + Test.fail "Expected False to be True (at "+Frame_Hider.get_top_stack_frame+")." ## Asserts that the given `Boolean` is `True`. @@ -393,7 +351,7 @@ Boolean.should_be_true self = case self of example_should_be_true = Examples.get_boolean . should_be_true Error.should_be_true : Spec_Result -Error.should_be_true self = Test.fail_match_on_unexpected_error self 1 +Error.should_be_true self = Frame_Hider.hide <| Test.fail_match_on_unexpected_error self ## Asserts that the given `Boolean` is `False` @@ -405,10 +363,9 @@ Error.should_be_true self = Test.fail_match_on_unexpected_error self 1 example_should_be_false = Examples.get_boolean . should_be_false Boolean.should_be_false : Spec_Result -Boolean.should_be_false self = case self of +Boolean.should_be_false self = Frame_Hider.hide <| case self of True -> - loc = Test.get_source_location 2 - Test.fail "Expected True to be False (at "+loc+")." + Test.fail "Expected True to be False (at "+Frame_Hider.get_top_stack_frame+")." False -> Spec_Result.Success ## Asserts that the given `Boolean` is `False` @@ -421,7 +378,7 @@ Boolean.should_be_false self = case self of example_should_be_false = Examples.get_boolean . should_be_false Error.should_be_false : Spec_Result -Error.should_be_false self = Test.fail_match_on_unexpected_error self 1 +Error.should_be_false self = Frame_Hider.hide <| Test.fail_match_on_unexpected_error self ## Asserts that a value is of a given type. @@ -435,9 +392,8 @@ Error.should_be_false self = Test.fail_match_on_unexpected_error self 1 example_should_be_a = 1.should_be_a Boolean Any.should_be_a : Any -> Spec_Result -Any.should_be_a self typ = +Any.should_be_a self typ = Frame_Hider.hide <| rhs_error_check typ - loc = Test.get_source_location 1 fail_on_wrong_arg_type = Panic.throw <| Illegal_Argument.Error "typ ("+typ.to_display_text+") must either be a type or a constructor. Use `should_equal` for value equality test instead." @@ -447,19 +403,19 @@ Any.should_be_a self typ = if a.constructor == c then Spec_Result.Success else expected_type = c.declaring_type.qualified_name actual_type = self.to Meta.Type . qualified_name - message = "Expected a value of type "+expected_type+", built with constructor "+c.name+", but got a value ["+self.to_text+"] of type "+actual_type+", built with constructor "+a.constructor.name+" instead (at "+loc+")." + message = "Expected a value of type "+expected_type+", built with constructor "+c.name+", but got a value ["+self.to_text+"] of type "+actual_type+", built with constructor "+a.constructor.name+" instead (at "+Frame_Hider.get_top_stack_frame+")." Test.fail message _ -> expected_type = c.declaring_type.qualified_name actual_type = self.to Meta.Type . qualified_name - message = "Expected a value of type "+expected_type+", built with constructor "+c.name+", but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+loc+")." + message = "Expected a value of type "+expected_type+", built with constructor "+c.name+", but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+Frame_Hider.get_top_stack_frame+")." Test.fail message meta_type : Meta.Type -> ok = self.is_a typ || self==typ if ok then Spec_Result.Success else expected_type = meta_type.qualified_name actual_type = self.to Meta.Type . qualified_name - message = "Expected a value of type "+expected_type+" but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+loc+")." + message = "Expected a value of type "+expected_type+" but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+Frame_Hider.get_top_stack_frame+")." Test.fail message # Workaround for 0-argument atom constructors which 'unapplies' them. atom : Meta.Atom -> @@ -470,13 +426,13 @@ Any.should_be_a self typ = ok = self.is_a typ if ok then Spec_Result.Success else actual_type = self.to Meta.Type . qualified_name - message = "Expected a value of Java class "+typ.to_text+" but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+loc+")." + message = "Expected a value of Java class "+typ.to_text+" but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+Frame_Hider.get_top_stack_frame+")." Test.fail message p : Meta.Primitive -> ok = self == p.value if ok then Spec_Result.Success else actual_type = self.to Meta.Type . qualified_name - message = "Expected a value of "+typ.to_text+" but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+loc+")." + message = "Expected a value of "+typ.to_text+" but got a value ["+self.to_text+"] of type "+actual_type+" instead (at "+Frame_Hider.get_top_stack_frame+")." Test.fail message _ -> fail_on_wrong_arg_type @@ -491,8 +447,6 @@ Any.should_be_a self typ = Arguments: - that: The collection to compare. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one vector should contain the same elements as another. @@ -501,25 +455,24 @@ Any.should_be_a self typ = from Standard.Test import Test example_should_equal = [1, 2] . should_equal_ignoring_order [2, 1] -Any.should_equal_ignoring_order : Any -> Integer -> Spec_Result -Any.should_equal_ignoring_order self that frames_to_skip=0 = - loc = Test.get_source_location 1+frames_to_skip +Any.should_equal_ignoring_order : Any -> Spec_Result +Any.should_equal_ignoring_order self that = Frame_Hider.hide <| if that.is_a Vector . not then - Panic.throw (Illegal_Argument.Error "Expected a Vector, but got a "+that.to_display_text+" (at "+loc+").") + Panic.throw (Illegal_Argument.Error "Expected a Vector, but got a "+that.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+").") that.each element-> if self.contains element . not then - msg = "The collection (" + self.to_text + ") did not contain " + element.to_text + " (at " + loc + ")." + msg = "The collection (" + self.to_text + ") did not contain " + element.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg self.each element-> if that.contains element . not then - msg = "The collection contained an element (" + element.to_text + ") which was not expected (at " + loc + ")." + msg = "The collection contained an element (" + element.to_text + ") which was not expected (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg Test.with_clue "Duplicate elements in either collection should have the same counts - checked by comparing sorted collections: " <| ## If the vector contains vectors or incomparable values, they may not get sorted correctly. We normalize by converting to a text representation. normalize e = Panic.catch No_Such_Method e.pretty _->e.to_text - (self.sort on=normalize) . should_equal (that.sort on=normalize) frames_to_skip=frames_to_skip+3 + (self.sort on=normalize) . should_equal (that.sort on=normalize) Spec_Result.Success ## Asserts that `self` value contains the same elements as `that`. @@ -533,8 +486,6 @@ Any.should_equal_ignoring_order self that frames_to_skip=0 = Arguments: - _: The collection to compare. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one vector should contain the same elements as another. @@ -543,10 +494,10 @@ Any.should_equal_ignoring_order self that frames_to_skip=0 = from Standard.Test import Test example_should_equal = [1, 2] . should_equal_ignoring_order [2, 1] -Error.should_equal_ignoring_order : Any -> Integer -> Spec_Result -Error.should_equal_ignoring_order self that frames_to_skip=0 = +Error.should_equal_ignoring_order : Any -> Spec_Result +Error.should_equal_ignoring_order self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value contains only elements in `that`. @@ -560,8 +511,6 @@ Error.should_equal_ignoring_order self that frames_to_skip=0 = Arguments: - that: The collection to compare. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one vector should contain only elements in another. @@ -570,13 +519,12 @@ Error.should_equal_ignoring_order self that frames_to_skip=0 = from Standard.Test import Test example_should_equal = [1, 2] . should_only_contain_elements_in [1, 2, 3, 4] -Any.should_only_contain_elements_in : Any -> Integer -> Spec_Result -Any.should_only_contain_elements_in self that frames_to_skip=0 = +Any.should_only_contain_elements_in : Any -> Spec_Result +Any.should_only_contain_elements_in self that = Frame_Hider.hide <| rhs_error_check that - loc = Test.get_source_location 1+frames_to_skip self.each element-> if that.contains element . not then - msg = "The collection contained an element ("+element.to_text+") which was not expected (at " + loc + ")." + msg = "The collection contained an element ("+element.to_text+") which was not expected (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg Spec_Result.Success @@ -592,8 +540,6 @@ Any.should_only_contain_elements_in self that frames_to_skip=0 = Arguments: - that: The collection to compare. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. > Example Assert that one vector should contain only elements in another. @@ -602,17 +548,15 @@ Any.should_only_contain_elements_in self that frames_to_skip=0 = from Standard.Test import Test example_should_equal = [1, 2] . should_only_contain_elements_in [1, 2, 3, 4] -Error.should_only_contain_elements_in : Any -> Integer -> Spec_Result -Error.should_only_contain_elements_in self that frames_to_skip=0 = +Error.should_only_contain_elements_in : Any -> Spec_Result +Error.should_only_contain_elements_in self that = Frame_Hider.hide <| _ = [that] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value contains an element. Arguments: - element: The element to check. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. This method delegates to the `contains` method of `self` and will use the rules of the particular type - be it a `Vector`, `Text` or any custom type @@ -624,24 +568,21 @@ Error.should_only_contain_elements_in self that frames_to_skip=0 = from Standard.Test import Test example_should_equal = "foobar".should_contain "foo" -Any.should_contain : Any -> Integer -> Spec_Result -Any.should_contain self element frames_to_skip=0 = +Any.should_contain : Any -> Spec_Result +Any.should_contain self element = Frame_Hider.hide <| rhs_error_check element - loc = Test.get_source_location 1+frames_to_skip contains_result = Panic.catch No_Such_Method (self.contains element) caught_panic-> if caught_panic.payload.method_name != "contains" then Panic.throw caught_panic else - msg = "The value (" + self.to_text + ") does not support the method `contains` (at " + loc + ")." + msg = "The value (" + self.to_text + ") does not support the method `contains` (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg if contains_result then Spec_Result.Success else - msg = "The value (" + self.to_text + ") did not contain the element (" + element.to_text + ") (at " + loc + ")." + msg = "The value (" + self.to_text + ") did not contain the element (" + element.to_text + ") (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Asserts that `self` value contains an element. Arguments: - element: The element to check. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. This method delegates to the `contains` method of `self` and will use the rules of the particular type - be it a `Vector`, `Text` or any custom type @@ -653,44 +594,39 @@ Any.should_contain self element frames_to_skip=0 = from Standard.Test import Test example_should_equal = "foobar".should_contain "foo" -Error.should_contain : Any -> Integer -> Spec_Result -Error.should_contain self element frames_to_skip=0 = +Error.should_contain : Any -> Spec_Result +Error.should_contain self element = Frame_Hider.hide <| _ = [element] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self ## Asserts that `self` value does not contain an element. Arguments: - element: The element to check. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. This method delegates to the `contains` method of `self` and will use the rules of the particular type - be it a `Vector`, `Text` or any custom type implementing a method `contains : a -> Boolean`. -Any.should_not_contain : Any -> Integer -> Spec_Result -Any.should_not_contain self element frames_to_skip=0 = +Any.should_not_contain : Any -> Spec_Result +Any.should_not_contain self element = Frame_Hider.hide <| rhs_error_check element - loc = Test.get_source_location 1+frames_to_skip contains_result = Panic.catch No_Such_Method (self.contains element) caught_panic-> if caught_panic.payload.method_name != "contains" then Panic.throw caught_panic else - msg = "The value (" + self.to_text + ") does not support the method `contains` (at " + loc + ")." + msg = "The value (" + self.to_text + ") does not support the method `contains` (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg if contains_result.not then Spec_Result.Success else - msg = "The value (" + self.to_text + ") contained the element (" + element.to_text + "), but it was expected to not contain it (at " + loc + ")." + msg = "The value (" + self.to_text + ") contained the element (" + element.to_text + "), but it was expected to not contain it (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Asserts that `self` value does not contain an element. Arguments: - element: The element to check. - - frames_to_skip (optional, advanced): used to alter the location which is - displayed as the source of this error. This method delegates to the `contains` method of `self` and will use the rules of the particular type - be it a `Vector`, `Text` or any custom type implementing a method `contains : a -> Boolean`. -Error.should_not_contain : Any -> Integer -> Spec_Result -Error.should_not_contain self element frames_to_skip=0 = +Error.should_not_contain : Any -> Spec_Result +Error.should_not_contain self element = Frame_Hider.hide <| _ = [element] - Test.fail_match_on_unexpected_error self 1+frames_to_skip + Test.fail_match_on_unexpected_error self diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Frame_Hider.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Frame_Hider.enso new file mode 100644 index 000000000000..152488d1fc08 --- /dev/null +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Frame_Hider.enso @@ -0,0 +1,137 @@ +from Standard.Base import all +import Standard.Base.Runtime.Ref.Ref + +## PRIVATE + + Frame_Hider is used in test utilities to hide uninteresting stack frames from + users when reporting the location of test failures. + + In a test utility such as `Any.should_equal`, the failure of a test assertion + is accompanied by the location of the failure. The location should not be a + stack frame inside `Any.should_equal`, but rather should be at the location + that called `Any.should_equal`. This means identifying stack frames we don't + want to bother the user with, and omitting them when we're looking for the + correct stack frame to use. + + The problem is more complicated when test utilities call other utilities, or + when test utilities invoke callbacks provided by user test code. + + The `hide` and `unhide*` methods are simple wrappers. `get_top_stack_frame` + identifies these on the stack, and uses them to remove the uninteresting + frames from consderation. + + A `hide` call should be wrapped around the body of every test utility. + + An `unhide*` call should be wrapped around any call from a test utility to a + user-supplied callback, depending on the number of arguments. If one test + utility forwards a callback to another test utility, the callback should be + wrapped at the forward site as well. + + ! Partial Application + + Partial application can prevent the `unhide*` methods from existing in the + stack trace, so test callbacks should have explicit parameters: + + # Do not use partial application: + tester = expect_column_names ["A", "B"] + # Use explicit parameters: + tester t = expect_column_names ["A", "B"] t + ! Tail Calls + + Tail calls can result in changes to the stack that prevent + `get_top_stack_frame` from working properly. For this reason, uses of + `hide` and `unhide` should be within the tail call: + + go i = Frame_Hider.hide <| + # ... + @Tail_Call go (i+1) + go 1 +type Frame_Hider + ## PRIVATE + + Hides the stack frames of the contained code from `get_top_stack_frame`. + + > Example + Wrap the body of a test utility to hide its stack frames. + + Any.should_equal self that = Frame_Hider.hide <| + ... + Error.throw ("Not equal at " + Frame_Hider.get_top_stack_frame) + hide ~action = + action + + ## PRIVATE + + Unhides the stack frames of the call to the user-supplied callback + application. + + > Example + Wrap a callback invocation to unhide its stack frames. + + test_utility test_predicate x = + ... + Frame_Hider.unhide (test_predicate x) + unhide ~action = + action + + ## PRIVATE + + Unhides the stack frames of the call to the user-supplied callback + application, uncurried for one argument. + + `unhide_1 f x` is Equivalent to `unhide (f x)`. + + > Example + Wrap a callback invocation to unhide its stack frames. + + test_utility test_predicate x = + ... + Frame_Hider.unhide_1 test_predicate x + unhide_1 f x = + f x + + ## PRIVATE + + Unhides the stack frames of the call to the user-supplied callback + application, uncurried for two arguments. + + `unhide_1 f x y` is Equivalent to `unhide (f x y)`. + + > Example + Wrap a callback invocation to unhide its stack frames. + + test_utility test_predicate x y = + ... + Frame_Hider.unhide_2 test_predicate x y + unhide_2 f x y = + f x y + + ## PRIVATE + + Identify the correct top stack frame by skipping over the stack frames + inside test utilities. + get_top_stack_frame -> Text = + stack_trace = Runtime.get_stack_trace + reversed_stack_trace = stack_trace.reverse + + ## Iterate through stack frames from bottom to top, determining how many + `hide` calls each one is nested inside. Each `hide` frame increases + the nesting level by 1, and each `unhide` decreases it by one. + + The stack frame we are looking for is the one before the last frame + that has a nesting level of 0 -- this is the most recent user-level + call, and the one that triggered the test assertion failure. + + If we cannot find such a frame, we simply return the top of the + stack. (In this case, some test code is missing a call to `unhide*`.) + delta_for_frame frame = + name = frame.name + if name.starts_with "Frame_Hider.hide" then 1 else + if name.starts_with "Frame_Hider.unhide" then -1 else 0 + nesting_levels = reversed_stack_trace.map delta_for_frame . running_fold 0 (+) + index = + i = nesting_levels.last_index_of 0 + if i.is_nothing || i == 0 then 0 else i-1 + + top = reversed_stack_trace . at index . source_location + top.to_display_text diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Main.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Main.enso index 0b2e84fed6f6..b245714303e7 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Main.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Main.enso @@ -27,6 +27,8 @@ export project.Extensions.should_succeed export project.Faker.Faker +export project.Frame_Hider.Frame_Hider + export project.Problems export project.Suite.Suite diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Problems.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Problems.enso index 4300e6e2f776..eaa93ec58b0f 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Problems.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Problems.enso @@ -1,6 +1,7 @@ from Standard.Base import all from project import Test +import project.Frame_Hider.Frame_Hider from project.Extensions import all ## Returns values of warnings attached to the value. @@ -27,20 +28,20 @@ get_attached_warnings v = duplicated and that will be accepted. If false (default), the warning count has to match the counts in `expected_problems`. test_problem_handling : (Problem_Behavior -> Any) -> Vector Any -> (Any -> Nothing) -> Boolean -> Boolean -> Nothing -test_problem_handling action expected_problems result_checker (unwrap_errors : Boolean = True) (ignore_warning_cardinality : Boolean = False) = +test_problem_handling action expected_problems result_checker (unwrap_errors : Boolean = True) (ignore_warning_cardinality : Boolean = False) = Frame_Hider.hide <| unwrap_maybe error = if unwrap_errors then Error.unwrap error else error - error_checker error_result = + error_checker error_result = Frame_Hider.hide <| first_problem = expected_problems.first first_problem_type = Meta.type_of first_problem - error_result . should_fail_with first_problem_type unwrap_errors=unwrap_errors frames_to_skip=3 - (unwrap_maybe error_result.catch) . should_equal first_problem frames_to_skip=3 - warnings_checker warnings = + error_result . should_fail_with first_problem_type unwrap_errors=unwrap_errors + (unwrap_maybe error_result.catch) . should_equal first_problem + warnings_checker warnings = Frame_Hider.hide <| Test.with_clue "The warnings were "+warnings.to_text+'.\n' <| (if ignore_warning_cardinality then warnings.distinct else warnings) . map unwrap_maybe - . should_equal_ignoring_order expected_problems frames_to_skip=8 - test_advanced_problem_handling action error_checker warnings_checker result_checker frames_to_skip=1 + . should_equal_ignoring_order expected_problems + test_advanced_problem_handling (Frame_Hider.unhide action) (Frame_Hider.unhide_1 error_checker) (Frame_Hider.unhide_1 warnings_checker) (Frame_Hider.unhide_1 result_checker) ## UNSTABLE Tests how a specific operation behaves depending on the requested @@ -58,31 +59,30 @@ test_problem_handling action expected_problems result_checker (unwrap_errors : B - result_checker: A function which should verify that the result generated by the action is correct. It does not return anything, instead it should use the standard testing approach, like `x.should_equal y`. -test_advanced_problem_handling : (Problem_Behavior -> Any) -> (Any -> Nothing) -> (Vector Any -> Nothing) -> (Any -> Nothing) -> Integer -> Nothing -test_advanced_problem_handling action error_checker warnings_checker result_checker frames_to_skip=0 = +test_advanced_problem_handling : (Problem_Behavior -> Any) -> (Any -> Nothing) -> (Vector Any -> Nothing) -> (Any -> Nothing) -> Nothing +test_advanced_problem_handling action error_checker warnings_checker result_checker = Frame_Hider.hide <| # First, we check the action ignoring any warnings. - result_ignoring = action Problem_Behavior.Ignore - result_checker result_ignoring - get_attached_warnings result_ignoring . should_equal [] frames_to_skip=frames_to_skip+1 + result_ignoring = Frame_Hider.unhide_1 action Problem_Behavior.Ignore + Frame_Hider.unhide_1 result_checker result_ignoring + get_attached_warnings result_ignoring . should_equal [] # Then, we check the fail-on-first-error mode. - error_result = action Problem_Behavior.Report_Error - error_checker error_result + error_result = Frame_Hider.unhide_1 action Problem_Behavior.Report_Error + Frame_Hider.unhide_1 error_checker error_result # Lastly, we check the report warnings mode and ensure that both the result is correct and the warnings are as expected. - result_warning = action Problem_Behavior.Report_Warning - result_checker result_warning - warnings_checker (get_attached_warnings result_warning) + result_warning = Frame_Hider.unhide_1 action Problem_Behavior.Report_Warning + Frame_Hider.unhide_1 result_checker result_warning + Frame_Hider.unhide_1 warnings_checker (get_attached_warnings result_warning) ## UNSTABLE Checks if the provided value does not have any attached problems. -assume_no_problems result = - loc = Test.get_source_location 1 +assume_no_problems result = Frame_Hider.hide <| if result.is_error then - Test.fail "Expected the result to not be an error, but a dataflow error has been matched: "+result.catch.to_display_text+" (at "+loc+")." details=result.get_stack_trace_text + Test.fail "Expected the result to not be an error, but a dataflow error has been matched: "+result.catch.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." details=result.get_stack_trace_text warnings = get_attached_warnings result if warnings.not_empty then - Test.fail "Expected the result to not contain any warnings, but it did: "+warnings.to_text+" (at "+loc+")." + Test.fail "Expected the result to not contain any warnings, but it did: "+warnings.to_text+" (at "+Frame_Hider.get_top_stack_frame+")." ## UNSTABLE Checks if the provided value has a specific warning attached. @@ -95,16 +95,15 @@ assume_no_problems result = - unwrap_errors: If true, remove any wrapping errors from the result before checking against the expected warning. expect_warning : Any -> Any -> Boolean -> Nothing -expect_warning expected_warning result unwrap_errors=True = +expect_warning expected_warning result unwrap_errors=True = Frame_Hider.hide <| unwrap_maybe error = if unwrap_errors then Error.unwrap error else error - loc = Test.get_source_location 1 if result.is_error then - Test.fail "Expected a warning "+expected_warning.to_text+", but a dataflow error has been matched: "+result.catch.to_display_text+" (at "+loc+")." + Test.fail "Expected a warning "+expected_warning.to_text+", but a dataflow error has been matched: "+result.catch.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." warnings = get_attached_warnings result . map unwrap_maybe found = warnings.find if_missing=Nothing x-> (x == expected_warning) || (x.is_a expected_warning) found.if_nothing <| - Test.fail "Expected the result to contain a warning: "+expected_warning.to_text+", but it did not. The warnings were "+warnings.short_display_text+' (at '+loc+').' + Test.fail "Expected the result to contain a warning: "+expected_warning.to_text+", but it did not. The warnings were "+warnings.short_display_text+' (at '+Frame_Hider.get_top_stack_frame+').' ## UNSTABLE Checks if the provided value has a specific warning attached and if there are @@ -119,20 +118,19 @@ expect_warning expected_warning result unwrap_errors=True = - unwrap_errors: If true, remove any wrapping errors from the result before checking against the expected warning. expect_only_warning : Any -> Any -> Boolean -> Any -expect_only_warning expected_warning result unwrap_errors=True = +expect_only_warning expected_warning result unwrap_errors=True = Frame_Hider.hide <| unwrap_maybe error = if unwrap_errors then Error.unwrap error else error - loc = Test.get_source_location 1 if result.is_error then - Test.fail "Expected only warning "+expected_warning.to_text+", but a dataflow error has been matched: "+result.catch.to_display_text+" (at "+loc+")." + Test.fail "Expected only warning "+expected_warning.to_text+", but a dataflow error has been matched: "+result.catch.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." warnings = get_attached_warnings result . map unwrap_maybe is_expected x = (x == expected_warning) || (x.is_a expected_warning) found = warnings.find if_missing=Nothing is_expected if found.is_nothing then - Test.fail "Expected the result to contain a warning: "+expected_warning.to_text+", but it did not. The warnings were "+warnings.short_display_text+' (at '+loc+').' + Test.fail "Expected the result to contain a warning: "+expected_warning.to_text+", but it did not. The warnings were "+warnings.short_display_text+' (at '+Frame_Hider.get_top_stack_frame+').' invalid = warnings.filter x-> is_expected x . not if invalid.not_empty then - Test.fail "Expected the result to contain only the warning: "+found.to_text+", but it also contained: "+invalid.to_text+' (at '+loc+').' + Test.fail "Expected the result to contain only the warning: "+found.to_text+", but it also contained: "+invalid.to_text+' (at '+Frame_Hider.get_top_stack_frame+').' found ## UNSTABLE @@ -140,9 +138,8 @@ expect_only_warning expected_warning result unwrap_errors=True = It allows other warnings to be present also. not_expect_warning : Any -> Any -> Nothing -not_expect_warning expected_warning_type result = +not_expect_warning expected_warning_type result = Frame_Hider.hide <| warnings = get_attached_warnings result found = warnings.find if_missing=Nothing x-> x.is_a expected_warning_type if found.is_nothing.not then - loc = Test.get_source_location 3 - Test.fail 'The result contained a warning it was not supposed to: '+found.to_text+' (at '+loc+').' + Test.fail 'The result contained a warning it was not supposed to: '+found.to_text+' (at '+Frame_Hider.get_top_stack_frame+').' diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Should_Reach.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Should_Reach.enso index ef5908c76280..7eb630759cc5 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Should_Reach.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Should_Reach.enso @@ -1,6 +1,7 @@ from Standard.Base import all import Standard.Base.Runtime.Ref.Ref +import project.Frame_Hider.Frame_Hider import project.Spec_Result.Spec_Result from project import Test from project.Extensions import all @@ -21,8 +22,7 @@ type Should_Reach Nothing ## Checks if a point was reached in execution. - should_have_reached : Integer -> Spec_Result - should_have_reached self (frames_to_skip : Integer = 0) -> Spec_Result = - loc = Test.get_source_location 1+frames_to_skip + should_have_reached : Spec_Result + should_have_reached self -> Spec_Result = Frame_Hider.hide <| if self.reached_ref.get then Spec_Result.Success else - Test.fail ("Did not reach Should_Reach (at "+loc+").") + Test.fail ("Did not reach Should_Reach (at "+Frame_Hider.get_top_stack_frame+").") diff --git a/distribution/lib/Standard/Test/0.0.0-dev/src/Test.enso b/distribution/lib/Standard/Test/0.0.0-dev/src/Test.enso index e56520913126..08b61f8a95ac 100644 --- a/distribution/lib/Standard/Test/0.0.0-dev/src/Test.enso +++ b/distribution/lib/Standard/Test/0.0.0-dev/src/Test.enso @@ -4,6 +4,7 @@ from Standard.Base.Errors.Common import Uninitialized_State from Standard.Base.Runtime import State import project.Clue.Clue +import project.Frame_Hider.Frame_Hider import project.Group.Group import project.Spec.Spec import project.Spec_Result.Spec_Result @@ -11,7 +12,6 @@ import project.Suite.Suite import project.Suite.Suite_Builder import project.Test_Result.Test_Result - polyglot java import java.lang.Thread @@ -42,9 +42,8 @@ type Test example_expect_panic_with = Test.expect_panic_with Examples.throw_panic Examples.My_Error - expect_panic_with : Any -> Any -> Integer -> Test_Result - expect_panic_with ~action matcher frames_to_skip=0 = - loc = Test.get_source_location 1+frames_to_skip + expect_panic_with : Any -> Any -> Test_Result + expect_panic_with ~action matcher = Frame_Hider.hide <| handle_panic caught_panic = payload = caught_panic.payload is_internal_test_panic = payload.is_a Spec_Result @@ -55,17 +54,17 @@ type Test is_panic_matching = payload.is_a matcher if is_panic_matching then payload else stack_trace = caught_panic.convert_to_dataflow_error.get_stack_trace_text - Test.fail ("Expected a " + matcher.to_text + ", but " + payload.to_text + " was thrown instead (at " + loc + ").") details=stack_trace + Test.fail ("Expected a " + matcher.to_text + ", but " + payload.to_text + " was thrown instead (at " + Frame_Hider.get_top_stack_frame + ").") details=stack_trace Panic.catch Any handler=handle_panic <| res = action # If the action did not panic above, we fail the test. case res.is_error of True -> - Test.fail ("Expected a Panic " + matcher.to_text + " to be thrown, but the action returned a Dataflow Error " + res.catch.to_display_text + " instead (at " + loc + ").") + Test.fail ("Expected a Panic " + matcher.to_text + " to be thrown, but the action returned a Dataflow Error " + res.catch.to_display_text + " instead (at " + Frame_Hider.get_top_stack_frame + ").") False -> return_suffix = if res.is_nothing then "" else " and returned ["+res.to_text+"]" - Test.fail ("Expected a Panic " + matcher.to_text + " to be thrown, but the action succeeded" + return_suffix + " (at " + loc + ").") + Test.fail ("Expected a Panic " + matcher.to_text + " to be thrown, but the action succeeded" + return_suffix + " (at " + Frame_Hider.get_top_stack_frame + ").") ## Expect a function to fail with the provided panic. @@ -90,20 +89,19 @@ type Test IO.println 'this is not reached' expect_panic : Any -> Any -> Test_Result - expect_panic matcher ~action = Test.expect_panic_with action matcher frames_to_skip=1 + expect_panic matcher ~action = Frame_Hider.hide <| Test.expect_panic_with action matcher ## Checks that the provided action returns without any errors or warnings. If you just want to check for errors, usage of the `.should_succeed` extension function is preferred. - assert_no_problems value frames_to_skip=0 = + assert_no_problems value = Frame_Hider.hide <| value.catch Any _-> - Test.fail_match_on_unexpected_error value 2+frames_to_skip + Test.fail_match_on_unexpected_error value warnings = Warning.get_all value . map .value if warnings.not_empty then - loc = Test.get_source_location 2+frames_to_skip - msg = "The action returned unexpected warnings: " + warnings.to_text + " (at " + loc + ")." + msg = "The action returned unexpected warnings: " + warnings.to_text + " (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg ## Fail a test with the given message. @@ -132,11 +130,10 @@ type Test ## PRIVATE Reports an unexpected dataflow error has occurred. - fail_match_on_unexpected_error : Error -> Integer -> Nothing - fail_match_on_unexpected_error error frames_to_skip = + fail_match_on_unexpected_error : Error -> Nothing + fail_match_on_unexpected_error error = Frame_Hider.hide <| payload = error.catch - loc = Test.get_source_location 1+frames_to_skip - msg = "An unexpected dataflow error (" + payload.to_text + ") has been matched (at " + loc + ")." + msg = "An unexpected dataflow error (" + payload.to_text + ") has been matched (at " + Frame_Hider.get_top_stack_frame + ")." Test.fail msg details=error.get_stack_trace_text ## Executes the block of code passed as behavior and adds a clue modifier which @@ -192,8 +189,6 @@ type Test attempts. with_retries : Any -> Any with_retries ~action = - loc = Test.get_source_location 1 - milliseconds_between_attempts = 100 ## We give the CI a bit more attempts, as failures are more annoying there. For local development, a bit less retries is enough - there it is more @@ -201,32 +196,14 @@ type Test don't want to spend too much time retrying when debugging the tests locally. max_retries = if Environment.get "CI" . is_nothing . not then 100 else 20 - go i = - Panic.catch Any action caught_panic-> + ## The `hide` is here because if it were at the top of the function, the + tail call confuses the location finder. + go i = Frame_Hider.hide <| + Panic.catch Any (Frame_Hider.unhide action) caught_panic-> # If the iterations are exhausted, we rethrow the panic. if i > max_retries then Panic.throw caught_panic else if i % 10 == 0 then - IO.println 'Still failing after '+i.to_text+' retries ('+loc.to_display_text+'):\n'+caught_panic.payload.to_display_text + IO.println 'Still failing after '+i.to_text+' retries ('+Frame_Hider.get_top_stack_frame.to_display_text+'):\n'+caught_panic.payload.to_display_text Thread.sleep milliseconds_between_attempts @Tail_Call go (i+1) go 1 - - - ## PRIVATE - - Returns a Text representing the source location of a stack frame above - the call. - - Arguments: - - skip_frames: how many frames on the stack to skip. - - If the function is called with 0 it will return the location of that call. - Note that not only function calls, but also things like pattern matching add - frames to the stack and there is no guarantee that the amount of frames that - need to be skipped will not change between versions, so this method should be - used carefully. - get_source_location skip_frames:Integer -> Text = - stack = Standard.Base.Runtime.get_stack_trace - element = stack . at skip_frames+1 - loc = element . source_location - loc . to_display_text diff --git a/test/Base_Tests/src/Semantic/Meta_Location_Spec.enso b/test/Base_Tests/src/Semantic/Meta_Location_Spec.enso index f8f698858ca3..6ee3a4ee303e 100644 --- a/test/Base_Tests/src/Semantic/Meta_Location_Spec.enso +++ b/test/Base_Tests/src/Semantic/Meta_Location_Spec.enso @@ -13,15 +13,6 @@ add_specs suite_builder = suite_builder.group "Meta-Value Inspection" group_buil pending_js_missing = if Polyglot.is_language_installed "js" then Nothing else "Can't run JavaScript tests, language `js` is not installed." - location_pending = case Platform.os of - Platform.OS.Windows -> "This test is disabled on Windows until issue 1561 is fixed." - _ -> Nothing - - group_builder.specify "should allow to get the source location of a frame" pending=location_pending <| - src = Test.get_source_location 0 - loc = "Meta_Location_Spec.enso:21:15-40" - src.take (..Last loc.length) . should_equal loc - group_builder.specify "should allow to get qualified type names of values" <| x = 42 y = My_Type.Value 1 2 3 diff --git a/test/Base_Tests/src/System/File_Spec.enso b/test/Base_Tests/src/System/File_Spec.enso index 20232241ced4..573a92c00004 100644 --- a/test/Base_Tests/src/System/File_Spec.enso +++ b/test/Base_Tests/src/System/File_Spec.enso @@ -17,13 +17,12 @@ import project.Data.Data_Spec import project.Network.Enso_Cloud.Cloud_Tests_Setup.Cloud_Tests_Setup ## We rely on a less strict equality for `File` as it is fine if a relative file gets resolved to absolute. -File.should_equal self other frames_to_skip=0 = - loc = Test.get_source_location 1+frames_to_skip +File.should_equal self other = Frame_Hider.hide <| are_same = case other of _ : File -> self.absolute.normalize.path == other.absolute.normalize.path _ -> False if are_same then self else - Test.fail "Expected "+self.to_text+" to be equal to "+other.to_text+" (at "+loc+")." + Test.fail "Expected "+self.to_text+" to be equal to "+other.to_text+" (at "+Frame_Hider.get_top_stack_frame+")." set_writable file writable = diff --git a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso index 98ec05d04b81..ef5f144d8141 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Aggregate_Spec.enso @@ -58,8 +58,8 @@ add_aggregate_specs suite_builder setup = table_builder = setup.table_builder data = Data.setup table_fn empty_table_fn - expect_column_names names table = - table.columns . map .name . should_equal names frames_to_skip=3 + expect_column_names names table = Frame_Hider.hide <| + table.columns . map .name . should_equal names find_row key table (columns=Nothing) = table_columns = if columns.is_nothing then table.columns else columns.map x->(table.columns.at x) @@ -1107,10 +1107,10 @@ add_aggregate_specs suite_builder setup = suite_builder.group prefix+"Table.aggregate Count_Distinct" group_builder-> group_builder.specify "should correctly count missing values" <| - get_value t = + get_value t = Frame_Hider.hide <| columns = materialize t . columns - columns.length . should_equal 1 frames_to_skip=1 - columns.first.length . should_equal 1 frames_to_skip=1 + columns.length . should_equal 1 + columns.first.length . should_equal 1 columns.first . at 0 ## TODO currently our builder does not allow all-null tables, so we @@ -1254,14 +1254,13 @@ add_aggregate_specs suite_builder setup = m1.columns.first.at 0 . should_equal 1.1180339887499 epsilon=0.000001 m1.columns.second.at 0 . should_equal 1.2909944487358 epsilon=0.000001 - expect_null_or_nan value = + expect_null_or_nan value = Frame_Hider.hide <| matches = case value of Nothing -> True _ : Float -> Double.isNaN value _ -> False if matches.not then - loc = Test.get_source_location 2 - Test.fail "Expected a Nothing or NaN but got: "+value.to_text+" (at "+loc+")." + Test.fail "Expected a Nothing or NaN but got: "+value.to_text+" (at "+Frame_Hider.get_top_stack_frame+")." if setup.flagged ..Supports_Infinity then suite_builder.group prefix+"Table.aggregate should correctly handle infinities" group_builder-> pos_inf = 1/0 @@ -1560,7 +1559,7 @@ add_aggregate_specs suite_builder setup = group_builder.specify "should warn when encountering invalid expressions, but try to perform the aggregations that are still valid" <| action1 = data.table.aggregate ["Index"] [Sum "Value", Sum (expr "[MISSING]*[MISSING]")] on_problems=_ - tester1 = expect_column_names ["Index", "Sum Value"] + tester1 t = expect_column_names ["Index", "Sum Value"] t problems1 = [Invalid_Aggregate_Column.Error "[MISSING]*[MISSING]" (No_Such_Column.Error "MISSING")] Problems.test_problem_handling action1 problems1 tester1 @@ -1624,7 +1623,7 @@ add_aggregate_specs suite_builder setup = action2 = table.aggregate ["Index"] [Sum "Value", Sum 42] on_problems=_ problems2 = [Missing_Input_Columns.Error [42]] - tester2 = expect_column_names ["Index", "Sum Value"] + tester2 t = expect_column_names ["Index", "Sum Value"] t Problems.test_problem_handling action2 problems2 tester2 # As above, missing errors from group-by take precedence over aggregates. @@ -1638,31 +1637,31 @@ add_aggregate_specs suite_builder setup = group_builder.specify "should raise a warning when a duplicate column name" <| action = table.aggregate ["Index", 0] [] on_problems=_ problems = [Duplicate_Output_Column_Names.Error ["Index"]] - tester = expect_column_names ["Index", "Index 1"] + tester t = expect_column_names ["Index", "Index 1"] t Problems.test_problem_handling action problems tester group_builder.specify "should raise a warning when a duplicate column name and rename default names first" <| action = table.aggregate ["Value"] [Sum "Index" "Value"] on_problems=_ problems = [Duplicate_Output_Column_Names.Error ["Value"]] - tester = expect_column_names ["Value 1", "Value"] + tester t = expect_column_names ["Value 1", "Value"] t Problems.test_problem_handling action problems tester group_builder.specify "should raise a warning when duplicate column names" <| action = table.aggregate columns=[Sum "Value" as="AGG1", Count as="AGG1"] on_problems=_ problems = [Duplicate_Output_Column_Names.Error ["AGG1"]] - tester = expect_column_names ["AGG1", "AGG1 1"] + tester t = expect_column_names ["AGG1", "AGG1 1"] t Problems.test_problem_handling action problems tester group_builder.specify "should allow partial matches on Count_Distinct" <| action = table.aggregate columns=[Count_Distinct ["Missing", "Value"]] on_problems=_ problems = [Missing_Input_Columns.Error ["Missing"]] - tester = expect_column_names ["Count Distinct Value"] + tester t = expect_column_names ["Count Distinct Value"] t Problems.test_problem_handling action problems tester group_builder.specify "should ignore Count_Distinct if no columns matched" <| action = table.aggregate columns=[Count_Distinct [-100], Count] on_problems=_ problems = [Missing_Input_Columns.Error [-100]] - tester = expect_column_names ["Count"] + tester t = expect_column_names ["Count"] t Problems.test_problem_handling action problems tester suite_builder.group prefix+"Table.aggregate should report warnings and errors based on types" group_builder-> @@ -1670,7 +1669,7 @@ add_aggregate_specs suite_builder setup = t = table_builder [["X", [1.1, 2.2, 3.3, 2.2]]] action = t.aggregate ["X"] on_problems=_ problems = [Floating_Point_Equality.Error "X"] - tester = expect_column_names ["X"] + tester t = expect_column_names ["X"] t Problems.test_problem_handling action problems tester case test_selection.advanced_stats of @@ -1679,7 +1678,7 @@ add_aggregate_specs suite_builder setup = t = table_builder [["X", [1.5, 2.0, 1.5, 1.0]]] action = t.aggregate columns=[Mode "X"] on_problems=_ problems = [Floating_Point_Equality.Error "Mode X"] - tester = expect_column_names ["Mode X"] + tester t = expect_column_names ["Mode X"] t Problems.test_problem_handling action problems tester False -> group_builder.specify "should error if unsupported operations are selected" <| @@ -1746,7 +1745,7 @@ add_aggregate_specs suite_builder setup = column = Concatenate "Text" separator="," action = table.aggregate columns=[column] on_problems=_ problems = [Unquoted_Delimiter.Error "Concatenate Text" [1]] - tester = expect_column_names ["Concatenate Text"] + tester t = expect_column_names ["Concatenate Text"] t Problems.test_problem_handling action problems tester suite_builder.group prefix+"Table.aggregate should merge warnings when issues computing aggregation" pending=(resolve_pending test_selection.aggregation_problems) group_builder-> diff --git a/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso index af7a04900cff..ca89e9d56594 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Join/Join_Spec.enso @@ -644,7 +644,7 @@ add_join_specs suite_builder setup = t6.column_names.should_equal ["Right X", "X", "Y", "Right Y 2"]+["Right Right X", "Right X 1", "Right Y 3", "Right Y", "Right Y 1", "Right Y 4"] action = t1.join t2 right_prefix="" on_problems=_ - tester = expect_column_names ["X", "Y", "Right Y", "X 1", "Y 1"] + tester t = expect_column_names ["X", "Y", "Right Y", "X 1", "Y 1"] t problems = [Duplicate_Output_Column_Names.Error ["X", "Y"]] Problems.test_problem_handling action problems tester diff --git a/test/Table_Tests/src/Common_Table_Operations/Main.enso b/test/Table_Tests/src/Common_Table_Operations/Main.enso index 4dc890751917..32df94e175b0 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Main.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Main.enso @@ -3,6 +3,7 @@ from Standard.Base import all import Standard.Database.Internal.Replace_Params.Replace_Params from Standard.Test import Test +import Standard.Test.Frame_Hider.Frame_Hider import project.Common_Table_Operations.Add_Group_Number_Spec import project.Common_Table_Operations.Add_Row_Number_Spec @@ -84,11 +85,10 @@ type Test_Setup supports_custom_objects self = self.is_database.not ## Checks if the provided column has integer type as defined by the backend. - expect_integer_type self column = - loc = Test.get_source_location 1 + expect_integer_type self column = Frame_Hider.hide <| value_type = column.value_type if self.is_integer_type value_type then column else - Test.fail ("Expected column ["+column.name+"] to have integer type, but got "+value_type.to_display_text+" (at " + loc + ").") + Test.fail ("Expected column ["+column.name+"] to have integer type, but got "+value_type.to_display_text+" (at " + Frame_Hider.get_top_stack_frame + ").") type Test_Selection ## The configuration specifying what features are supported by a given diff --git a/test/Table_Tests/src/Common_Table_Operations/Select_Columns_Spec.enso b/test/Table_Tests/src/Common_Table_Operations/Select_Columns_Spec.enso index 257b178ef2fc..d3d821b3da31 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Select_Columns_Spec.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Select_Columns_Spec.enso @@ -144,7 +144,7 @@ add_select_column_specs suite_builder setup = group_builder.specify "should correctly handle problems: out of bounds indices" <| selector = [1, 0, 100, -200, 300] action = data.table.select_columns selector error_on_missing_columns=False on_problems=_ - tester = expect_column_names ["foo", "bar"] + tester t = expect_column_names ["foo", "bar"] t problems = [Missing_Input_Columns.Error [100, -200, 300]] Problems.test_problem_handling action problems tester @@ -190,7 +190,7 @@ add_select_column_specs suite_builder setup = weird_name = '.*?-!@#!"' selector = ["foo", "hmm", weird_name] action = data.table.select_columns selector error_on_missing_columns=False on_problems=_ - tester = expect_column_names ["foo"] + tester t = expect_column_names ["foo"] t problems = [Missing_Input_Columns.Error ["hmm", weird_name]] Problems.test_problem_handling action problems tester @@ -279,7 +279,7 @@ add_select_column_specs suite_builder setup = group_builder.specify "should correctly handle problems: out of bounds indices" <| selector = [1, 0, 100, -200, 300] action = data.table.remove_columns selector on_problems=_ - tester = expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] + tester t = expect_column_names ["Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t problems = [Missing_Input_Columns.Error [100, -200, 300]] Problems.test_problem_handling action problems tester @@ -310,7 +310,7 @@ add_select_column_specs suite_builder setup = weird_name = '.*?-!@#!"' selector = ["foo", "hmm", weird_name] action = data.table.remove_columns selector on_problems=_ - tester = expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] + tester t = expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t problems = [Missing_Input_Columns.Error ["hmm", weird_name]] Problems.test_problem_handling action problems tester @@ -375,7 +375,7 @@ add_select_column_specs suite_builder setup = group_builder.specify "should correctly handle problems: out of bounds indices" <| selector = [1, 0, 100, -200, 300] action = data.table.reorder_columns selector on_problems=_ - tester = expect_column_names ["bar", "foo", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] + tester t = expect_column_names ["bar", "foo", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123"] t problems = [Missing_Input_Columns.Error [100, -200, 300]] Problems.test_problem_handling action problems tester @@ -401,7 +401,7 @@ add_select_column_specs suite_builder setup = weird_name = '.*?-!@#!"' selector = ["foo", "hmm", weird_name] action = data.table.reorder_columns selector Position.After_Other_Columns on_problems=_ - tester = expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] + tester t = expect_column_names ["bar", "Baz", "foo 1", "foo 2", "ab.+123", "abcd123", "foo"] t problems = [Missing_Input_Columns.Error ["hmm", weird_name]] Problems.test_problem_handling action problems tester @@ -559,7 +559,7 @@ add_select_column_specs suite_builder setup = weird_name = '.*?-!@#!"' map = Dictionary.from_vector [["alpha", "FirstColumn"], ["omicron", "Another"], [weird_name, "Fixed"]] action = data.table.rename_columns map error_on_missing_columns=False on_problems=_ - tester = expect_column_names ["FirstColumn", "beta", "gamma", "delta"] + tester t = expect_column_names ["FirstColumn", "beta", "gamma", "delta"] t err_checker err = err.catch.should_be_a Missing_Input_Columns.Error err.catch.criteria.should_equal_ignoring_order ["omicron", weird_name] @@ -571,7 +571,7 @@ add_select_column_specs suite_builder setup = group_builder.specify "should correctly handle problems: out of bounds indices" <| map = Dictionary.from_vector [[0, "FirstColumn"], [-1, "Another"], [100, "Boo"], [-200, "Nothing"], [300, "Here"]] action = data.table.rename_columns map error_on_missing_columns=False on_problems=_ - tester = expect_column_names ["FirstColumn", "beta", "gamma", "Another"] + tester t = expect_column_names ["FirstColumn", "beta", "gamma", "Another"] t err_checker err = err.catch.should_be_a Missing_Input_Columns.Error err.catch.criteria.should_equal_ignoring_order [-200, 100, 300] @@ -639,14 +639,14 @@ add_select_column_specs suite_builder setup = group_builder.specify "should correctly handle problems: duplicate names" <| map = ["Test", "Test", "Test", "Test"] action = data.table.rename_columns map on_problems=_ - tester = expect_column_names ["Test 1", "Test 2", "Test 3", "Test"] ignore_order=True + tester t = expect_column_names ["Test 1", "Test 2", "Test 3", "Test"] t ignore_order=True problems = [Duplicate_Output_Column_Names.Error ["Test", "Test", "Test"]] Problems.test_problem_handling action problems tester group_builder.specify "should correctly handle problems: new name is clashing with existing name of existing column" <| map = Dictionary.from_vector [["alpha", "beta"]] action = data.table.rename_columns map on_problems=_ - tester = expect_column_names ["beta", "beta 1", "gamma", "delta"] + tester t = expect_column_names ["beta", "beta 1", "gamma", "delta"] t problems = [Duplicate_Output_Column_Names.Error ["beta"]] Problems.test_problem_handling action problems tester @@ -659,7 +659,7 @@ add_select_column_specs suite_builder setup = group_builder.specify "should correctly handle problems: too many input names" <| map = ["A", "B", "C", "D", "E", "F"] action = data.table.rename_columns map on_problems=_ - tester = expect_column_names ["A", "B", "C", "D"] + tester t = expect_column_names ["A", "B", "C", "D"] t problem_checker problem = problem.should_be_a Too_Many_Column_Names_Provided.Error problem.column_names.should_equal_ignoring_order ["E", "F"] diff --git a/test/Table_Tests/src/Common_Table_Operations/Util.enso b/test/Table_Tests/src/Common_Table_Operations/Util.enso index 6030e5538415..bc4cdd2b85c5 100644 --- a/test/Table_Tests/src/Common_Table_Operations/Util.enso +++ b/test/Table_Tests/src/Common_Table_Operations/Util.enso @@ -7,10 +7,10 @@ from Standard.Test import all from project.In_Memory.Common_Spec import in_memory_setup -expect_column_names names table ignore_order=False = +expect_column_names names table ignore_order=False = Frame_Hider.hide <| case ignore_order of - False -> table.columns . map .name . should_equal names frames_to_skip=2 - True -> table.columns . map .name . sort . should_equal names.sort frames_to_skip=2 + False -> table.columns . map .name . should_equal names + True -> table.columns . map .name . sort . should_equal names.sort ## These tests are parametrized by various backends and so they should be run in context of a specific backend. However, for the purpose of testing we provide @@ -49,10 +49,9 @@ within_table table = Test.with_clue 'Resulting table:\n'+description+'\n\n' ## PRIVATE -Any.should_equal_tz_agnostic self other = - loc = Test.get_source_location 1 +Any.should_equal_tz_agnostic self other = Frame_Hider.hide <| _ = other - Test.fail "Expected a vector but got "+self.to_display_text+" (at "+loc+")." + Test.fail "Expected a vector but got "+self.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." ## PRIVATE A helper method that compares two vectors of Date_Time values. @@ -60,24 +59,22 @@ Any.should_equal_tz_agnostic self other = It ensures that they represent the same instant in time, but ignore the timezone that is attached to them. This is simply done by converting them to UTC. -Vector.should_equal_tz_agnostic self other = - loc = Test.get_source_location 1 +Vector.should_equal_tz_agnostic self other = Frame_Hider.hide <| case other of _ : Vector -> utc = Time_Zone.utc normalize_date_time dt = case dt of _ : Date_Time -> dt.at_zone utc - _ -> Test.fail "The vector should contain Date_Time objects but it contained "+dt.to_display_text+" (at "+loc+")" + _ -> Test.fail "The vector should contain Date_Time objects but it contained "+dt.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")" self_normalized = self.map normalize_date_time other_normalized = other.map normalize_date_time - self_normalized.should_equal other_normalized frames_to_skip=2 - _ -> Test.fail "Expected a vector but got "+other.to_display_text+" (at "+loc+")" + self_normalized.should_equal other_normalized + _ -> Test.fail "Expected a vector but got "+other.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")" ## PRIVATE -Error.should_equal_tz_agnostic self other = - loc = Test.get_source_location 1 +Error.should_equal_tz_agnostic self other = Frame_Hider.hide <| _ = other - Test.fail "Expected a vector but got a dataflow error "+self.catch.to_display_text+" (at "+loc+")." + Test.fail "Expected a vector but got a dataflow error "+self.catch.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." ## PRIVATE Builds a table ensuring that the rows are in the order as given. diff --git a/test/Table_Tests/src/IO/Fetch_Spec.enso b/test/Table_Tests/src/IO/Fetch_Spec.enso index c4b11c1a27c6..e6e02fce2093 100644 --- a/test/Table_Tests/src/IO/Fetch_Spec.enso +++ b/test/Table_Tests/src/IO/Fetch_Spec.enso @@ -135,9 +135,9 @@ add_specs suite_builder = after_count = get_num_response_cache_entries [before_count, after_count] - expect_counts expected_counts ~action = + expect_counts expected_counts ~action = Frame_Hider.hide <| counts = with_counts action - counts . should_equal expected_counts frames_to_skip=1 + counts . should_equal expected_counts get_cache_files : Vector Text get_cache_files -> Vector Text = diff --git a/test/Table_Tests/src/In_Memory/Table_Spec.enso b/test/Table_Tests/src/In_Memory/Table_Spec.enso index 36e922007ae6..f71df5bc5f1f 100644 --- a/test/Table_Tests/src/In_Memory/Table_Spec.enso +++ b/test/Table_Tests/src/In_Memory/Table_Spec.enso @@ -703,8 +703,8 @@ add_specs suite_builder = actual.column_names . should_equal ["col0", "col_between", "col1"] suite_builder.group "Use First Row As Names" group_builder-> - expect_column_names names table = - table.columns . map .name . should_equal names frames_to_skip=2 + expect_column_names names table = Frame_Hider.hide <| + table.columns . map .name . should_equal names group_builder.specify "should work happily with mixed types" <| c_0 = ['A', ["H", "B", "C"]] @@ -723,7 +723,7 @@ add_specs suite_builder = c_4 = ['Z', [True, False, True]] table = Table.new [c_0, c_1, c_2, c_3, c_4] action = table.use_first_row_as_names on_problems=_ - tester = expect_column_names ["Column 1", "1980-01-01", "1", "5.3", "True"] + tester t = expect_column_names ["Column 1", "1980-01-01", "1", "5.3", "True"] t problems = [Invalid_Column_Names.Error [""]] Problems.test_problem_handling action problems tester @@ -735,7 +735,7 @@ add_specs suite_builder = c_4 = ['Z', [True, False, True]] table = Table.new [c_0, c_1, c_2, c_3, c_4] action = table.use_first_row_as_names on_problems=_ - tester = expect_column_names ["A", "1980-01-01", "Column 1", "5.3", "True"] + tester t = expect_column_names ["A", "1980-01-01", "Column 1", "5.3", "True"] t problems = [Invalid_Column_Names.Error [Nothing]] Problems.test_problem_handling action problems tester @@ -747,7 +747,7 @@ add_specs suite_builder = c_4 = ['Z', [True, False, True]] table = Table.new [c_0, c_1, c_2, c_3, c_4] action = table.use_first_row_as_names on_problems=_ - tester = expect_column_names ["Column 1", "1980-01-01", "Column 2", "5.3", "True"] + tester t = expect_column_names ["Column 1", "1980-01-01", "Column 2", "5.3", "True"] t problems = [Invalid_Column_Names.Error ["", Nothing]] Problems.test_problem_handling action problems tester @@ -758,7 +758,7 @@ add_specs suite_builder = c_3 = ['C', ["A", "B", "C"]] table = Table.new [c_0, c_1, c_2, c_3] action = table.use_first_row_as_names on_problems=_ - tester = expect_column_names ["A", "A 1", "A 2", "A 3"] + tester t = expect_column_names ["A", "A 1", "A 2", "A 3"] t problems = [Duplicate_Output_Column_Names.Error ["A", "A", "A"]] Problems.test_problem_handling action problems tester diff --git a/test/Table_Tests/src/Util.enso b/test/Table_Tests/src/Util.enso index 424b243dbc31..0a9b1fe65dfa 100644 --- a/test/Table_Tests/src/Util.enso +++ b/test/Table_Tests/src/Util.enso @@ -9,33 +9,31 @@ from Standard.Test import all polyglot java import org.enso.base_test_helpers.FileSystemHelper -Table.should_equal : Any -> Integer -> Boolean -> Any -Table.should_equal self expected frames_to_skip=0 ignore_order=False = - loc = Test.get_source_location 1+frames_to_skip +Table.should_equal : Any -> Boolean -> Any +Table.should_equal self expected ignore_order=False = Frame_Hider.hide <| rhs_error_check expected - Panic.catch Test_Failure_Error (table_should_equal_impl self expected loc ignore_order) error-> + Panic.catch Test_Failure_Error (table_should_equal_impl self expected ignore_order) error-> Test.fail error.payload.message -Column.should_equal : Any -> Integer -> Any -Column.should_equal self expected frames_to_skip=0 = - loc = Test.get_source_location 1+frames_to_skip +Column.should_equal : Any -> Any +Column.should_equal self expected = Frame_Hider.hide <| rhs_error_check expected - Panic.catch Test_Failure_Error (column_should_equal_impl self expected loc) error-> + Panic.catch Test_Failure_Error (column_should_equal_impl self expected) error-> Test.fail error.payload.message -DB_Table.should_equal : DB_Table|Table -> Integer -> Boolean -> Any -DB_Table.should_equal self expected frames_to_skip=0 ignore_order=False = +DB_Table.should_equal : DB_Table|Table -> Boolean -> Any +DB_Table.should_equal self expected ignore_order=False = Frame_Hider.hide <| rhs_error_check expected t0 = self.read t1 = expected.read - t0 . should_equal t1 frames_to_skip+1 ignore_order + t0 . should_equal t1 ignore_order -DB_Column.should_equal : DB_Column -> Integer -> Any -DB_Column.should_equal self expected frames_to_skip=0 = +DB_Column.should_equal : DB_Column -> Any +DB_Column.should_equal self expected = Frame_Hider.hide <| rhs_error_check expected t0 = self.read t1 = expected.read - t0 . should_equal t1 frames_to_skip+1 + t0 . should_equal t1 type Test_Failure_Error ## PRIVATE @@ -50,49 +48,49 @@ type Test_Failure_Error to_display_text self = "Test failure error: "+self.message ## PRIVATE -table_should_equal_impl actual_table expected_table loc ignore_order = +table_should_equal_impl actual_table expected_table ignore_order = Frame_Hider.hide <| case expected_table of _ : Table -> actual = if ignore_order then actual_table.sort actual_table.column_names else actual_table expected = if ignore_order then expected_table.sort expected_table.column_names else expected_table if actual.columns.length != expected.columns.length then - Panic.throw (Test_Failure_Error.Error 'Tables differ at '+loc+'.\nActual:\n'+actual_table.display+'\nExpected:\n'+expected_table.display+'\nExpected '+expected.columns.length.to_text+" columns, but got "+actual.columns.length.to_text+'.') - Panic.catch Test_Failure_Error (actual.columns.zip expected.columns a-> e->(column_should_equal_impl a e)) error-> + Panic.throw (Test_Failure_Error.Error 'Tables differ at '+Frame_Hider.get_top_stack_frame+'.\nActual:\n'+actual_table.display+'\nExpected:\n'+expected_table.display+'\nExpected '+expected.columns.length.to_text+" columns, but got "+actual.columns.length.to_text+'.') + Panic.catch Test_Failure_Error (actual.columns.zip expected.columns a-> e->(column_should_equal_impl a e False)) error-> msg_sorted = if ignore_order then " (sorted)" else "" - msg = 'Tables differ at '+loc+'.\nActual'+msg_sorted+':\n'+actual.display+'\nExpected'+msg_sorted+':\n'+expected.display+'\n'+error.payload.message + msg = 'Tables differ at '+Frame_Hider.get_top_stack_frame+'.\nActual'+msg_sorted+':\n'+actual.display+'\nExpected'+msg_sorted+':\n'+expected.display+'\n'+error.payload.message Panic.throw (Test_Failure_Error.Error msg) - _ -> Panic.throw (Test_Failure_Error.Error "Got a Table, but expected a "+expected_table.to_display_text+(display_loc loc)+'.') + _ -> Panic.throw (Test_Failure_Error.Error "Got a Table, but expected a "+expected_table.to_display_text+' (at '+Frame_Hider.get_top_stack_frame+').') ## PRIVATE -column_should_equal_impl actual expected loc='' = +column_should_equal_impl actual expected should_display:Boolean=True = Frame_Hider.hide <| case expected of _ : Column -> if actual.name != expected.name then - Panic.throw (Test_Failure_Error.Error "Expected column name "+expected.name+", but got "+actual.name+(display_loc loc)+'.') + Panic.throw (Test_Failure_Error.Error "Expected column name "+expected.name+", but got "+actual.name+(display_loc should_display)+'.') if actual.length != expected.length then - Panic.throw (Test_Failure_Error.Error "Expected column length "+expected.length.to_text+", but got "+actual.length.to_text+(display_loc loc)+'.') + Panic.throw (Test_Failure_Error.Error "Expected column length "+expected.length.to_text+", but got "+actual.length.to_text+(display_loc should_display)+'.') if actual.value_type != expected.value_type then - Panic.throw (Test_Failure_Error.Error "Expected column type "+expected.value_type.to_text+", but got "+actual.value_type.to_text+(display_loc loc)+'.') + Panic.throw (Test_Failure_Error.Error "Expected column type "+expected.value_type.to_text+", but got "+actual.value_type.to_text+(display_loc should_display)+'.') actual.zip expected skip_nothing=False a-> e-> if values_not_equal a e then - report_fail actual expected loc - _ -> Panic.throw (Test_Failure_Error.Error "Got a Column, but expected a "+expected.to_display_text+(display_loc loc)+'.') + report_fail actual expected should_display + _ -> Panic.throw (Test_Failure_Error.Error "Got a Column, but expected a "+expected.to_display_text+(display_loc should_display)+'.') ## PRIVATE values_not_equal a e = a != e && (a.is_a Number && e.is_a Number && a.is_nan && e.is_nan).not ## PRIVATE -report_fail actual expected loc = +report_fail actual expected should_display = Frame_Hider.hide <| indexed = actual.zip (0.up_to actual.length) skip_nothing=False a-> i-> Pair.new a i indexed.zip expected skip_nothing=False a-> e-> if values_not_equal a.first e then - Panic.throw (Test_Failure_Error.Error "Column: "+actual.name+" differs at row "+a.second.to_text+'.\n\t Actual : '+a.first.to_text+'\n\t Expected: '+e.to_text+'\n\t'+(display_loc loc)+'.') + Panic.throw (Test_Failure_Error.Error "Column: "+actual.name+" differs at row "+a.second.to_text+'.\n\t Actual : '+a.first.to_text+'\n\t Expected: '+e.to_text+'\n\t'+(display_loc should_display)+'.') ## PRIVATE -display_loc loc:Text = - if loc.is_empty then '' else - ' (at '+loc+')' +display_loc should_display:Boolean = + if should_display.not then '' else + ' (at '+Frame_Hider.get_top_stack_frame+')' normalize_lines string line_separator=Line_Ending_Style.Unix.to_text newline_at_end=True = case newline_at_end of @@ -113,18 +111,17 @@ set_writable file writable = For example, if `example` is `[[1, 2], [3]]`, then both `[1, 2, 3]` and `[2, 1, 3]` will be accepted, but `[2, 3, 1]` will be rejected. -Any.should_have_relative_ordering self (example : Vector) = - loc = Test.get_source_location 1 +Any.should_have_relative_ordering self (example : Vector) = Frame_Hider.hide <| case self of _ : Vector -> example.each v-> case v of _ : Vector -> - if v.is_empty then Test.fail "The example vector should not contain empty vectors as they are meaningless (at "+loc+")." - _ -> Test.fail "Expected a vector of vectors but got a vector containing "+v.to_display_text+" (at "+loc+")." + if v.is_empty then Test.fail "The example vector should not contain empty vectors as they are meaningless (at "+Frame_Hider.get_top_stack_frame+")." + _ -> Test.fail "Expected a vector of vectors but got a vector containing "+v.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." total_length = example.fold 0 acc-> v-> acc+v.length if self.length != total_length then - Test.fail "Expected a vector of length "+total_length.to_text+" but got "+self.length.to_text+" (at "+loc+")." + Test.fail "Expected a vector of length "+total_length.to_text+" but got "+self.length.to_text+" (at "+Frame_Hider.get_top_stack_frame+")." pieces = Vector.build builder-> example.fold 0 offset-> reference_v-> @@ -141,15 +138,14 @@ Any.should_have_relative_ordering self (example : Vector) = (got_piece.sort on_problems=..Report_Error) == (expected_piece.sort on_problems=..Report_Error) if are_consistent.not then offset = pieces.take ix . fold 0 acc-> p-> acc+p.length - Test.fail "Expected the run of vector elements starting at offset "+offset.to_text+" to be a permutation of "+expected_piece.to_display_text+" but got "+got_piece.to_display_text+" (at "+loc+")." + Test.fail "Expected the run of vector elements starting at offset "+offset.to_text+" to be a permutation of "+expected_piece.to_display_text+" but got "+got_piece.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." - _ -> Test.fail "Expected a vector but got "+self.to_display_text+" (at "+loc+")." + _ -> Test.fail "Expected a vector but got "+self.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." ## PRIVATE See `Any.should_have_relative_ordering`. -Error.should_have_relative_ordering self example = - loc = Test.get_source_location 1 +Error.should_have_relative_ordering self example = Frame_Hider.hide <| _ = example - Test.fail "Expected a vector but got a dataflow error "+self.catch.to_display_text+" (at "+loc+")." + Test.fail "Expected a vector but got a dataflow error "+self.catch.to_display_text+" (at "+Frame_Hider.get_top_stack_frame+")." ## PRIVATE diff --git a/test/Table_Tests/src/Util_Spec.enso b/test/Table_Tests/src/Util_Spec.enso index 6d68a14d6366..21c551b26d09 100644 --- a/test/Table_Tests/src/Util_Spec.enso +++ b/test/Table_Tests/src/Util_Spec.enso @@ -61,33 +61,33 @@ add_specs suite_builder = group_builder.specify "Two Columns With Different Name are Not Equal" <| expected_column = Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"] actual_column = Column.from_vector "Col2" ["Quis", "custodiet", "ipsos", "custodes?"] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal "Expected column name Col1, but got Col2 (at LOCATION_PATH)." + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with "Expected column name Col1, but got Col2 (at " group_builder.specify "Two Columns With Different Lengths are Not Equal" <| expected_column = Column.from_vector "Col" ["Quis", "custodiet", "ipsos", "custodes?"] actual_column = Column.from_vector "Col" ["Quis", "custodiet", "ipsos"] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal "Expected column length 4, but got 3 (at LOCATION_PATH)." + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with "Expected column length 4, but got 3 (at " group_builder.specify "Two Columns with different content Are Not Equal" <| expected_column = Column.from_vector "Col" ["Quis", "custodiet", "ipsos", "custodes?"] actual_column = Column.from_vector "Col" ["Who", "guards", "the", "guards?"] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal 'Column: Col differs at row 0.\n\t Actual : Who\n\t Expected: Quis\n\t (at LOCATION_PATH).' + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with 'Column: Col differs at row 0.\n\t Actual : Who\n\t Expected: Quis\n\t (at ' group_builder.specify "Two Columns Are Not Equal in Row 3" <| expected_column = Column.from_vector "My Column" ["Quis", "custodiet", "ipsos", "custodes?"] actual_column = Column.from_vector "My Column" ["Quis", "custodiet", "ipsos", "guards?"] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal 'Column: My Column differs at row 3.\n\t Actual : guards?\n\t Expected: custodes?\n\t (at LOCATION_PATH).' + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with 'Column: My Column differs at row 3.\n\t Actual : guards?\n\t Expected: custodes?\n\t (at ' group_builder.specify "Two Columns with different types Are Not Equal" <| expected_column = Column.from_vector "Col" ["1", "2", "3", "4"] actual_column = Column.from_vector "Col" [1, 2, 3, 4] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal "Expected column type (Char Nothing True), but got (Integer 64 bits) (at LOCATION_PATH)." + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with "Expected column type (Char Nothing True), but got (Integer 64 bits) (at " group_builder.specify "Comparing a Column to non column" <| expected_column = 42 actual_column = Column.from_vector "Col" [1, 2, 3, 4] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal "Got a Column, but expected a 42 (at LOCATION_PATH)." + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with "Got a Column, but expected a 42 (at " group_builder.specify "Two Columns Containing NaNs Are Equal" <| # This is somewhat of a special case, as NaN != NaN but for the purposes of testing we consider them equal expected_column = Column.from_vector "Col" [1.0, 2.0, Number.nan] @@ -100,23 +100,23 @@ add_specs suite_builder = group_builder.specify "Comparing to Actual Nothing Value should fail" <| expected_column = Column.from_vector "Col" [1.0, 2.0, 3.0] actual_column = Column.from_vector "Col" [1.0, 2.0, Nothing] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal 'Column: Col differs at row 2.\n\t Actual : Nothing\n\t Expected: 3.0\n\t (at LOCATION_PATH).' + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with 'Column: Col differs at row 2.\n\t Actual : Nothing\n\t Expected: 3.0\n\t (at ' group_builder.specify "Comparing to Expected Nothing Value should fail" <| expected_column = Column.from_vector "Col" [1.0, 2.0, Nothing] actual_column = Column.from_vector "Col" [1.0, 2.0, 3.0] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal 'Column: Col differs at row 2.\n\t Actual : 3.0\n\t Expected: Nothing\n\t (at LOCATION_PATH).' + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with 'Column: Col differs at row 2.\n\t Actual : 3.0\n\t Expected: Nothing\n\t (at ' group_builder.specify "Comparing to Actual Nothing Value to Expected NaN Value should fail" <| expected_column = Column.from_vector "Col" [1.0, 2.0, Number.nan] actual_column = Column.from_vector "Col" [1.0, 2.0, Nothing] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal 'Column: Col differs at row 2.\n\t Actual : Nothing\n\t Expected: NaN\n\t (at LOCATION_PATH).' + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with 'Column: Col differs at row 2.\n\t Actual : Nothing\n\t Expected: NaN\n\t (at ' group_builder.specify "Comparing to Actual NaN Value to Expected Nothing Value should fail" <| expected_column = Column.from_vector "Col" [1.0, 2.0, Nothing] actual_column = Column.from_vector "Col" [1.0, 2.0, Number.nan] - res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column "LOCATION_PATH") - res.catch.message.should_equal 'Column: Col differs at row 2.\n\t Actual : NaN\n\t Expected: Nothing\n\t (at LOCATION_PATH).' + res = Panic.recover Test_Failure_Error (column_should_equal_impl actual_column expected_column) + res.catch.message.should_start_with 'Column: Col differs at row 2.\n\t Actual : NaN\n\t Expected: Nothing\n\t (at ' group_builder.specify "Two Tables Are Equal" <| expected_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] @@ -133,35 +133,37 @@ add_specs suite_builder = group_builder.specify "Two Tables With Different Values" <| expected_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] actual_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "teh", "guards?"]] - res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table "LOCATION_PATH" False) + res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table False) res.catch.message.should_end_with 'Column: Col2 differs at row 2.\n\t Actual : teh\n\t Expected: the\n\t.' - res.catch.message.should_start_with 'Tables differ at LOCATION_PATH.\nActual:' + res.catch.message.should_start_with 'Tables differ at ' + res.catch.message.should_contain 'Util_Spec.enso:136:53-109.\nActual:' group_builder.specify "Two Tables With Different Values Ignoring Order" <| expected_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] actual_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "teh", "guards?"]] - res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table "LOCATION_PATH" True) + res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table True) res.catch.message.should_end_with 'Column: Col2 differs at row 3.\n\t Actual : teh\n\t Expected: the\n\t.' - res.catch.message.should_start_with 'Tables differ at LOCATION_PATH.\nActual (sorted):' + res.catch.message.should_start_with 'Tables differ at ' + res.catch.message.should_contain 'Util_Spec.enso:143:53-108.\nActual (sorted):' group_builder.specify "Tables different number of columns" <| expected_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"]] actual_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] - res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table "LOCATION_PATH" False) + res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table False) res.catch.message.should_end_with "Expected 1 columns, but got 2." group_builder.specify "Tables different number of columns2" <| expected_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] actual_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"]] - res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table "LOCATION_PATH" False) + res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table False) res.catch.message.should_end_with "Expected 2 columns, but got 1." group_builder.specify "Tables With Mismatched Column names" <| expected_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] actual_table = Table.new [Column.from_vector "Col" ["Quis", "custodiet", "ipsos", "custodes?"], Column.from_vector "Col2" ["Who", "guards", "the", "guards?"]] - res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table "LOCATION_PATH" False) + res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table False) res.catch.message.should_end_with "Expected column name Col1, but got Col." group_builder.specify "Comparing a Table to non Table" <| expected_table = 42 actual_table = Table.new [Column.from_vector "Col1" ["Quis", "custodiet", "ipsos", "custodes?"]] - res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table "LOCATION_PATH" False) - res.catch.message.should_equal "Got a Table, but expected a 42 (at LOCATION_PATH)." + res = Panic.recover Test_Failure_Error (table_should_equal_impl actual_table expected_table False) + res.catch.message.should_start_with "Got a Table, but expected a 42 (at " type DB_Tables Value t1 t2 tA diff --git a/test/Test_Tests/src/Extensions_Spec.enso b/test/Test_Tests/src/Extensions_Spec.enso index afee91d94597..a49701a0f28b 100644 --- a/test/Test_Tests/src/Extensions_Spec.enso +++ b/test/Test_Tests/src/Extensions_Spec.enso @@ -84,3 +84,68 @@ add_specs suite_builder = r1 = expect_test_failure <| "abc".should_end_with "d" r1.message.should_contain "Extensions_Spec.enso:85" + + suite_builder.group "stack trace location and frame hiding" group_builder-> + group_builder.specify "should be able to get a stack trace without test helper frames" <| + r1 = expect_test_failure <| + "ab".should_equal "ac" + r1.message.should_contain "Extensions_Spec.enso:91" + + group_builder.specify "should be able to get a stack trace without test helper frames (with nesting)" <| + should_equal_2 x y = Frame_Hider.hide <| + x.should_equal y + should_equal_3 x y = Frame_Hider.hide <| + should_equal_2 x y + + r1 = expect_test_failure <| + should_equal_3 "ab" "ac" + r1.message.should_contain "Extensions_Spec.enso:101" + + group_builder.specify "should be able to get a stack trace without test helper frames (with nesting and a no-arg callback)" <| + ## This test is here because of differences in stack traces with no-arg calls. + should_equal_a checker _ _ = Frame_Hider.hide <| + Frame_Hider.unhide checker + should_equal_b checker x y = Frame_Hider.hide <| + should_equal_a (Frame_Hider.unhide checker) x y + + my_checker = + False . should_be_true + + r1 = expect_test_failure <| + should_equal_b my_checker "ab" "ac" + r1.message.should_contain "Extensions_Spec.enso:112" + + group_builder.specify "should be able to get a stack trace without test helper frames (with nesting and a one-arg callback)" <| + should_equal_a checker x = Frame_Hider.hide <| + Frame_Hider.unhide (checker x) + should_equal_b checker x = Frame_Hider.hide <| + should_equal_a (Frame_Hider.unhide_1 checker x) + + my_checker x = + x . should_equal "ac" + + r1 = expect_test_failure <| + should_equal_b my_checker "ab" + r1.message.should_contain "Extensions_Spec.enso:125" + + group_builder.specify "should be able to get a stack trace without test helper frames (with nesting and a two-arg callback)" <| + should_equal_a checker x y = Frame_Hider.hide <| + Frame_Hider.unhide (checker x y) + should_equal_b checker x y = Frame_Hider.hide <| + should_equal_a (Frame_Hider.unhide_2 checker x y) + + my_checker x y = + x.should_equal y + + r1 = expect_test_failure <| + should_equal_b my_checker "ab" "ac" + r1.message.should_contain "Extensions_Spec.enso:138" + + location_pending = case Platform.os of + Platform.OS.Windows -> "This test is disabled on Windows until issue 1561 is fixed." + _ -> Nothing + + group_builder.specify "should allow to get the source location of a frame" pending=location_pending <| + src = Frame_Hider.get_top_stack_frame + loc = "Extensions_Spec.enso:149:19-49" + src.take (..Last loc.length) . should_equal loc diff --git a/test/Test_Tests/src/Helpers.enso b/test/Test_Tests/src/Helpers.enso index 5942d2f545f6..f03effbbe97c 100644 --- a/test/Test_Tests/src/Helpers.enso +++ b/test/Test_Tests/src/Helpers.enso @@ -1,11 +1,11 @@ from Standard.Base import all +import Standard.Test.Frame_Hider.Frame_Hider import Standard.Test.Spec_Result.Spec_Result from Standard.Test import Test ## Expects the inner action to report a test failure exception and returns its payload. -expect_test_failure ~action -> Spec_Result = - loc = Test.get_source_location 1 +expect_test_failure ~action -> Spec_Result = Frame_Hider.hide <| handle_panic caught_panic = result = caught_panic.payload case result of @@ -13,5 +13,5 @@ expect_test_failure ~action -> Spec_Result = _ -> Test.fail "Expected test failure, but "+result.to_text+" was raised as error." Panic.catch Spec_Result handler=handle_panic <| - action - Test.fail "Expected the inner action to fail, but there was no failure (at "+loc+")." + Frame_Hider.unhide action + Test.fail "Expected the inner action to fail, but there was no failure (at "+Frame_Hider.get_top_stack_frame+")."