Skip to content

Commit ad51d91

Browse files
Merge pull request #59 from shinnokdisengir/feature/trigger
add trigger generator + tests
2 parents cdcc8f1 + ad66953 commit ad51d91

File tree

10 files changed

+643
-0
lines changed

10 files changed

+643
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2025 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
defmodule Astarte.Core.Generators.Triggers.SimpleEvents.DeviceConnectedEvent do
20+
@moduledoc """
21+
This module provides generators for Astarte Trigger Simple Event DeviceConnectedEvent struct.
22+
"""
23+
use ExUnitProperties
24+
25+
import Astarte.Generators.Utilities.ParamsGen
26+
27+
alias Astarte.Core.Triggers.SimpleEvents.DeviceConnectedEvent
28+
29+
alias Astarte.Common.Generators.Ip, as: IpGenerator
30+
alias Astarte.Utilities.Map, as: MapUtilities
31+
32+
@spec device_connected_event() :: StreamData.t(DeviceConnectedEvent.t())
33+
@spec device_connected_event(keyword :: keyword()) :: StreamData.t(DeviceConnectedEvent.t())
34+
def device_connected_event(params \\ []) do
35+
params gen all device_ip_address <- device_ip_address(),
36+
params: params do
37+
%DeviceConnectedEvent{
38+
device_ip_address: device_ip_address
39+
}
40+
end
41+
end
42+
43+
@doc """
44+
Convert this struct/stream to changes
45+
"""
46+
@spec to_changes(DeviceConnectedEvent.t()) :: StreamData.t(map())
47+
def to_changes(data) when not is_struct(data, StreamData),
48+
do: data |> constant() |> to_changes()
49+
50+
@spec to_changes(StreamData.t(DeviceConnectedEvent.t())) :: StreamData.t(map())
51+
def to_changes(gen) do
52+
gen all %DeviceConnectedEvent{
53+
device_ip_address: device_ip_address
54+
} <- gen do
55+
%{
56+
device_ip_address: device_ip_address
57+
}
58+
|> MapUtilities.clean()
59+
end
60+
end
61+
62+
defp device_ip_address,
63+
do:
64+
IpGenerator.ip(:ipv4)
65+
|> map(&Tuple.to_list/1)
66+
|> map(&Enum.join(&1, "."))
67+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2025 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
defmodule Astarte.Core.Generators.Triggers.SimpleEvents.DeviceDisconnectedEvent do
20+
@moduledoc """
21+
This module provides generators for Astarte Trigger Simple Event DeviceDisconnectedEvent struct.
22+
"""
23+
use ExUnitProperties
24+
25+
alias Astarte.Core.Triggers.SimpleEvents.DeviceDisconnectedEvent
26+
27+
alias Astarte.Utilities.Map, as: MapUtilities
28+
29+
@spec device_disconnected_event() :: StreamData.t(DeviceDisconnectedEvent.t())
30+
def device_disconnected_event, do: constant(%DeviceDisconnectedEvent{})
31+
32+
@doc """
33+
Convert this struct/stream to changes
34+
"""
35+
@spec to_changes(DeviceDisconnectedEvent.t()) :: StreamData.t(map())
36+
def to_changes(data) when not is_struct(data, StreamData),
37+
do: data |> constant() |> to_changes()
38+
39+
@spec to_changes(StreamData.t(DeviceDisconnectedEvent.t())) :: StreamData.t(map())
40+
def to_changes(gen) do
41+
gen all device_disconnected_event <- gen do
42+
device_disconnected_event
43+
|> Map.from_struct()
44+
|> MapUtilities.clean()
45+
end
46+
end
47+
end
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2025 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
defmodule Astarte.Core.Generators.Triggers.SimpleEvents.DeviceErrorEvent do
20+
@moduledoc """
21+
This module provides generators for Astarte Trigger Simple Event DeviceErrorEvent struct.
22+
"""
23+
use ExUnitProperties
24+
25+
import Astarte.Generators.Utilities.ParamsGen
26+
27+
alias Astarte.Core.Triggers.SimpleEvents.DeviceErrorEvent
28+
29+
alias Astarte.Utilities.Map, as: MapUtilities
30+
31+
@spec device_error_event() :: StreamData.t(DeviceErrorEvent.t())
32+
@spec device_error_event(keyword :: keyword()) :: StreamData.t(DeviceErrorEvent.t())
33+
def device_error_event(params \\ []) do
34+
params gen all error_name <- error_name(),
35+
metadata <- metadata(),
36+
params: params do
37+
%DeviceErrorEvent{
38+
error_name: error_name,
39+
metadata: metadata
40+
}
41+
end
42+
end
43+
44+
@doc """
45+
Convert this struct/stream to changes
46+
"""
47+
@spec to_changes(DeviceErrorEvent.t()) :: StreamData.t(map())
48+
def to_changes(data) when not is_struct(data, StreamData),
49+
do: data |> constant() |> to_changes()
50+
51+
@spec to_changes(StreamData.t(DeviceErrorEvent.t())) :: StreamData.t(map())
52+
def to_changes(gen) do
53+
gen all %DeviceErrorEvent{
54+
error_name: error_name,
55+
metadata: metadata
56+
} <- gen do
57+
%{
58+
error_name: error_name,
59+
metadata: metadata
60+
}
61+
|> MapUtilities.clean()
62+
end
63+
end
64+
65+
defp error_name, do: one_of([nil, string(:utf8)])
66+
67+
defp metadata,
68+
do: map_of(string(:utf8), string(:utf8), min_length: 0, max_length: 10)
69+
end
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2025 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
defmodule Astarte.Core.Generators.Triggers.SimpleEvents.IncomingDataEvent do
20+
@moduledoc """
21+
This module provides generators for Astarte Trigger Simple Event IncomingDataEvent struct.
22+
"""
23+
use ExUnitProperties
24+
25+
import Astarte.Generators.Utilities.ParamsGen
26+
27+
alias Astarte.Core.Triggers.SimpleEvents.IncomingDataEvent
28+
29+
alias Astarte.Core.Interface
30+
31+
alias Astarte.Core.Generators.Interface, as: InterfaceGenerator
32+
alias Astarte.Core.Generators.Mapping.Value, as: ValueGenerator
33+
34+
@spec incoming_data_event() :: StreamData.t(IncomingDataEvent.t())
35+
@spec incoming_data_event(keyword :: keyword()) :: StreamData.t(IncomingDataEvent.t())
36+
def incoming_data_event(params \\ []) do
37+
gen_fields =
38+
params gen all :interface,
39+
%Interface{name: interface_name} = interface <-
40+
InterfaceGenerator.interface(),
41+
value <- ValueGenerator.value(interface: interface),
42+
params: params do
43+
%{
44+
interface: interface_name,
45+
path: value.path,
46+
bson_value: value.value
47+
}
48+
end
49+
50+
gen_fields
51+
|> bind(fn fields ->
52+
fields
53+
|> Map.new(fn {k, v} -> {k, constant(v)} end)
54+
|> optional_map()
55+
end)
56+
|> map(&struct(IncomingDataEvent, &1))
57+
end
58+
end
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2025 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
defmodule Astarte.Core.Generators.Triggers.SimpleEvents.IncomingIntrospectionEvent do
20+
@moduledoc """
21+
This module provides generators for Astarte Trigger Simple Event IncomingIntrospectionEvent struct.
22+
"""
23+
use ExUnitProperties
24+
25+
import Astarte.Generators.Utilities.ParamsGen
26+
27+
alias Astarte.Core.Interface
28+
alias Astarte.Core.Triggers.SimpleEvents.IncomingIntrospectionEvent
29+
alias Astarte.Core.Triggers.SimpleEvents.InterfaceVersion
30+
31+
alias Astarte.Core.Generators.Interface, as: InterfaceGenerator
32+
33+
@spec incoming_introspection_event() :: StreamData.t(IncomingIntrospectionEvent.t())
34+
@spec incoming_introspection_event(keyword :: keyword()) ::
35+
StreamData.t(IncomingIntrospectionEvent.t())
36+
def incoming_introspection_event(params \\ []) do
37+
params gen all interfaces <- InterfaceGenerator.interface() |> list_of(max_length: 10),
38+
params: params do
39+
introspection_map =
40+
interfaces
41+
|> Enum.map(fn %Interface{
42+
name: name,
43+
major_version: major_version,
44+
minor_version: minor_version
45+
} ->
46+
{name, major_version, minor_version}
47+
end)
48+
|> Map.new(fn {name, major_version, minor_version} ->
49+
{name,
50+
%InterfaceVersion{
51+
major: major_version,
52+
minor: minor_version
53+
}}
54+
end)
55+
56+
%IncomingIntrospectionEvent{
57+
introspection_map: introspection_map
58+
}
59+
end
60+
end
61+
end
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#
2+
# This file is part of Astarte.
3+
#
4+
# Copyright 2025 SECO Mind Srl
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
19+
defmodule Astarte.Core.Generators.Triggers.SimpleEvents.DeviceConnectedEventTest do
20+
use ExUnit.Case, async: true
21+
use ExUnitProperties
22+
23+
alias Astarte.Core.Triggers.SimpleEvents.DeviceConnectedEvent
24+
25+
alias Astarte.Core.Generators.Triggers.SimpleEvents.DeviceConnectedEvent,
26+
as: DeviceConnectedEventGenerator
27+
28+
@moduletag :trigger
29+
@moduletag :simple_event
30+
@moduletag :device_connected_event
31+
32+
@doc false
33+
describe "triggers device_connected_event generator" do
34+
@describetag :success
35+
@describetag :ut
36+
property "generates valid device_connected_event" do
37+
check all device_connected_event <- DeviceConnectedEventGenerator.device_connected_event() do
38+
assert %DeviceConnectedEvent{} = device_connected_event
39+
end
40+
end
41+
42+
property "device_connected_event generates valid ip address ipv4" do
43+
check all %DeviceConnectedEvent{
44+
device_ip_address: device_ip_address
45+
} <- DeviceConnectedEventGenerator.device_connected_event(),
46+
ipv4_address = String.to_charlist(device_ip_address) do
47+
assert {:ok, _} = :inet.parse_ipv4_address(ipv4_address)
48+
end
49+
end
50+
51+
property "generates valid changes using to_changes (gen)" do
52+
gen_device_connected_event_changes =
53+
DeviceConnectedEventGenerator.device_connected_event()
54+
|> DeviceConnectedEventGenerator.to_changes()
55+
56+
check all changes <- gen_device_connected_event_changes do
57+
assert is_map(changes)
58+
end
59+
end
60+
61+
property "generates valid changes using to_changes (struct)" do
62+
check all device_connected_event <- DeviceConnectedEventGenerator.device_connected_event(),
63+
changes <- DeviceConnectedEventGenerator.to_changes(device_connected_event) do
64+
assert is_map(changes)
65+
end
66+
end
67+
end
68+
end

0 commit comments

Comments
 (0)