Skip to content

Commit 8791c9a

Browse files
committed
Script pour tester les règles custom Chouette Valid
1 parent cf3e23f commit 8791c9a

File tree

2 files changed

+376
-0
lines changed

2 files changed

+376
-0
lines changed
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
[
2+
{
3+
"rule_context": "resource/kind_of",
4+
"resource_classes": [
5+
"StopPlace",
6+
"Line",
7+
"Operator",
8+
"Network"
9+
],
10+
"rules": [
11+
{
12+
"rule": "attribute/mandatory",
13+
"name": "name",
14+
"criticity": "error",
15+
"code": "name-mandatory",
16+
"message": "A StopPlace, Line, Operator, Network, GroupOfLines has a Name"
17+
}
18+
]
19+
},
20+
{
21+
"rule": "attribute/match",
22+
"name": "short_name",
23+
"value": "/^.{0,12}$/",
24+
"criticity": "error",
25+
"code": "shortname-length",
26+
"message": "A ShortName have 12 or less than characters"
27+
},
28+
{
29+
"rule": "attribute/match",
30+
"name": "public_code",
31+
"value": "/^.{0,12}$/",
32+
"criticity": "error",
33+
"code": "public-code-length",
34+
"message": "A Public Code have 12 or less than characters"
35+
},
36+
{
37+
"rule_context": "resource/kind_of",
38+
"resource_classes": [
39+
"Quay",
40+
"StopPlace",
41+
"StopPlaceEntrance"
42+
],
43+
"rules": [
44+
{
45+
"rule": "attribute/mandatory",
46+
"name": "longitude",
47+
"criticity": "error",
48+
"code": "longitude-mandatory",
49+
"message": "Quay, StopPlace and StopPlaceEntrance have a Longitude"
50+
},
51+
{
52+
"rule": "attribute/mandatory",
53+
"name": "latitude",
54+
"criticity": "error",
55+
"code": "latitude-mandatory",
56+
"message": "Quay, StopPlace and StopPlaceEntrance have a Latitude"
57+
}
58+
]
59+
},
60+
{
61+
"rule_context": "resource/kind_of",
62+
"resource_class": "Line",
63+
"rules": [
64+
{
65+
"rule": "attribute/mandatory",
66+
"name": "transport_mode",
67+
"criticity": "error",
68+
"code": "line-transport-mode-mandatory",
69+
"message": "A Line has a Transport Mode"
70+
}
71+
]
72+
},
73+
{
74+
"rule_context": "resource/kind_of",
75+
"resource_class": "Line",
76+
"rules": [
77+
{
78+
"rule": "attribute/mandatory",
79+
"name": "presentation",
80+
"criticity": "warning",
81+
"code": "line-presentation-mandatory",
82+
"message": "A Line has a Presentation"
83+
},
84+
{
85+
"rule_context": "reduce/element",
86+
"element": "presentation",
87+
"rules": [
88+
{
89+
"rule": "attribute/mandatory",
90+
"name": "colour",
91+
"criticity": "warning",
92+
"code": "line-presentation-colour-mandatory",
93+
"message": "A Line has a Presentation color"
94+
}
95+
]
96+
}
97+
]
98+
},
99+
{
100+
"rule_context": "resource/kind_of",
101+
"resource_class": "Line",
102+
"rules": [
103+
{
104+
"rule": "attribute/blank",
105+
"name": "routes",
106+
"code": "line-no-inner-routes",
107+
"message": "A Line doesn’t define its own routes"
108+
}
109+
]
110+
},
111+
{
112+
"rule_context": "resource/kind_of",
113+
"resource_class": "Route",
114+
"rules": [
115+
{
116+
"rule": "attribute/mandatory",
117+
"name": "line_ref",
118+
"code": "route-line-ref-mandatory",
119+
"message": "A Route has a LineRef"
120+
}
121+
]
122+
},
123+
{
124+
"rule_context": "resource/kind_of",
125+
"resource_class": "JourneyPattern",
126+
"rules": [
127+
{
128+
"rule": "attribute/mandatory",
129+
"name": "route_ref",
130+
"code": "journey-pattern-route-ref-mandatory",
131+
"message": "A ServiceJourneyPattern has a RouteRef"
132+
}
133+
]
134+
},
135+
{
136+
"rule_context": "resource/kind_of",
137+
"resource_class": "ServiceJourney",
138+
"rules": [
139+
{
140+
"rule": "attribute/mandatory",
141+
"name": "journey_pattern_ref",
142+
"code": "service-journey-journey-pattern-ref-mandatory",
143+
"message": "A ServiceJourney has a JourneyPatternRef"
144+
}
145+
]
146+
},
147+
{
148+
"rule_context": "resource/kind_of",
149+
"resource_class": "JourneyPattern",
150+
"rules": [
151+
{
152+
"rule": "collection/count",
153+
"collection": "points_in_sequence",
154+
"minimum_count": 2,
155+
"code": "service-journey-pattern-many-points-in-sequence",
156+
"message": "A (Service)JourneyPattern has two or more pointsInSequence"
157+
}
158+
]
159+
},
160+
{
161+
"rule_context": "resource/kind_of",
162+
"resource_class": "ServiceJourney",
163+
"rules": [
164+
{
165+
"rule": "collection/count",
166+
"collection": "day_types",
167+
"minimum_count": 1,
168+
"code": "service-journey-day-types-mandatory",
169+
"message": "A ServiceJourney has one or more dayTypes"
170+
}
171+
]
172+
},
173+
{
174+
"rule_context": "resource/kind_of",
175+
"resource_class": "ServiceJourney",
176+
"rules": [
177+
{
178+
"rule": "collection/count",
179+
"collection": "passing_times",
180+
"minimum_count": 2,
181+
"code": "service-journey-passing-times-mandatory",
182+
"message": "A ServiceJourney has two or more passingTimes"
183+
}
184+
]
185+
},
186+
{
187+
"rule_context": "resource/kind_of",
188+
"resource_class": "DestinationDisplay",
189+
"rules": [
190+
{
191+
"rule": "attribute/mandatory",
192+
"name": "front_text",
193+
"code": "destination-display-front-text",
194+
"message": "A Destination Display have a FrontText attribute"
195+
}
196+
]
197+
},
198+
{
199+
"rule_context": "resource/kind_of",
200+
"resource_class": "PassengerStopAssignment",
201+
"rules": [
202+
{
203+
"rule": "attribute/mandatory",
204+
"name": "scheduled_stop_point_ref",
205+
"code": "passenger-stop-assignment-scheduled-stop-point-ref",
206+
"message": "A PassengerStopAssignment has a ScheduledStopPointRef"
207+
}
208+
]
209+
},
210+
{
211+
"rule": "attribute/match",
212+
"name": "id",
213+
"value": "/^.{0,255}$/",
214+
"criticity": "warning",
215+
"code": "id-length",
216+
"message": "Any NeTEx id uses less than 256 characters"
217+
},
218+
{
219+
"rule": "reference/exist",
220+
"referenced_class": "ScheduledStopPoint",
221+
"code": "scheduled-stop-point-refs-exist",
222+
"message": "Referenced ScheduledStopPoints are present"
223+
},
224+
{
225+
"rule": "reference/exist",
226+
"referenced_class": "Operator",
227+
"code": "operator-refs-exist",
228+
"message": "Referenced Operators are present"
229+
},
230+
{
231+
"rule": "reference/exist",
232+
"referenced_class": "DayType",
233+
"code": "day-type-refs-exist",
234+
"message": "Referenced DayTypes are present"
235+
},
236+
{
237+
"rule": "reference/exist",
238+
"referenced_class": "Route",
239+
"code": "route-refs-exist",
240+
"message": "Referenced Routes are present"
241+
},
242+
{
243+
"rule": "reference/exist",
244+
"referenced_class": "JourneyPattern",
245+
"code": "journey-pattern-refs-exist",
246+
"message": "Referenced (Service)JourneyPattern are present"
247+
},
248+
{
249+
"rule": "reference/exist",
250+
"referenced_class": "DestinationDisplay",
251+
"code": "destination-display-refs-exist",
252+
"message": "Referenced DestinationDisplays are present"
253+
},
254+
{
255+
"rule": "reference/exist",
256+
"referenced_class": "Direction",
257+
"code": "direction-refs-exist",
258+
"message": "Referenced Directions are present"
259+
},
260+
{
261+
"rule": "reference/exist",
262+
"referenced_class": "RoutePoint",
263+
"code": "route-point-refs-exist",
264+
"message": "Referenced RoutePoints are present"
265+
},
266+
{
267+
"rule": "service_journey/passing_times_chronology",
268+
"code": "service-journey-passing-times-chronology",
269+
"message": "TimedPassingTimes use chronological passing times"
270+
}
271+
]

scripts/chouette_valid_ruleset.exs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
defmodule Script do
2+
@moduledoc """
3+
Script to debug and inspect current implementation of validation rules for the
4+
French NeTEx profile.
5+
"""
6+
7+
import Transport.NeTEx.FrenchProfile
8+
alias Transport.EnRoute.ChouetteValidRulesetsClient.Slugs
9+
alias Transport.EnRoute.ChouetteValidRulesetsClient.Wrapper
10+
11+
def document_rulesets do
12+
with_file("chouette_ruleset.json", &ruleset/1)
13+
with_file("chouette_ruleset.md", &markdown/1)
14+
end
15+
16+
def list_rulesets do
17+
Wrapper.impl().list_rulesets()
18+
|> IO.inspect()
19+
end
20+
21+
def purge_rulesets do
22+
Wrapper.impl().list_rulesets()
23+
|> Enum.each(fn %{"id" => ruleset_id, "slug" => slug} ->
24+
IO.puts("Deleting profile #{slug}")
25+
Wrapper.impl().delete_ruleset(ruleset_id)
26+
end)
27+
end
28+
29+
def list_versions(slug) do
30+
Wrapper.list_versions(slug)
31+
|> Enum.map(fn %{"slug" => version_slug, "id" => id, "updated_at" => timestamp} ->
32+
{version_slug, id, timestamp}
33+
end)
34+
|> IO.inspect()
35+
end
36+
37+
def find_ruleset_id(slug) do
38+
Wrapper.find_ruleset_id(slug)
39+
|> IO.inspect(label: "found slug #{slug}")
40+
end
41+
42+
def get_ruleset(slug) do
43+
Wrapper.impl().get_ruleset(slug)
44+
|> IO.inspect()
45+
end
46+
47+
def publish_rulesets(slug) do
48+
slug = Slugs.check_slug!(slug)
49+
50+
result =
51+
with_string(&ruleset/1)
52+
|> prepend_enroute_starter_kit()
53+
|> upsert_ruleset("French profile", slug)
54+
55+
case result do
56+
{:ok, ruleset_id} -> IO.puts("Ruleset properly pushed with id: #{ruleset_id}")
57+
{:error, msg} -> IO.puts("Error pushing the rulesets: #{msg}")
58+
end
59+
end
60+
61+
def upsert_ruleset(ruleset, name, slug) do
62+
case Wrapper.impl().create_ruleset(ruleset, name, slug) do
63+
{:error, "Slug already taken"} -> Wrapper.impl().update_ruleset(ruleset, name, slug)
64+
result -> result
65+
end
66+
end
67+
68+
defp with_file(file, proc), do: File.write(file, with_string(proc))
69+
70+
defp with_string(proc) do
71+
{:ok, device} = StringIO.open("")
72+
73+
proc.(device)
74+
75+
StringIO.flush(device)
76+
end
77+
78+
# I wish we could refer another ruleset
79+
defp prepend_enroute_starter_kit(json) do
80+
enroute_rules = read_enroute_starter_kit()
81+
pan_rules = Jason.decode!(json)
82+
83+
Jason.encode!(enroute_rules ++ pan_rules)
84+
end
85+
86+
defp read_enroute_starter_kit do
87+
"apps/transport/lib/netex/enroute-starter-kit.json"
88+
|> File.read!()
89+
|> Jason.decode!()
90+
end
91+
end
92+
93+
# Script.document_rulesets()
94+
95+
# Script.list_rulesets()
96+
# Script.purge_rulesets()
97+
# Script.list_rulesets()
98+
# Script.find_ruleset_id("pan:french_profile:2")
99+
# Script.find_ruleset_id("pan:french_profile:7")
100+
101+
# Script.get_ruleset("pan:french_profile:7")
102+
Script.publish_rulesets("pan:french_profile:1")
103+
Script.get_ruleset("pan:french_profile:1")
104+
105+
Script.list_versions("pan:french_profile")

0 commit comments

Comments
 (0)