elixir-lang / elixir

Elixir is a dynamic, functional language for building scalable and maintainable applications
https://elixir-lang.org/
Apache License 2.0
24.65k stars 3.39k forks source link

Exceptions when pattern matching a DateTime struct #14017

Closed timgent closed 2 weeks ago

timgent commented 2 weeks ago

Elixir and Erlang/OTP versions

Erlang/OTP 26 [erts-14.2.5.1] [source] [64-bit] [smp:11:11] [ds:11:11:10] [async-threads:1] [jit]

Elixir 1.17.3 (compiled with Erlang/OTP 26)

Operating system

MacOS - 14.7.1 (23H222)

Current behavior

Running a test which pattern matches a date I get the below error. The error occurs when running mix test but not when running just this individual test. mix test works fine if I comment out this test

** (EXIT from #PID<0.98.0>) an exception was raised:
    ** (RuntimeError) found error while checking types for LearnerPerformanceService.LearnerPerformanceTest."test from_map/1 transforms map into a LearnerPerformance struct if all the data is valid"/1:

** (RuntimeError) expected DateTime to return struct metadata, but got none
The exception happened while checking this code:

def test from_map/1 transforms map into a LearnerPerformance struct if all the data is valid(_) do
  (
    right = %{
      __struct__: DateTime,
      calendar: Calendar.ISO,
      year: 2023,
      month: 9,
      day: 15,
      hour: 11,
      minute: 32,
      second: 16,
      microsecond: {0, 0},
      time_zone: "Etc/UTC",
      zone_abbr: "UTC",
      utc_offset: 0,
      std_offset: 0
    }

    expr =
      {:assert, [line: 132],
       [
         {:=, [line: 132],
          [
            {:%, [line: 132],
             [{:__aliases__, [line: 132], [:DateTime]}, {:%{}, [line: 132], []}]},
            {:sigil_U, [line: 132], [{:<<>>, [line: 132], ["2023-09-15 11:32:16Z"]}, []]}
          ]}
       ]}

    [] =
      case right do
        %DateTime{} ->
          case right do
            x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
              :erlang.error(
                ExUnit.AssertionError.exception(
                  expr: expr,
                  message: <<"Expected truthy, got ", Kernel.inspect(right)::binary>>
                )
              )

            _ ->
              :ok
          end

          []

        _ ->
          left = {:%, [line: 132, column: 14], [DateTime, {:%{}, [line: 132, column: 23], []}]}

          :erlang.error(
            ExUnit.AssertionError.exception(
              left: left,
              right: right,
              expr: expr,
              message: <<"match (=) failed", ExUnit.Assertions.__pins__([])::binary>>,
              context: {:match, []}
            )
          )
      end

    right
  )

  :ok
end

Please report this bug at: https://github.com/elixir-lang/elixir/issues

        (elixir 1.17.3) lib/module/types/of.ex:182: Module.Types.Of.struct/6
        (elixir 1.17.3) lib/module/types/pattern.ex:90: Module.Types.Pattern.of_pattern/4
        (elixir 1.17.3) lib/module/types/helpers.ex:128: Module.Types.Helpers.do_map_reduce_ok/3
        (elixir 1.17.3) lib/module/types/pattern.ex:18: Module.Types.Pattern.of_head/5
        (elixir 1.17.3) lib/module/types/expr.ex:502: anonymous fn/3 in Module.Types.Expr.of_clauses/3
        (elixir 1.17.3) lib/module/types/helpers.ex:108: Module.Types.Helpers.do_reduce_ok/3
        (elixir 1.17.3) lib/module/types/expr.ex:213: Module.Types.Expr.of_expr/3
        (elixir 1.17.3) lib/module/types/expr.ex:125: Module.Types.Expr.of_expr/3
        (elixir 1.17.3) lib/module/types/helpers.ex:128: Module.Types.Helpers.do_map_reduce_ok/3
        (elixir 1.17.3) lib/module/types/expr.ex:185: Module.Types.Expr.of_expr/3
        (elixir 1.17.3) lib/module/types/helpers.ex:128: Module.Types.Helpers.do_map_reduce_ok/3
        (elixir 1.17.3) lib/module/types/expr.ex:185: Module.Types.Expr.of_expr/3
        (elixir 1.17.3) lib/module/types.ex:56: Module.Types.warnings_from_clause/6
        (elixir 1.17.3) lib/module/types.ex:15: anonymous fn/7 in Module.Types.warnings/5
        (elixir 1.17.3) lib/enum.ex:4353: Enum.flat_map_list/2
        (elixir 1.17.3) lib/enum.ex:4354: Enum.flat_map_list/2
        (elixir 1.17.3) lib/module/parallel_checker.ex:264: Module.ParallelChecker.check_module/3
        (elixir 1.17.3) lib/module/parallel_checker.ex:82: anonymous fn/6 in Module.ParallelChecker.spawn/4

Expected behavior

The test should work!

josevalim commented 2 weeks ago

This usually happens if you are using mocking libraries that replace modules. Is that the case? If so, can you please try updating them to the latest? If the issue persists, can you please provide a minimal application that reproduces the error?

timgent commented 2 weeks ago

Thanks, bumping the version of Mimic seems to resolve this