From f0bad129cc282ab4bebba74d708b7c4f6bf74821 Mon Sep 17 00:00:00 2001 From: Lukasz Samson Date: Sat, 28 Sep 2024 13:05:52 +0200 Subject: [PATCH] exclude and fix tests on < 1.15 --- lib/elixir_sense/core/compiler.ex | 12 +++- lib/elixir_sense/core/normalized/macro/env.ex | 10 +++- test/elixir_sense/core/compiler_test.exs | 53 ++++++++++-------- .../metadata_builder/error_recovery_test.exs | 2 + .../core/metadata_builder_test.exs | 56 ++++++------------- test/elixir_sense/core/parser_test.exs | 13 +++++ 6 files changed, 80 insertions(+), 66 deletions(-) diff --git a/lib/elixir_sense/core/compiler.ex b/lib/elixir_sense/core/compiler.ex index c0824047..5e8b5a48 100644 --- a/lib/elixir_sense/core/compiler.ex +++ b/lib/elixir_sense/core/compiler.ex @@ -1747,10 +1747,16 @@ defmodule ElixirSense.Core.Compiler do expanded_arg end) + prematch = if Version.match?(System.version(), ">= 1.15.0-dev") do + Code.get_compiler_option(:on_undefined_variable) + else + :warn + end + {e_guard, state, env_for_expand} = __MODULE__.Clauses.guard( guards, - %{state | prematch: :raise}, + %{state | prematch: prematch}, %{env_for_expand | context: :guard} ) @@ -2521,7 +2527,11 @@ defmodule ElixirSense.Core.Compiler do {e_args, close_write(sa, s), ea} end + if Version.match?(System.version(), ">= 1.15.0-dev") do @internals [{:behaviour_info, 1}, {:module_info, 1}, {:module_info, 0}] + else + @internals [{:module_info, 1}, {:module_info, 0}] + end defp import_info_callback(module, state) do fn kind -> if Map.has_key?(state.mods_funs_to_positions, {module, nil, nil}) do diff --git a/lib/elixir_sense/core/normalized/macro/env.ex b/lib/elixir_sense/core/normalized/macro/env.ex index 595ac852..211b47c5 100644 --- a/lib/elixir_sense/core/normalized/macro/env.ex +++ b/lib/elixir_sense/core/normalized/macro/env.ex @@ -491,8 +491,14 @@ defmodule ElixirSense.Core.Normalized.Macro.Env do end) end - defp remove_internals(set) do - set -- [{:behaviour_info, 1}, {:module_info, 1}, {:module_info, 0}] + if Version.match?(System.version(), ">= 1.15.0-dev") do + defp remove_internals(set) do + set -- [{:behaviour_info, 1}, {:module_info, 1}, {:module_info, 0}] + end + else + defp remove_internals(set) do + set -- [{:module_info, 1}, {:module_info, 0}] + end end defp ensure_keyword_list([]) do diff --git a/test/elixir_sense/core/compiler_test.exs b/test/elixir_sense/core/compiler_test.exs index e7503970..d67e4a9c 100644 --- a/test/elixir_sense/core/compiler_test.exs +++ b/test/elixir_sense/core/compiler_test.exs @@ -76,26 +76,13 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do end defp state_to_map(%State{} = state) do - res = Map.take(state, [:caller, :prematch, :stacktrace, :unused, :runtime_modules, :vars]) - - if Version.match?(System.version(), "< 1.15.0") do - res |> Map.put(:prematch, :warn) - else - res - end + Map.take(state, [:caller, :prematch, :stacktrace, :unused, :runtime_modules, :vars]) end defp expand(ast) do Compiler.expand( ast, - %State{ - prematch: - if Version.match?(System.version(), ">= 1.15.0-dev") do - Code.get_compiler_option(:on_undefined_variable) - else - :warn - end - }, + state_with_prematch(), Compiler.env() ) end @@ -143,10 +130,21 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do {:ok, %{}} end + defp state_with_prematch do + %State{ + prematch: + if Version.match?(System.version(), ">= 1.15.0-dev") do + Code.get_compiler_option(:on_undefined_variable) + else + :warn + end + } + end + test "initial" do elixir_env = :elixir_env.new() assert Compiler.env() == elixir_env - assert state_to_map(%State{}) == elixir_ex_to_map(:elixir_env.env_to_ex(elixir_env)) + assert state_to_map(state_with_prematch()) == elixir_ex_to_map(:elixir_env.env_to_ex(elixir_env)) end describe "special forms" do @@ -227,7 +225,7 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do test "expands __MODULE__" do ast = {:__MODULE__, [], nil} - {expanded, state, env} = Compiler.expand(ast, %State{}, %{Compiler.env() | module: Foo}) + {expanded, state, env} = Compiler.expand(ast, state_with_prematch(), %{Compiler.env() | module: Foo}) elixir_env = %{:elixir_env.new() | module: Foo} {elixir_expanded, elixir_state, elixir_env} = @@ -242,7 +240,7 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do ast = {:__DIR__, [], nil} {expanded, state, env} = - Compiler.expand(ast, %State{}, %{Compiler.env() | file: __ENV__.file}) + Compiler.expand(ast, state_with_prematch(), %{Compiler.env() | file: __ENV__.file}) elixir_env = %{:elixir_env.new() | file: __ENV__.file} @@ -256,7 +254,7 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do test "expands __CALLER__" do ast = {:__CALLER__, [], nil} - {expanded, state, env} = Compiler.expand(ast, %State{caller: true}, Compiler.env()) + {expanded, state, env} = Compiler.expand(ast, %State{state_with_prematch() | caller: true}, Compiler.env()) elixir_env = :elixir_env.new() {elixir_expanded, elixir_state, elixir_env} = @@ -273,7 +271,7 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do test "expands __STACKTRACE__" do ast = {:__STACKTRACE__, [], nil} - {expanded, state, env} = Compiler.expand(ast, %State{stacktrace: true}, Compiler.env()) + {expanded, state, env} = Compiler.expand(ast, %State{state_with_prematch() | stacktrace: true}, Compiler.env()) elixir_env = :elixir_env.new() {elixir_expanded, elixir_state, elixir_env} = @@ -290,20 +288,27 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do test "expands __ENV__" do ast = {:__ENV__, [], nil} - {expanded, state, env} = Compiler.expand(ast, %State{}, Compiler.env()) + {expanded, state, env} = Compiler.expand(ast, state_with_prematch(), Compiler.env()) elixir_env = :elixir_env.new() {elixir_expanded, elixir_state, elixir_env} = :elixir_expand.expand(ast, :elixir_env.env_to_ex(elixir_env), elixir_env) - assert expanded == elixir_expanded + assert {:%{}, [], expanded_fields} = expanded + assert {:%{}, [], elixir_fields} = elixir_expanded + + assert Enum.sort(expanded_fields) == Enum.sort(elixir_fields) assert env == elixir_env assert state_to_map(state) == elixir_ex_to_map(elixir_state) end test "expands __ENV__.property" do assert_expansion("__ENV__.requires") - assert_expansion("__ENV__.foo") + if Version.match?(System.version(), ">= 1.15.0") do + # elixir 1.14 returns fields in different order + # we don't test that as the code is invalid anyway + assert_expansion("__ENV__.foo") + end end if Version.match?(System.version(), ">= 1.16.0") do @@ -682,7 +687,7 @@ if true or Version.match?(System.version(), ">= 1.17.0-dev") do test "expands nullary call if_undefined: :apply" do ast = {:self, [if_undefined: :apply], nil} - {expanded, state, env} = Compiler.expand(ast, %State{}, Compiler.env()) + {expanded, state, env} = Compiler.expand(ast, state_with_prematch(), Compiler.env()) elixir_env = :elixir_env.new() {elixir_expanded, elixir_state, elixir_env} = diff --git a/test/elixir_sense/core/metadata_builder/error_recovery_test.exs b/test/elixir_sense/core/metadata_builder/error_recovery_test.exs index f68dcf96..4ecc239f 100644 --- a/test/elixir_sense/core/metadata_builder/error_recovery_test.exs +++ b/test/elixir_sense/core/metadata_builder/error_recovery_test.exs @@ -1,3 +1,4 @@ +if Version.match?(System.version(), ">= 1.15.0") do defmodule ElixirSense.Core.MetadataBuilder.ErrorRecoveryTest do use ExUnit.Case, async: true @@ -2831,3 +2832,4 @@ defmodule ElixirSense.Core.MetadataBuilder.ErrorRecoveryTest do assert env.module == nil end end +end diff --git a/test/elixir_sense/core/metadata_builder_test.exs b/test/elixir_sense/core/metadata_builder_test.exs index 3bbf1c4f..ef4f286b 100644 --- a/test/elixir_sense/core/metadata_builder_test.exs +++ b/test/elixir_sense/core/metadata_builder_test.exs @@ -1672,7 +1672,11 @@ defmodule ElixirSense.Core.MetadataBuilderTest do """ |> string_to_state - assert [%VarInfo{type: {:atom, :my_var}}] = state |> get_line_vars(3) + if Version.match?(System.version(), "< 1.15.0") do + assert [%VarInfo{type: {:intersection, [{:atom, :my_var}, {:local_call, :x, []}]}}] = state |> get_line_vars(3) + else + assert [%VarInfo{type: {:atom, :my_var}}] = state |> get_line_vars(3) + end end test "variable binding simple case match context reverse order" do @@ -1685,7 +1689,11 @@ defmodule ElixirSense.Core.MetadataBuilderTest do """ |> string_to_state + if Version.match?(System.version(), "< 1.15.0") do + assert [%VarInfo{type: {:intersection, [{:atom, :my_var}, {:local_call, :x, []}]}}] = state |> get_line_vars(3) + else assert [%VarInfo{type: {:atom, :my_var}}] = state |> get_line_vars(3) + end end test "variable binding simple case match context guard" do @@ -2147,13 +2155,19 @@ defmodule ElixirSense.Core.MetadataBuilderTest do ] = state |> get_line_vars(7) assert [ - %VarInfo{name: :var1, type: nil}, + %VarInfo{name: :var1, type: maybe_local_call}, %VarInfo{name: :var2, type: {:local_call, :now, []}}, %VarInfo{name: :var3, type: {:local_call, :now, [{:atom, :abc}]}}, %VarInfo{name: :var4, type: {:local_call, :now, [{:atom, :abc}]}}, %VarInfo{name: :var5, type: {:local_call, :now, [{:atom, :abc}, {:integer, 5}]}} ] = state |> get_line_vars(16) + if Version.match?(System.version(), "< 1.15.0") do + assert maybe_local_call == {:local_call, :now, []} + else + assert maybe_local_call == nil + end + assert [ %VarInfo{name: :abc, type: nil}, %VarInfo{name: :var1, type: {:call, {:variable, :var1, 0}, :abc, []}}, @@ -7403,7 +7417,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do """ |> string_to_state - if Version.match?(System.version(), ">= 1.15.0") do assert %{ 4 => [ %CallInfo{arity: 1, func: :func, position: {4, 11}, mod: {:attribute, :attr}}, @@ -7413,17 +7426,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do %CallInfo{arity: 1, func: :func, position: {5, 9}, mod: {:variable, :var, 0}} ] } = state.calls - else - assert %{ - 4 => [ - %CallInfo{arity: 1, func: :func, position: {4, 11}, mod: {:attribute, :attr}} - ], - 5 => [ - %CallInfo{arity: 0, func: :var, position: {5, 5}, mod: nil}, - %CallInfo{arity: 1, func: :func, position: {5, 9}, mod: {:variable, :var, 0}} - ] - } = state.calls - end end test "registers calls on attribute and var without args" do @@ -7439,7 +7441,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do """ |> string_to_state - if Version.match?(System.version(), ">= 1.15.0") do Enum.any?( state.calls[4], &match?( @@ -7455,17 +7456,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do &1 ) ) - else - assert %{ - 4 => [ - %CallInfo{arity: 0, func: :func, position: {4, 11}, mod: {:attribute, :attr}} - ], - 5 => [ - %CallInfo{arity: 0, func: :var, position: {5, 5}, mod: nil}, - %CallInfo{arity: 0, func: :func, position: {5, 9}, mod: {:variable, :var, 0}} - ] - } = state.calls - end end test "registers calls on attribute and var anonymous" do @@ -7481,7 +7471,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do """ |> string_to_state - if Version.match?(System.version(), ">= 1.15.0") do assert %{ 4 => [ %CallInfo{arity: 0, func: {:attribute, :attr}, position: {4, 11}, mod: nil}, @@ -7491,17 +7480,6 @@ defmodule ElixirSense.Core.MetadataBuilderTest do %CallInfo{arity: 0, func: {:variable, :var, 0}, position: {5, 9}, mod: nil} ] } = state.calls - else - assert %{ - 4 => [ - %CallInfo{arity: 0, func: {:attribute, :attr}, position: {4, 11}, mod: nil} - ], - 5 => [ - %CallInfo{arity: 0, func: :var, position: {5, 5}, mod: nil}, - %CallInfo{arity: 0, func: {:variable, :var, 0}, position: {5, 9}, mod: nil} - ] - } = state.calls - end end test "registers calls pipe with __MODULE__ operator no parens" do @@ -8107,7 +8085,7 @@ defmodule ElixirSense.Core.MetadataBuilderTest do } } = state.types - if Version.match?(System.version(), ">= 1.14.0") do + if Version.match?(System.version(), ">= 1.15.0") do assert "All the types that implement this protocol" <> _ = doc end end diff --git a/test/elixir_sense/core/parser_test.exs b/test/elixir_sense/core/parser_test.exs index 5381a743..8deb5a03 100644 --- a/test/elixir_sense/core/parser_test.exs +++ b/test/elixir_sense/core/parser_test.exs @@ -113,7 +113,9 @@ defmodule ElixirSense.Core.ParserTest do error: {:error, :parse_error} }, %Env{functions: functions}} = parse(source, {3, 10}) + if Version.match?(System.version(), ">= 1.15.0") do assert Keyword.has_key?(functions, List) + end end test "parse_string with missing terminator \"\'\"" do @@ -128,7 +130,9 @@ defmodule ElixirSense.Core.ParserTest do error: {:error, :parse_error} }, %Env{functions: functions}} = parse(source, {3, 10}) + if Version.match?(System.version(), ">= 1.15.0") do assert Keyword.has_key?(functions, List) + end end test "parse_string with missing heredoc terminator" do @@ -203,11 +207,13 @@ defmodule ElixirSense.Core.ParserTest do {_metadata, env} = parse(source, {3, 23}) + if Version.match?(System.version(), ">= 1.15.0") do assert %Env{ vars: [ %VarInfo{name: :x} ] } = env + end end test "parse_string with missing terminator \"end\" attempts to insert `end` at correct indentation" do @@ -359,10 +365,17 @@ defmodule ElixirSense.Core.ParserTest do vars: vars }} = parse(source, {5, 14}) + if Version.match?(System.version(), "< 1.15.0") do + # container_cursor_to_quoted removes function body + assert [ + %ElixirSense.Core.State.VarInfo{name: :y} + ] = Enum.sort(vars) + else assert [ %ElixirSense.Core.State.VarInfo{name: :x}, %ElixirSense.Core.State.VarInfo{name: :y} ] = Enum.sort(vars) + end end test "parse struct" do