@@ -23,12 +23,68 @@ defmodule Astarte.Core.Generators.InterfaceTest do
2323 use ExUnit.Case , async: true
2424 use ExUnitProperties
2525
26- alias Astarte.Core.Generators.Interface , as: InterfaceGenerator
2726 alias Astarte.Core.Interface
27+ alias Astarte.Core.Mapping
28+
29+ alias Astarte.Core.Generators.Interface , as: InterfaceGenerator
2830
2931 @ moduletag :core
3032 @ moduletag :interface
3133
34+ @ endpoint_cases [
35+ { [ "/AbCde" , "/AbCde/QwEr" , "/XyZ" ] , [ "/AbCde" , "/XyZ" ] } ,
36+ { [ "/shop/Prd45" , "/shop/Prd45/Details" ] , [ "/shop/Prd45" ] } ,
37+ { [ "/alpha/Beta" , "/alpha/Beta/Gamma" , "/alpha/Delta" ] , [ "/alpha/Beta" , "/alpha/Delta" ] } ,
38+ { [ "/%{RootB}/Xy" , "/%{RootA}" , "/%{RootA}/Xy" , "/Abc" ] , [ "/%{RootB}/Xy" ] } ,
39+ { [ "/%{RootB}" , "/%{RootB}/Seg1" , "/%{RootB}/Seg1/Seg2" ] , [ "/%{RootB}" ] } ,
40+ { [ "/api/%{CA}" , "/api/%{CA}/status" , "/api/%{VA}/status" ] , [ "/api/%{CA}" ] } ,
41+ { [ "/api/%{V_1}" , "/api/%{V_1}/ping" , "/api/%{V_2}" ] , [ "/api/%{V_1}" ] } ,
42+ { [ "/api/%{V_1}/detail" , "/%{mask}/detail" , "/api/%{V_2}" ] , [ "/api/%{V_1}/detail" ] } ,
43+ { [ "/Ux9/Za2" , "/Ux9/Za2/Rt7" ] , [ "/Ux9/Za2" ] } ,
44+ { [ "/foo/%{idA}" , "/foo/%{idB}/bar" ] , [ "/foo/%{idA}" ] } ,
45+ { [ "/foo/%{Ab1}" , "/foo/%{Ab1}/X" , "/bar/Baz" ] , [ "/foo/%{Ab1}" , "/bar/Baz" ] } ,
46+ { [ "/mmNn/ooPP" , "/mmNn/ooPP/qqRR" ] , [ "/mmNn/ooPP" ] } ,
47+ { [ "/docs/%{Slug_1}" , "/docs/%{Slug_1}/v1" , "/docs/%{Slug_2}" ] , [ "/docs/%{Slug_1}" ] } ,
48+ { [ "/AA/BB" , "/AA/BB/CC" , "/DD" ] , [ "/AA/BB" , "/DD" ] } ,
49+ { [ "/AA/BB/CC" , "/AA/BB" ] , [ "/AA/BB/CC" ] } ,
50+ { [ "/xY/Za" , "/xY/Za/Q1" , "/xY/Zb" ] , [ "/xY/Za" , "/xY/Zb" ] } ,
51+ { [ "/p1q2/RS" , "/p1q2/RS/TT/UU" ] , [ "/p1q2/RS" ] } ,
52+ { [ "/user/%{U_123}" , "/user/%{U_123}/orders" , "/user/%{U_456}" ] , [ "/user/%{U_123}" ] } ,
53+ { [ "/calc/%{ModeA}/run" , "/calc/%{ModeB}/run" ] , [ "/calc/%{ModeA}/run" ] } ,
54+ { [ "/calc/%{ModeC}/run/now" , "/calc/%{ModeC}/run" ] , [ "/calc/%{ModeC}/run/now" ] } ,
55+ { [ "/A1b2C3" , "/A1b2C3/D4e5" ] , [ "/A1b2C3" ] } ,
56+ { [ "/AABB" , "/AABBCC" ] , [ "/AABB" , "/AABBCC" ] } ,
57+ { [ "/srv/%{EnvX}/cfg" , "/srv/%{EnvX}/cfg/edit" ] , [ "/srv/%{EnvX}/cfg" ] } ,
58+ { [ "/srv/%{Env_1}/cfg" , "/srv/%{Env_2}/cfg" ] , [ "/srv/%{Env_1}/cfg" ] } ,
59+ { [ "/%{ROOT_X}" , "/%{ROOT_Y}" , "/%{ROOT_Y}/x" ] , [ "/%{ROOT_X}" ] } ,
60+ { [ "/root/%{Id1}/x" , "/root/%{Id2}/x/y" ] , [ "/root/%{Id1}/x" ] } ,
61+ { [ "/root/%{Abc}/x/y" , "/root/%{Abc}/x" ] , [ "/root/%{Abc}/x/y" ] } ,
62+ { [ "/kLm/Nop" , "/kLm/Nop/Qrs" , "/kLm/Tuv" ] , [ "/kLm/Nop" , "/kLm/Tuv" ] } ,
63+ { [ "/data/%{KeyA}/val" , "/data/%{KeyB}/val" ] , [ "/data/%{KeyA}/val" ] } ,
64+ { [ "/data/%{KeyA}/val" , "/data/%{KeyA}/val/x" ] , [ "/data/%{KeyA}/val" ] } ,
65+ { [ "/zZz/%{Pid}/q" , "/zZz/%{Pid}/q/r" ] , [ "/zZz/%{Pid}/q" ] } ,
66+ { [ "/zZz/%{Pid1}/q" , "/zZz/%{Pid2}/w" ] , [ "/zZz/%{Pid1}/q" , "/zZz/%{Pid2}/w" ] } ,
67+ { [ "/Mix/Aa" , "/Mix/Aa/Bb" , "/Mix/Cc" ] , [ "/Mix/Aa" , "/Mix/Cc" ] } ,
68+ { [ "/auth/Login" , "/auth/Login/Step2" ] , [ "/auth/Login" ] } ,
69+ { [ "/auth/%{FlowA}/step/next" , "/auth/%{FlowA}/step" ] , [ "/auth/%{FlowA}/step/next" ] } ,
70+ { [ "/auth/%{FlowA}/step" , "/auth/%{FlowB}" ] , [ "/auth/%{FlowA}/step" ] } ,
71+ { [ "/r1/r2/r3" , "/r1/r2" ] , [ "/r1/r2/r3" ] } ,
72+ { [ "/r1/%{VarA}" , "/r1/%{VarA}/x" , "/r2" ] , [ "/r1/%{VarA}" , "/r2" ] } ,
73+ { [ "/A_/B_" , "/A_/B_/C_" ] , [ "/A_/B_" ] } ,
74+ { [ "/A_/B_/C_" , "/A_/B_/C_/D_" ] , [ "/A_/B_/C_" ] } ,
75+ { [ "/node/%{N1}/leaf/%{L2}" , "/node/%{N1}/leaf" ] , [ "/node/%{N1}/leaf/%{L2}" ] } ,
76+ { [ "/node/%{N1}/leaf/%{L2}" , "/node/%{N2}/leaf/%{L3}" ] , [ "/node/%{N1}/leaf/%{L2}" ] } ,
77+ { [ "/Sx/Tx" , "/Sx/Tx/Ux" , "/Sx/Vx" ] , [ "/Sx/Tx" , "/Sx/Vx" ] } ,
78+ { [ "/G1/H2" , "/G1/H2/I3/J4" ] , [ "/G1/H2" ] } ,
79+ { [ "/lib/%{Pkg}/v" , "/lib/%{Pkg}/v/1" ] , [ "/lib/%{Pkg}/v" ] } ,
80+ { [ "/lib/%{PkgA}/v" , "/lib/%{PkgB}/v" ] , [ "/lib/%{PkgA}/v" ] } ,
81+ { [ "/cat/%{C1}/dog/%{D2}" , "/cat/%{C1}/dog/%{D2}/x" ] , [ "/cat/%{C1}/dog/%{D2}" ] } ,
82+ { [ "/alpha/%{A1}/beta" , "/alpha/%{A1}/beta/gamma" ] , [ "/alpha/%{A1}/beta" ] } ,
83+ { [ "/alpha/%{A1}/beta" , "/alpha/%{A2}" ] , [ "/alpha/%{A1}/beta" ] } ,
84+ { [ "/xLong/SegName" , "/xLong/SegName/Next" ] , [ "/xLong/SegName" ] } ,
85+ { [ "/Ping" , "/Ping/Pong" , "/Pang" ] , [ "/Ping" , "/Pang" ] }
86+ ]
87+
3288 @ doc false
3389 describe "interface generator" do
3490 @ describetag :success
@@ -51,6 +107,35 @@ defmodule Astarte.Core.Generators.InterfaceTest do
51107 end
52108 end
53109
110+ test "validate endpoints in :individual" do
111+ for { endpoints , results } <- @ endpoint_cases do
112+ mappings =
113+ for endpoint <- endpoints do
114+ % Mapping { endpoint: endpoint }
115+ end
116+
117+ uniq_mappings = InterfaceGenerator . uniq_endpoints ( mappings )
118+
119+ uniq_endpoints =
120+ for % Mapping { endpoint: endpoint } <- uniq_mappings do
121+ endpoint
122+ end
123+
124+ assert MapSet . new ( results ) == MapSet . new ( uniq_endpoints )
125+ end
126+ end
127+
128+ property "validate endpoints in aggregation :object must be the same" do
129+ check all % Interface { mappings: mappings } <-
130+ InterfaceGenerator . interface ( aggregation: :object ) ,
131+ endpoints =
132+ mappings
133+ |> Enum . map ( fn % Mapping { endpoint: endpoint } -> endpoint end )
134+ |> Enum . map ( & Regex . replace ( ~r" /[^/]+$" , & 1 , "" ) ) do
135+ assert 1 == endpoints |> Enum . uniq ( ) |> length ( )
136+ end
137+ end
138+
54139 @ tag issue: 45
55140 property "custom interface creation" do
56141 gen_interface_changes =
0 commit comments