Fix RDF.BlankNode.Generator.start_link interface

This commit is contained in:
Marcel Otto 2022-02-26 23:03:17 +01:00
parent f5d8d16bc9
commit b89b5d34d2
5 changed files with 93 additions and 48 deletions

View file

@ -15,6 +15,11 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
- `RDF.Triple.coercible_t`, `RDF.Quad.coercible_t`, `RDF.Star.Triple.coercible_t` - `RDF.Triple.coercible_t`, `RDF.Quad.coercible_t`, `RDF.Star.Triple.coercible_t`
and `RDF.Star.Quad.coercible_t` types and `RDF.Star.Quad.coercible_t` types
### Fixed
- the interface of `RDF.BlankNode.Generator.start_link/1` was fixed, so that
generators can be started supervised
[Compare v0.10.0...HEAD](https://github.com/rdf-elixir/rdf-ex/compare/v0.10.0...HEAD) [Compare v0.10.0...HEAD](https://github.com/rdf-elixir/rdf-ex/compare/v0.10.0...HEAD)

View file

@ -12,22 +12,40 @@ defmodule RDF.BlankNode.Generator do
The state will be initialized according to the given `RDF.BlankNode.Generator.Algorithm`. The state will be initialized according to the given `RDF.BlankNode.Generator.Algorithm`.
""" """
def start_link(generation_mod, init_opts \\ %{}) do def start_link(algorithm) when is_atom(algorithm) do
GenServer.start_link(__MODULE__, {generation_mod, convert_opts(init_opts)}) start_link({[algorithm: algorithm], []})
end end
def start_link({algorithm, gen_server_opts}) when is_atom(algorithm) do
start_link({[algorithm: algorithm], gen_server_opts})
end
def start_link({init_opts, gen_server_opts}) do
{algorithm, init_opts} = Keyword.pop!(init_opts, :algorithm)
GenServer.start_link(__MODULE__, {algorithm, Map.new(init_opts)}, gen_server_opts)
end
def start_link(init_opts), do: start_link({init_opts, []})
@doc """ @doc """
Starts a blank node generator process without links (outside of a supervision tree). Starts a blank node generator process without links (outside of a supervision tree).
The state will be initialized according to the given `RDF.BlankNode.Generator.Algorithm`. The state will be initialized according to the given `RDF.BlankNode.Generator.Algorithm`.
""" """
def start(generation_mod, init_opts \\ %{}) do def start(algorithm) when is_atom(algorithm) do
GenServer.start(__MODULE__, {generation_mod, convert_opts(init_opts)}) start({[algorithm: algorithm], []})
end end
defp convert_opts(nil), do: %{} def start({algorithm, gen_server_opts}) when is_atom(algorithm) do
defp convert_opts(opts) when is_list(opts), do: Map.new(opts) start({[algorithm: algorithm], gen_server_opts})
defp convert_opts(opts) when is_map(opts), do: opts end
def start({init_opts, gen_server_opts}) do
{algorithm, init_opts} = Keyword.pop!(init_opts, :algorithm)
GenServer.start(__MODULE__, {algorithm, Map.new(init_opts)}, gen_server_opts)
end
def start(init_opts), do: start({init_opts, []})
@doc """ @doc """
Synchronously stops the blank node generator with the given `reason`. Synchronously stops the blank node generator with the given `reason`.

View file

@ -8,7 +8,7 @@ defmodule RDF.BlankNode.Generator.Algorithm do
@doc """ @doc """
Returns the initial state of the algorithm. Returns the initial state of the algorithm.
""" """
@callback init(opts :: map | keyword) :: map @callback init(opts :: map) :: map
@doc """ @doc """
Generates a blank node. Generates a blank node.

View file

@ -0,0 +1,61 @@
defmodule RDF.BlankNode.GeneratorTest do
use RDF.Test.Case
import RDF, only: [bnode: 1]
alias RDF.BlankNode.{Generator, Increment}
describe "Increment generator" do
test "generator without prefix" do
{:ok, generator} = start_supervised({Generator, Increment})
assert Generator.generate(generator) == bnode(0)
assert Generator.generate(generator) == bnode(1)
assert Generator.generate_for(generator, "foo") == bnode(2)
assert Generator.generate(generator) == bnode(3)
assert Generator.generate_for(generator, "bar") == bnode(4)
assert Generator.generate(generator) == bnode(5)
assert Generator.generate_for(generator, "foo") == bnode(2)
assert Generator.generate(generator) == bnode(6)
end
test "generator with prefix" do
{:ok, generator} = start_supervised({Generator, [algorithm: Increment, prefix: "b"]})
assert Generator.generate(generator) == bnode("b0")
assert Generator.generate(generator) == bnode("b1")
assert Generator.generate_for(generator, "foo") == bnode("b2")
assert Generator.generate(generator) == bnode("b3")
assert Generator.generate_for(generator, "bar") == bnode("b4")
assert Generator.generate(generator) == bnode("b5")
assert Generator.generate_for(generator, "foo") == bnode("b2")
assert Generator.generate(generator) == bnode("b6")
end
test "generator with non-string values" do
{:ok, generator} = start_supervised({Generator, [algorithm: Increment, prefix: "b"]})
assert Generator.generate(generator) == bnode("b0")
assert Generator.generate(generator) == bnode("b1")
assert Generator.generate_for(generator, {:foo, 42}) == bnode("b2")
assert Generator.generate(generator) == bnode("b3")
assert Generator.generate_for(generator, [:bar, 3.14]) == bnode("b4")
assert Generator.generate(generator) == bnode("b5")
assert Generator.generate_for(generator, {:foo, 42}) == bnode("b2")
assert Generator.generate(generator) == bnode("b6")
end
test "named generator" do
{:ok, _} = start_supervised({Generator, {Increment, [name: Foo]}})
assert Generator.generate(Foo) == bnode(0)
assert Generator.generate(Foo) == bnode(1)
{:ok, _} =
start_supervised({Generator, {[algorithm: Increment, prefix: "b"], [name: Bar]}}, id: :g2)
assert Generator.generate(Bar) == bnode("b0")
assert Generator.generate(Bar) == bnode("b1")
end
end
end

View file

@ -3,7 +3,7 @@ defmodule RDF.BlankNode.IncrementTest do
import RDF, only: [bnode: 1] import RDF, only: [bnode: 1]
alias RDF.BlankNode.{Generator, Increment} alias RDF.BlankNode.Increment
describe "generate/1" do describe "generate/1" do
test "without prefix" do test "without prefix" do
@ -36,43 +36,4 @@ defmodule RDF.BlankNode.IncrementTest do
{bnode("b0"), %{counter: 1, map: %{"foo" => 0}, prefix: "b"}} {bnode("b0"), %{counter: 1, map: %{"foo" => 0}, prefix: "b"}}
end end
end end
test "generator without prefix" do
{:ok, generator} = Generator.start_link(Increment)
assert Generator.generate(generator) == bnode(0)
assert Generator.generate(generator) == bnode(1)
assert Generator.generate_for(generator, "foo") == bnode(2)
assert Generator.generate(generator) == bnode(3)
assert Generator.generate_for(generator, "bar") == bnode(4)
assert Generator.generate(generator) == bnode(5)
assert Generator.generate_for(generator, "foo") == bnode(2)
assert Generator.generate(generator) == bnode(6)
end
test "generator with prefix" do
{:ok, generator} = Generator.start_link(Increment, prefix: "b")
assert Generator.generate(generator) == bnode("b0")
assert Generator.generate(generator) == bnode("b1")
assert Generator.generate_for(generator, "foo") == bnode("b2")
assert Generator.generate(generator) == bnode("b3")
assert Generator.generate_for(generator, "bar") == bnode("b4")
assert Generator.generate(generator) == bnode("b5")
assert Generator.generate_for(generator, "foo") == bnode("b2")
assert Generator.generate(generator) == bnode("b6")
end
test "generator with non-string values" do
{:ok, generator} = Generator.start_link(Increment, prefix: "b")
assert Generator.generate(generator) == bnode("b0")
assert Generator.generate(generator) == bnode("b1")
assert Generator.generate_for(generator, {:foo, 42}) == bnode("b2")
assert Generator.generate(generator) == bnode("b3")
assert Generator.generate_for(generator, [:bar, 3.14]) == bnode("b4")
assert Generator.generate(generator) == bnode("b5")
assert Generator.generate_for(generator, {:foo, 42}) == bnode("b2")
assert Generator.generate(generator) == bnode("b6")
end
end end