From cbda7bb1653861f003f2ae5daec60a1c595eb319 Mon Sep 17 00:00:00 2001 From: Marlus Saraiva Date: Mon, 28 Oct 2024 14:06:15 -0300 Subject: [PATCH] Normalize compile error accross Elixir versions --- lib/surface/catalogue.ex | 8 +- lib/surface/compile_error.ex | 17 +++- lib/surface/compiler.ex | 1 - lib/surface/compiler/helpers.ex | 2 +- test/surface/api_test.exs | 29 ++++--- test/surface/catalogue/live_example_test.exs | 8 +- test/surface/catalogue/playground_test.exs | 6 +- test/surface/compiler/parser_test.exs | 12 +-- test/surface/compiler_test.exs | 2 +- test/surface/component_test.exs | 2 +- test/surface/components/context_test.exs | 56 ++++++------- test/surface/constructs/case_test.exs | 4 +- test/surface/constructs/for_test.exs | 4 +- test/surface/constructs/if_test.exs | 6 +- test/surface/integrations/directives_test.exs | 24 +++--- test/surface/integrations/properties_test.exs | 18 +++-- test/surface/integrations/slot_test.exs | 78 +++++++++---------- test/surface/integrations/transform_test.exs | 2 +- test/surface/macro_component_test.exs | 12 ++- test/surface_test.exs | 14 ++-- 20 files changed, 157 insertions(+), 148 deletions(-) diff --git a/lib/surface/catalogue.ex b/lib/surface/catalogue.ex index 8eee9332..126ea17a 100644 --- a/lib/surface/catalogue.ex +++ b/lib/surface/catalogue.ex @@ -104,15 +104,15 @@ defmodule Surface.Catalogue do subject _ -> - message = """ - no subject defined for #{inspect(type)} + message = "no subject defined for #{inspect(type)}" - Hint: You can define the subject using the :subject option. Example: + hint = """ + you can define the subject using the :subject option. Example: use #{inspect(type)}, subject: MyApp.MyButton """ - Surface.IOHelper.compile_error(message, caller.file, caller.line) + Surface.IOHelper.compile_error(message, hint, caller.file, caller.line) end end diff --git a/lib/surface/compile_error.ex b/lib/surface/compile_error.ex index 94f4f652..7d359b2c 100644 --- a/lib/surface/compile_error.ex +++ b/lib/surface/compile_error.ex @@ -36,7 +36,8 @@ defmodule Surface.CompileError do lineCode = String.trim_trailing(lineCode) :elixir_errors.format_snippet(:error, {line, column}, file, description, lineCode, %{}) else - description + prefix = IO.ANSI.format([:red, "error:"]) + "#{prefix} #{description}" end hint = @@ -47,12 +48,22 @@ defmodule Surface.CompileError do end location = Exception.format_file_line_column(Path.relative_to_cwd(file), line, column) - location <> " " <> message <> hint + location <> "\n" <> message <> hint end else defp format_message(file, line, column, description, hint) do location = Exception.format_file_line_column(Path.relative_to_cwd(file), line, column) - location <> " " <> description <> (hint || "") + + hint = + if hint do + prefix = IO.ANSI.format([:blue, "hint:"]) + "\n\n#{prefix} " <> hint + else + "" + end + + prefix = IO.ANSI.format([:red, "error:"]) + location <> "\n#{prefix} " <> description <> hint end end end diff --git a/lib/surface/compiler.ex b/lib/surface/compiler.ex index 162e43c3..524c3b85 100644 --- a/lib/surface/compiler.ex +++ b/lib/surface/compiler.ex @@ -288,7 +288,6 @@ defmodule Surface.Compiler do %AST.Error{message: message, meta: meta} {:error, {message, details, line, column}, meta} -> - details = if details, do: "\n\n" <> details, else: "" # TODO: turn it back as a warning when using @after_verify in Elixir >= 0.14. # Make sure to check if the genarated `require .__info__()` doesn't get called, # raising Elixir's CompileError. diff --git a/lib/surface/compiler/helpers.ex b/lib/surface/compiler/helpers.ex index 6a53922e..7b6c1c39 100644 --- a/lib/surface/compiler/helpers.ex +++ b/lib/surface/compiler/helpers.ex @@ -291,7 +291,7 @@ defmodule Surface.Compiler.Helpers do defp hint_for_unloaded_module(node_alias) do """ - Hint: make sure module `#{node_alias}` can be successfully compiled. + make sure module `#{node_alias}` can be successfully compiled. If the module is namespaced, you can use its full name. For instance: diff --git a/test/surface/api_test.exs b/test/surface/api_test.exs index e6a0e2bb..9e27e6c7 100644 --- a/test/surface/api_test.exs +++ b/test/surface/api_test.exs @@ -146,17 +146,17 @@ defmodule Surface.APITest do # invalid value code = "prop field, :string, css_variant: 123" - message = """ - code:4: invalid value for :css_variant. Expected either a boolean or a keyword list of options, got: 123. + message = ~r""" + code:4:\n.+?error:.+? invalid value for :css_variant\. Expected either a boolean or a keyword list of options, got: 123\. Valid options for type :string are: - * :not_nil - the name of the variant when the value is not `nil`. Default is the assign name. - * :nil - the name of the variant when the value is `nil`. Default is `no-[assign-name]`. + \* :not_nil - the name of the variant when the value is not `nil`\. Default is the assign name\. + \* :nil - the name of the variant when the value is `nil`\. Default is `no-\[assign-name\]`\. or, if you use the `values` or `values!` options: - * :prefix - the prefix of the variant name for each value listed in `values` or `values!`. Default is `[assign-name]-`. + \* :prefix - the prefix of the variant name for each value listed in `values` or `values!`. Default is `\[assign-name\]-`\. """ assert_raise(Surface.CompileError, message, fn -> eval(code) end) @@ -445,11 +445,11 @@ defmodule Surface.APITest do end """ - message = """ - code.exs:7: cannot use property `unknown` as generator for slot. \ + message = ~r""" + code.exs:7:\n.+?error:.+? cannot use property `unknown` as generator for slot\. \ Expected an existing property of type `:generator`, got: an undefined property `unknown`. - Hint: Available generators are [:items]\ + Hint: Available generators are \[:items\]\ """ assert_raise(Surface.CompileError, message, fn -> @@ -473,11 +473,11 @@ defmodule Surface.APITest do end """ - message = """ - code.exs:6: cannot use property `label` as generator for slot. \ + message = ~r""" + code.exs:6:\n.+?error:.+? cannot use property `label` as generator for slot\. \ Expected a property of type :generator, got: a property of type :string - Hint: Available generators are []\ + Hint: Available generators are \[\]\ """ assert_raise(Surface.CompileError, message, fn -> @@ -804,9 +804,7 @@ defmodule Surface.APISyncTest do assert {%Surface.CompileError{ description: "cannot render (module NonExisting could not be loaded)", hint: """ - - - Hint: make sure module `NonExisting` can be successfully compiled. + make sure module `NonExisting` can be successfully compiled. If the module is namespaced, you can use its full name. For instance: @@ -843,7 +841,8 @@ defmodule Surface.APISyncTest do end """ - error_message = ~r"code.exs:7(:8)?: cannot render \(module NonExisting could not be loaded\)" + error_message = + ~r"code.exs:7(:8)?:\n.+?error:.+? cannot render \(module NonExisting could not be loaded\)" assert_raise(Surface.CompileError, error_message, fn -> {{:module, _, _, _}, _} = diff --git a/test/surface/catalogue/live_example_test.exs b/test/surface/catalogue/live_example_test.exs index df0061ef..e1b65270 100644 --- a/test/surface/catalogue/live_example_test.exs +++ b/test/surface/catalogue/live_example_test.exs @@ -35,12 +35,12 @@ defmodule Surface.Catalogue.LiveExampleTest do end """ - message = """ - code.exs:2: no subject defined for Surface.Catalogue.LiveExample + message = ~r""" + code\.exs:2:\n.+?error:.+? no subject defined for Surface\.Catalogue\.LiveExample - Hint: You can define the subject using the :subject option. Example: + .+?hint:.+? you can define the subject using the :subject option\. Example: - use Surface.Catalogue.LiveExample, subject: MyApp.MyButton + use Surface\.Catalogue\.LiveExample, subject: MyApp.MyButton """ assert_raise Surface.CompileError, message, fn -> diff --git a/test/surface/catalogue/playground_test.exs b/test/surface/catalogue/playground_test.exs index 2c3ec7dd..43f66d67 100644 --- a/test/surface/catalogue/playground_test.exs +++ b/test/surface/catalogue/playground_test.exs @@ -28,10 +28,10 @@ defmodule Surface.Catalogue.PlaygroundTest do end """ - message = """ - code.exs:2: no subject defined for Surface.Catalogue.Playground + message = ~r""" + code.exs:2:\n.+?error:.+? no subject defined for Surface.Catalogue.Playground - Hint: You can define the subject using the :subject option. Example: + .+?hint:.+?you can define the subject using the :subject option. Example: use Surface.Catalogue.Playground, subject: MyApp.MyButton """ diff --git a/test/surface/compiler/parser_test.exs b/test/surface/compiler/parser_test.exs index 7ee7bbb0..8d1153c9 100644 --- a/test/surface/compiler/parser_test.exs +++ b/test/surface/compiler/parser_test.exs @@ -742,8 +742,8 @@ defmodule Surface.Compiler.ParserTest do /> """ - message = """ - nofile:2: invalid value for tagged expression `{=1}`. The expression must be either an assign or a variable. + message = ~r""" + nofile:2:\n.+?error:.+? invalid value for tagged expression `{=1}`. The expression must be either an assign or a variable. Examples: `
` or `
` """ @@ -758,8 +758,8 @@ defmodule Surface.Compiler.ParserTest do /> """ - message = """ - nofile:2: cannot assign `{=@class}` to attribute `class`. \ + message = ~r""" + nofile:2:\n.+?error:.+? cannot assign `{=@class}` to attribute `class`. \ The tagged expression `{= }` can only be used on a root attribute/property. Example:
@@ -995,7 +995,7 @@ defmodule Surface.Compiler.ParserTest do {/if} """ - message = "nofile:2: missing expression for block {#if ...}" + message = ~r"nofile:2:\n.+?error:.+? missing expression for block {#if ...}" assert_raise Surface.CompileError, message, fn -> parse!(code) end @@ -1006,7 +1006,7 @@ defmodule Surface.Compiler.ParserTest do {/case} """ - message = "nofile:2: missing expression for block {#case ...}" + message = ~r"nofile:2:\n.+?error:.+? missing expression for block {#case ...}" assert_raise Surface.CompileError, message, fn -> parse!(code) end end diff --git a/test/surface/compiler_test.exs b/test/surface/compiler_test.exs index 6983d2f2..8228bd36 100644 --- a/test/surface/compiler_test.exs +++ b/test/surface/compiler_test.exs @@ -1021,7 +1021,7 @@ defmodule Surface.CompilerSyncTest do assert_raise( Surface.CompileError, - ~r/nofile:2(:4)?: cannot render \(module But could not be loaded\)/, + ~r/nofile:2(:4)?:\n.+?error:.+? cannot render \(module But could not be loaded\)/, fn -> Surface.Compiler.compile(code, 1, __ENV__) end diff --git a/test/surface/component_test.exs b/test/surface/component_test.exs index 8cbd29b9..46f734e5 100644 --- a/test/surface/component_test.exs +++ b/test/surface/component_test.exs @@ -208,7 +208,7 @@ defmodule Surface.ComponentTest do end """ - message = "code.exs:2: invalid value for option :slot. Expected a string, got: {1, 2}" + message = ~r"code.exs:2:\n.+?error:.+? invalid value for option :slot. Expected a string, got: {1, 2}" assert_raise(Surface.CompileError, message, fn -> {{:module, _, _, _}, _} = Code.eval_string(code, [], %{__ENV__ | file: "code.exs", line: 1}) diff --git a/test/surface/components/context_test.exs b/test/surface/components/context_test.exs index 8209b200..73620f4f 100644 --- a/test/surface/components/context_test.exs +++ b/test/surface/components/context_test.exs @@ -931,11 +931,11 @@ defmodule Surface.Components.ContextTest do """ end - message = """ - code:2: invalid value for property "get". expected a scope \ - module (optional) along with a keyword list of bindings, \ + message = ~r""" + code:2:\n.+?error:.+? invalid value for property "get". expected a scope \ + module \(optional\) along with a keyword list of bindings, \ e.g. {Form, form: form} or {field: my_field}, \ - got: {ContextTest.Outer, field: [field]}.\ + got: {ContextTest.Outer, field: \[field\]}.\ """ assert_raise(Surface.CompileError, message, fn -> @@ -954,7 +954,7 @@ defmodule Surface.Components.ContextTest do """ end - assert_raise(Surface.CompileError, ~r/code:2: invalid value for property "get"/, fn -> + assert_raise(Surface.CompileError, ~r/code:2:\n.+?error:.+? invalid value for property "get"/, fn -> compile_surface(code) end) end @@ -970,7 +970,7 @@ defmodule Surface.Components.ContextTest do """ end - assert_raise(Surface.CompileError, ~r/code:2: invalid value for property "get"/, fn -> + assert_raise(Surface.CompileError, ~r/code:2:\n.+?error:.+? invalid value for property "get"/, fn -> compile_surface(code) end) end @@ -988,9 +988,9 @@ defmodule Surface.Components.ContextTest do """ end - message = """ - code:2: invalid value for property "put". expected a scope \ - module (optional) along with a keyword list of values, \ + message = ~r""" + code:2:\n.+?error:.+? invalid value for property "put". expected a scope \ + module \(optional\) along with a keyword list of values, \ e.g. {MyModule, field: @value, other: "other"} or {field: @value}, \ got: {ContextTest.Outer, 123}.\ """ @@ -1011,7 +1011,7 @@ defmodule Surface.Components.ContextTest do """ end - assert_raise(Surface.CompileError, ~r/code:2: invalid value for property "put"/, fn -> + assert_raise(Surface.CompileError, ~r/code:2:\n.+?error:.+? invalid value for property "put"/, fn -> compile_surface(code) end) end @@ -1027,7 +1027,7 @@ defmodule Surface.Components.ContextTest do """ end - assert_raise(Surface.CompileError, ~r/code:2: invalid value for property "put"/, fn -> + assert_raise(Surface.CompileError, ~r/code:2:\n.+?error:.+? invalid value for property "put"/, fn -> compile_surface(code) end) end @@ -1177,8 +1177,8 @@ defmodule Surface.Components.ContextTest do end """ - message = """ - code.exs:7: components propagating context values through slots must be configured \ + message = ~r""" + code.exs:7:\n.+?error:.+? components propagating context values through slots must be configured \ as `propagate_context_to_slots: true`. In case you don't want to propagate any value, you need to explicitly \ @@ -1186,10 +1186,10 @@ defmodule Surface.Components.ContextTest do # Example - config :surface, :components, [ + config :surface, :components, \[ {Surface.Components.ContextTest.WarnOnSlotPropContextPut, propagate_context_to_slots: true}, ... - ] + \] This warning is emitted whenever a <#slot ...> uses the `context_put` prop or \ it's placed inside a parent component that propagates context values through its slots. @@ -1217,8 +1217,8 @@ defmodule Surface.Components.ContextTest do end """ - message = """ - code.exs:9: components propagating context values through slots must be configured \ + message = ~r""" + code.exs:9:\n.+?error:.+? components propagating context values through slots must be configured \ as `propagate_context_to_slots: true`. In case you don't want to propagate any value, you need to explicitly \ @@ -1226,17 +1226,17 @@ defmodule Surface.Components.ContextTest do # Example - config :surface, :components, [ + config :surface, :components, \[ {Surface.Components.ContextTest.WarnOnContextPut, propagate_context_to_slots: true}, ... - ] + \] This warning is emitted whenever a <#slot ...> uses the `context_put` prop or \ it's placed inside a parent component that propagates context values through its slots. Current parent components propagating context values: - * `Surface.Components.Context` at line 8 + \* `Surface.Components.Context` at line 8 """ assert_raise(Surface.CompileError, message, fn -> @@ -1263,27 +1263,27 @@ defmodule Surface.Components.ContextTest do end """ - message = """ - code.exs:10: components propagating context values through slots must be configured \ - as `propagate_context_to_slots: true`. + message = ~r""" + code.exs:10:\n.+?error:.+? components propagating context values through slots must be configured \ + as `propagate_context_to_slots: true`\. In case you don't want to propagate any value, you need to explicitly \ - set `propagate_context_to_slots` to `false`. + set `propagate_context_to_slots` to `false`\. # Example - config :surface, :components, [ + config :surface, :components, \[ {Surface.Components.ContextTest.WarnOnSlotInsideComponentPropagating, propagate_context_to_slots: true}, ... - ] + \] This warning is emitted whenever a <#slot ...> uses the `context_put` prop or \ it's placed inside a parent component that propagates context values through its slots. Current parent components propagating context values: - * `Surface.Components.ContextTest.Outer` at line 8 - * `Surface.Components.ContextTest.OuterUsingPropContextPut` at line 9 + \* `Surface.Components.ContextTest.Outer` at line 8 + \* `Surface.Components.ContextTest.OuterUsingPropContextPut` at line 9 """ assert_raise(Surface.CompileError, message, fn -> diff --git a/test/surface/constructs/case_test.exs b/test/surface/constructs/case_test.exs index 67ab7220..39bca007 100644 --- a/test/surface/constructs/case_test.exs +++ b/test/surface/constructs/case_test.exs @@ -79,7 +79,7 @@ defmodule Surface.Constructs.CaseTest do """ end - message = ~S(code:2: cannot have content between {#case ...} and {#match ...}) + message = ~r/code:2:\n.+?error:.+? cannot have content between {#case ...} and {#match ...}/ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -98,7 +98,7 @@ defmodule Surface.Constructs.CaseTest do end message = - ~S(code:2: no {#match} sub-block defined. A {#case} block must include at least one {#match ...} sub-block.) + ~r/code:2:\n.+?error:.+? no {#match} sub-block defined. A {#case} block must include at least one {#match ...} sub-block./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) diff --git a/test/surface/constructs/for_test.exs b/test/surface/constructs/for_test.exs index d75022d0..e4f1eb9e 100644 --- a/test/surface/constructs/for_test.exs +++ b/test/surface/constructs/for_test.exs @@ -111,7 +111,7 @@ defmodule Surface.Constructs.ForTest do """ end - message = ~S(code:3: invalid value for property "prop". Expected a :list, got: "some string".) + message = ~r/code:3:\n.+?error:.+? invalid value for property "prop". Expected a :list, got: "some string"./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -207,7 +207,7 @@ defmodule Surface.Constructs.ForTest do end message = - ~r/code:3: using `{#else}` is only supported when the expression in `{#for}` has a single generator and no filters./ + ~r/code:3:\n.+?error:.+? using `{#else}` is only supported when the expression in `{#for}` has a single generator and no filters./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code, assigns) diff --git a/test/surface/constructs/if_test.exs b/test/surface/constructs/if_test.exs index 7c36f819..a7fed5bd 100644 --- a/test/surface/constructs/if_test.exs +++ b/test/surface/constructs/if_test.exs @@ -86,7 +86,7 @@ defmodule Surface.Constructs.IfTest do """ end - message = ~S(code:2: invalid value for property "prop". Expected a :list, got: "some string".) + message = ~r/code:2:\n.+?error:.+? invalid value for property "prop". Expected a :list, got: "some string"./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -311,7 +311,7 @@ defmodule Surface.Constructs.IfTest do """ end - message = ~S(code:12: invalid value for property "prop". Expected a :list, got: "some string".) + message = ~r/code:12:\n.+?error:.+? invalid value for property "prop". Expected a :list, got: "some string"./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -396,7 +396,7 @@ defmodule Surface.Constructs.IfTest do """ end - message = ~S(code:2: invalid value for property "prop". Expected a :list, got: "some string".) + message = ~r/code:2:\n.+?error:.+? invalid value for property "prop". Expected a :list, got: "some string"./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) diff --git a/test/surface/integrations/directives_test.exs b/test/surface/integrations/directives_test.exs index bdfc7103..7e70dacc 100644 --- a/test/surface/integrations/directives_test.exs +++ b/test/surface/integrations/directives_test.exs @@ -186,11 +186,11 @@ defmodule Surface.DirectivesTest do """ end - message = """ - code:3: cannot assign `{...@props}` to attribute `class`. \ - The tagged expression `{... }` can only be used on a root attribute/property. + message = ~r""" + code:3:\n.+?error:.+? cannot assign `{\.\.\.@props}` to attribute `class`\. \ + The tagged expression `{\.\.\. }` can only be used on a root attribute/property\. - Example:
+ Example:
""" assert_raise(Surface.CompileError, message, fn -> @@ -315,11 +315,11 @@ defmodule Surface.DirectivesTest do """ end - message = """ - code:3: cannot assign `{...@attrs}` to attribute `class`. \ - The tagged expression `{... }` can only be used on a root attribute/property. + message = ~r""" + code:3:\n.+?error:.+? cannot assign `{\.\.\.@attrs}` to attribute `class`\. \ + The tagged expression `{\.\.\. }` can only be used on a root attribute/property\. - Example:
+ Example:
""" assert_raise(Surface.CompileError, message, fn -> @@ -385,8 +385,8 @@ defmodule Surface.DirectivesTest do """ end - message = """ - code:2: unknown modifier "unknown" for directive :for\ + message = ~r""" + code:2:\n.+?error:.+? unknown modifier "unknown" for directive :for\ """ assert_raise(Surface.CompileError, message, fn -> @@ -407,8 +407,8 @@ defmodule Surface.DirectivesTest do """ end - message = """ - code:2: cannot apply modifier "with_index" on generators with multiple clauses\ + message = ~r""" + code:2:\n.+?error:.+? cannot apply modifier "with_index" on generators with multiple clauses\ """ assert_raise(Surface.CompileError, message, fn -> diff --git a/test/surface/integrations/properties_test.exs b/test/surface/integrations/properties_test.exs index 74f13e87..93998638 100644 --- a/test/surface/integrations/properties_test.exs +++ b/test/surface/integrations/properties_test.exs @@ -195,7 +195,7 @@ defmodule Surface.PropertiesTest do """ end - message = ~S(code:1: invalid value for property "as". Expected a :atom, got: "some string".) + message = ~r/code:1:\n.+?error:.+? invalid value for property "as"\. Expected a :atom, got: "some string"\./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -300,7 +300,8 @@ defmodule Surface.PropertiesTest do """ end - message = ~S(code:1: invalid value for property "prop". Expected a :keyword, got: "some string".) + message = + ~r/code:1:\n.+?error:.+? invalid value for property "prop"\. Expected a :keyword, got: "some string"\./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -446,7 +447,7 @@ defmodule Surface.PropertiesTest do """ end - message = ~S(code:1: invalid value for property "prop". Expected a :map, got: "some string".) + message = ~r/code:1:\n.+?error:.+? invalid value for property "prop"\. Expected a :map, got: "some string"\./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -529,7 +530,7 @@ defmodule Surface.PropertiesTest do """ end - message = ~S(code:1: invalid value for property "prop". Expected a :list, got: {1, 2}.) + message = ~r/code:1:\n.+?error:.+? invalid value for property "prop"\. Expected a :list, got: {1, 2}\./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -598,7 +599,8 @@ defmodule Surface.PropertiesTest do """ end - message = ~S(code:1: invalid value for property "prop". Expected a :list, got: "some string".) + message = + ~r/code:1:\n.+?error:.+? invalid value for property "prop"\. Expected a :list, got: "some string"\./ assert_raise(Surface.CompileError, message, fn -> compile_surface(code) @@ -848,8 +850,8 @@ defmodule Surface.PropertiesTest do """ end - message = """ - code:2: invalid value for property "labels". Expected a :generator Example: `{i <- ...}`, got: {"label"}.\ + message = ~r""" + code:2:\n.+?error:.+? invalid value for property "labels"\. Expected a :generator Example: `{i <- \.\.\.}`, got: {"label"}\.\ """ assert_raise(Surface.CompileError, message, fn -> @@ -1005,7 +1007,7 @@ defmodule Surface.PropertiesSyncTest do end """ - message = "code.exs:11: `generator_value` is missing for slot `default`" + message = ~r"code.exs:11:\n.+?error:.+? `generator_value` is missing for slot `default`" assert_raise(Surface.CompileError, message, fn -> {{:module, _, _, _}, _} = Code.eval_string(code, [], %{__ENV__ | file: "code.exs", line: 1}) diff --git a/test/surface/integrations/slot_test.exs b/test/surface/integrations/slot_test.exs index 4d58ac8e..10f8a44a 100644 --- a/test/surface/integrations/slot_test.exs +++ b/test/surface/integrations/slot_test.exs @@ -781,8 +781,8 @@ defmodule Surface.SlotTest do """ end - message = """ - code:2: cannot use :let to redefine variable from the component's generator. + message = ~r""" + code:2:\n.+?error:.+? cannot use :let to redefine variable from the component's generator\. variables `i` and `j` already defined in `{i, j} <- @items` at code:1 @@ -1001,10 +1001,10 @@ defmodule Surface.SlotTest do """ end - message = """ - code:3: invalid value for directive :let. \ + message = ~r""" + code:3:\n.+?error:.+? invalid value for directive :let\. \ Expected a pattern to be matched by the slot argument, \ - got: {"a_string", "other_string"}.\ + got: {"a_string", "other_string"}\.\ """ assert_raise(Surface.CompileError, message, fn -> @@ -1022,8 +1022,8 @@ defmodule Surface.SlotTest do """ end - message = """ - code:1: no slot "default" defined in parent component + message = ~r""" + code:1:\n.+?error:.+? no slot "default" defined in parent component """ assert_raise(Surface.CompileError, message, fn -> @@ -1043,10 +1043,10 @@ defmodule Surface.SlotTest do """ end - message = """ - code:2: invalid value for directive :let. \ + message = ~r""" + code:2:\n.+?error:.+? invalid value for directive :let\. \ Expected a pattern to be matched by the slot argument, \ - got: {a, info: [my_info]}.\ + got: {a, info: \[my_info\]}\.\ """ assert_raise(Surface.CompileError, message, fn -> @@ -1063,10 +1063,10 @@ defmodule Surface.SlotTest do """ end - message = """ - code:2: invalid value for attribute "root". \ + message = ~r""" + code:2:\n.+?error:.+? invalid value for attribute "root"\. \ Expected the slot and a single expression to be given as the slot argument, \ - got: {@default, a, b}.\ + got: {@default, a, b}\.\ """ assert_raise(Surface.CompileError, message, fn -> @@ -1083,10 +1083,10 @@ defmodule Surface.SlotTest do """ end - message = """ - code:2: invalid value for attribute "root". \ + message = ~r""" + code:2:\n.+?error:.+? invalid value for attribute "root"\. \ Expected the slot and a single expression to be given as the slot argument, \ - got: {@default, a, info: "Info from slot"}.\ + got: {@default, a, info: "Info from slot"}\.\ """ assert_raise(Surface.CompileError, message, fn -> @@ -1248,12 +1248,12 @@ defmodule Surface.SlotSyncTest do """ end - message = """ - code:2: The slotable component has the `:slot` option set to `inner`. + message = ~r""" + code:2:\n.+?error:.+? The slotable component has the `:slot` option set to `inner`\. - That slot name is not declared in parent component . + That slot name is not declared in parent component \. - Please declare the slot in the parent component or rename the value in the `:slot` option. + Please declare the slot in the parent component or rename the value in the `:slot` option\. """ assert_raise(Surface.CompileError, message, fn -> @@ -1272,12 +1272,12 @@ defmodule Surface.SlotSyncTest do """ end - message = """ - code:2: The slotable component has the `:slot` option set to `inner`. + message = ~r""" + code:2:\n.+?error:.+? The slotable component has the `:slot` option set to `inner`\. - That slot name is not declared in parent component . + That slot name is not declared in parent component \. - Please declare the slot in the parent component or rename the value in the `:slot` option. + Please declare the slot in the parent component or rename the value in the `:slot` option\. Available slot: "col" """ @@ -1301,10 +1301,10 @@ defmodule Surface.SlotSyncTest do """ end - message = """ - code:4: no slot "foot" defined in parent component + message = ~r""" + code:4:\n.+?error:.+? no slot "foot" defined in parent component - Did you mean "footer"? + Did you mean "footer"\? Available slots: "default", "header" and "footer" """ @@ -1335,11 +1335,11 @@ defmodule Surface.SlotSyncTest do """ message = ~r""" - code:12: no slot `footer` defined in the component `Surface.SlotSyncTest.TestComponentWithoutDeclaringSlots` + code:12:\n.+?error:.+? no slot `footer` defined in the component `Surface.SlotSyncTest.TestComponentWithoutDeclaringSlots` Available slots: "default" and "header"\ - Hint: You can define slots using the `slot` macro.\ + Hint: You can define slots using the `slot` macro\.\ For instance: `slot footer`\ """ @@ -1367,9 +1367,9 @@ defmodule Surface.SlotSyncTest do """ message = ~r""" - code:7: no slot `default` defined in the component `Surface.SlotSyncTest.TestComponentWithShortSyntaxButWithoutDeclaringDefaultSlot` + code:7:\n.+?error:.+? no slot `default` defined in the component `Surface.SlotSyncTest.TestComponentWithShortSyntaxButWithoutDeclaringDefaultSlot` - Please declare the default slot using `slot default` in order to use the `<#slot />` notation. + Please declare the default slot using `slot default` in order to use the `<#slot />` notation\. """ assert_raise(Surface.CompileError, message, fn -> @@ -1469,8 +1469,8 @@ defmodule Surface.SlotSyncTest do """ end - message = """ - code:1: no slot "default" defined in parent component + message = ~r""" + code:1:\n.+?error:.+? no slot "default" defined in parent component """ assert_raise(Surface.CompileError, message, fn -> @@ -1534,9 +1534,9 @@ defmodule Surface.SlotSyncTest do """ message = ~r""" - code:10: invalid directive `:attrs` for <#slot>. + code:10:\n.+?error:.+? invalid directive `:attrs` for <#slot>\. - Slots only accept the root prop, `generator_value`, `:if` and `:for`. + Slots only accept the root prop, `generator_value`, `:if` and `:for`\. """ assert_raise(Surface.CompileError, message, fn -> @@ -1565,9 +1565,9 @@ defmodule Surface.SlotSyncTest do """ message = ~r""" - code:11: invalid attribute `let` for <#slot>. + code:11:\n.+?error:.+? invalid attribute `let` for <#slot>\. - Slots only accept the root prop, `generator_value`, `:if` and `:for`. + Slots only accept the root prop, `generator_value`, `:if` and `:for`\. """ assert_raise(Surface.CompileError, message, fn -> @@ -1595,7 +1595,7 @@ defmodule Surface.SlotSyncTest do """ message = ~r""" - code:10: cannot pass dynamic attributes to <#slot>. + code:10:\n.+?error:.+? cannot pass dynamic attributes to <#slot>. Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:if` and `:for`. """ @@ -1625,7 +1625,7 @@ defmodule Surface.SlotSyncTest do """ message = ~r""" - code:10: cannot pass dynamic attributes to <#slot>. + code:10:\n.+?error:.+? cannot pass dynamic attributes to <#slot>. Slots only accept the root prop, `for`, `name`, `index`, `generator_value`, `:if` and `:for`. """ diff --git a/test/surface/integrations/transform_test.exs b/test/surface/integrations/transform_test.exs index fb307bef..6150f2f0 100644 --- a/test/surface/integrations/transform_test.exs +++ b/test/surface/integrations/transform_test.exs @@ -186,7 +186,7 @@ defmodule Surface.TransformTest do assert_raise( Surface.CompileError, - "nofile:1: invalid value for property \"prop\". Expected a :list, got: \"string\".", + ~r"nofile:1:\n.+?error:.+? invalid value for property \"prop\"\. Expected a :list, got: \"string\".", fn -> Surface.Compiler.compile(code, 1, __ENV__) end diff --git a/test/surface/macro_component_test.exs b/test/surface/macro_component_test.exs index 03bc4440..22a37001 100644 --- a/test/surface/macro_component_test.exs +++ b/test/surface/macro_component_test.exs @@ -201,14 +201,14 @@ defmodule Surface.MacroComponentTest do """ end - message = """ - code:2: invalid value for property "align" + message = ~r""" + code:2:\n.+?error:.+? invalid value for property "align" Expected a string while evaluating {@align}, got: nil Hint: static properties of macro components can only accept static values like module attributes, literals or compile-time expressions. Runtime variables and expressions, including component - assigns, cannot be evaluated as they are not available during compilation. + assigns, cannot be evaluated as they are not available during compilation\. """ assert_raise(Surface.CompileError, message, fn -> @@ -255,9 +255,7 @@ defmodule Surface.MacroComponentTest do assert {%Surface.CompileError{ description: "cannot render <#NonExisting> (module NonExisting could not be loaded)", hint: """ - - - Hint: make sure module `NonExisting` can be successfully compiled. + make sure module `NonExisting` can be successfully compiled. If the module is namespaced, you can use its full name. For instance: @@ -284,7 +282,7 @@ defmodule Surface.MacroComponentTest do assert_raise( Surface.CompileError, - ~r/code:1(:2)?: cannot render \<#NonExisting\> \(module NonExisting could not be loaded\)/, + ~r/code:1(:2)?:\n.+?error:.+? cannot render \<#NonExisting\> \(module NonExisting could not be loaded\)/, fn -> compile_surface(code) end diff --git a/test/surface_test.exs b/test/surface_test.exs index 1ec5a1e4..bcb9959f 100644 --- a/test/surface_test.exs +++ b/test/surface_test.exs @@ -63,8 +63,8 @@ defmodule SurfaceTest do end test "raise error when trying to unquote an undefined variable" do - message = """ - code.ex:2: undefined variable "content". + message = ~r""" + code.ex:2:\n.+?error:.+? undefined variable "content"\. Available variable: "message" """ @@ -81,10 +81,10 @@ defmodule SurfaceTest do end test "raise error when trying to unquote expressions that are not variables" do - message = """ - code.ex:2: cannot unquote `to_string(:abc)`. + message = ~r""" + code.ex:2:\n.+?error:.+? cannot unquote `to_string\(:abc\)`\. - The expression to be unquoted must be written as `^var`, where `var` is an existing variable. + The expression to be unquoted must be written as `\^var`, where `var` is an existing variable\. """ assert_raise(Surface.CompileError, message, fn -> @@ -109,7 +109,7 @@ defmodule SurfaceTest do end """ - message = "code.exs:1: the code to be quoted must be wrapped in a `~F` sigil." + message = ~r"code.exs:1:\n.+?error:.+? the code to be quoted must be wrapped in a `~F` sigil\." assert_raise(Surface.CompileError, message, fn -> {{:module, _, _, _}, _} = Code.eval_string(code, [], %{__ENV__ | file: "code.exs", line: 1}) @@ -117,7 +117,7 @@ defmodule SurfaceTest do end test "raise error when using {^...} outside `quote_surface`" do - message = "code:2: cannot use tagged expression {^var} outside `quote_surface`" + message = ~r"code:2:\n.+?error:.+? cannot use tagged expression \{\^var\} outside `quote_surface`" code = quote do