Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't Crash on Map Update #22

Merged
merged 5 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/channel_spec/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ defmodule ChannelSpec.Schema do
refs ->
schema = ref.schema()
refs = Map.put(refs, ref, schema)
refs = Map.update!(refs, :__unresolved_refs, &(&1 -- [ref]))
refs = Map.update(refs, :__unresolved_refs, [], &(&1 -- [ref]))

{schema, refs} = compile_refs(schema, refs, [])

Expand Down
157 changes: 157 additions & 0 deletions test/channel_spec/socket_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use ChannelSpec.Operations
end

defmodule :"#{mod}" do

Check warning on line 22 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test3715)

Check warning on line 22 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test1252)
use ChannelSpec.Socket

channel("foo", __MODULE__.MyChannel)
Expand All @@ -36,7 +36,7 @@
use ChannelSpec.Operations
end

defmodule :"#{mod}" do

Check warning on line 39 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test2627)

Check warning on line 39 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test1570)
use ChannelSpec.Socket

channel("foo", __MODULE__.MyChannel, assigns: [foo: "bar"])
Expand Down Expand Up @@ -82,7 +82,7 @@
use ChannelSpec.Operations
end

defmodule :"#{mod}" do

Check warning on line 85 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test1093)
use ChannelSpec.Socket

channel("foo", __MODULE__.MyChannel)
Expand All @@ -107,7 +107,7 @@
use ChannelSpec.Operations
end

defmodule :"#{mod}" do

Check warning on line 110 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test1317)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -135,7 +135,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 138 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test258)

Check warning on line 138 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test4803)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -239,7 +239,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 242 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 24.3)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test548)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -285,7 +285,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 288 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test2884)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -323,7 +323,7 @@
handle "bar", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 326 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 24.3)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test5187)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -367,7 +367,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 370 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 24.3)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test3940)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -408,7 +408,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 411 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 24.3)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test3043)

Check warning on line 411 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test1539)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -453,7 +453,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 456 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test2532)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -504,7 +504,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 507 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test611)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand Down Expand Up @@ -587,7 +587,7 @@
handle "foo", fn _params, _context, socket -> {:noreply, socket} end
end

defmodule :"#{mod}" do

Check warning on line 590 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 24.3)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test3460)

Check warning on line 590 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 25.0.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test5379)

Check warning on line 590 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.14.3, 25.2)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test484)
use ChannelSpec.Socket

channel "foo", __MODULE__.MyChannel
Expand All @@ -595,5 +595,162 @@

refute File.exists?(Path.join(tmp_dir, "schema.json"))
end

@tag :tmp_dir
test "schemas nested in a single module with references work", %{
mod: mod,
tmp_dir: tmp_dir
} do
defmodule :"#{mod}.LotsOfRefsSchema" do
@moduledoc """
This specific setup causes `__unresolved_refs` to get into a state that makes the schema
fail to compile. The PR in which this file was introduced switches from `Map.update!` to
`Map.update` with a default and generates a valid schema.
"""

mod_base = __MODULE__

defmodule Base do
@mod_base mod_base

def schema() do
%{
type: :object,
properties: %{
foo: %{"$ref": :"#{@mod_base}.Foo"},
bar: %{type: :array, items: [%{"$ref": :"#{@mod_base}.Bar"}]},
flim: %{type: :array, items: [%{"$ref": :"#{@mod_base}.Flim"}]}
},
additionalProperties: false
}
end
end

defmodule Flim do
@mod_base mod_base

def schema() do
%{
type: :object,
properties: %{
flam: %{
oneOf: [
%{type: :null},
%{"$ref": :"#{@mod_base}.Flam"}
]
}
},
additionalProperties: false
}
end
end

defmodule Foo do
def schema() do
%{oneOf: [%{type: :null}, %{type: :string}]}
end
end

defmodule Bar do
@mod_base mod_base

def schema() do
%{type: :object, properties: %{baz: %{"$ref": :"#{@mod_base}.Baz"}}}
end
end

defmodule Baz do
def schema() do
%{oneOf: [%{type: :string}, %{type: :null}]}
end
end
end

defmodule :"#{mod}.LotsOfRefsSchema.Flam" do
def schema() do
%{
type: :object,
properties: %{
whatever: %{
type: :array,
items: [%{type: :array, items: [%{type: :string}]}]
}
},
additionalProperties: false
}
end
end

defmodule :"#{mod}.MyChannel" do
use ChannelHandler.Router
use ChannelSpec.Operations

operation "foo", payload: %{"$ref": :"#{mod}.LotsOfRefsSchema.Base"}
handle "foo", fn _params, _context, socket -> {:noreply, socket} end

subscription "sub", %{type: :integer}
end

defmodule :"#{mod}" do

Check warning on line 694 in test/channel_spec/socket_test.exs

View workflow job for this annotation

GitHub Actions / Elixir Unit Tests (1.13.4, 24.3)

function id/1 required by behaviour Phoenix.Socket is not implemented (in module Test2115)
use ChannelSpec.Socket, schema_path: Path.join(tmp_dir, "schema.json")

channel "foo", __MODULE__.MyChannel, schema_file: Path.join(tmp_dir, "schema.json")
end

saved_json = Path.join(tmp_dir, "schema.json") |> File.read!() |> Jason.decode!()

auto_assert %{
"channels" => %{
"foo" => %{
"messages" => %{
"foo" => %{"payload" => %{"$ref" => "#/definitions/Base"}}
},
"subscriptions" => %{"sub" => %{"type" => "integer"}}
}
},
"definitions" => %{
"Bar" => %{
"properties" => %{"baz" => %{"$ref" => "#/definitions/Baz"}},
"type" => "object"
},
"Base" => %{
"additionalProperties" => false,
"properties" => %{
"bar" => %{
"items" => [%{"$ref" => "#/definitions/Bar"}],
"type" => "array"
},
"flim" => %{
"items" => [%{"$ref" => "#/definitions/Flim"}],
"type" => "array"
},
"foo" => %{"$ref" => "#/definitions/Foo"}
},
"type" => "object"
},
"Baz" => %{"oneOf" => [%{"type" => "string"}, %{"type" => "null"}]},
"Flam" => %{
"additionalProperties" => false,
"properties" => %{
"whatever" => %{
"items" => [%{"items" => [%{"type" => "string"}], "type" => "array"}],
"type" => "array"
}
},
"type" => "object"
},
"Flim" => %{
"additionalProperties" => false,
"properties" => %{
"flam" => %{
"oneOf" => [%{"type" => "null"}, %{"$ref" => "#/definitions/Flam"}]
}
},
"type" => "object"
},
"Foo" => %{"oneOf" => [%{"type" => "null"}, %{"type" => "string"}]}
}
} <- saved_json
end
end
end
Loading