atco 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/atco/version.rb +1 -1
- data/lib/atco.rb +16 -3
- data/spec/atco_spec.rb +155 -113
- data/spec/spec_helper.rb +12 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59b747dbf14f2f4ab07ca86c8344fda6294efbf4d7b83cdd11fcfa45a9e4961b
|
4
|
+
data.tar.gz: 276916993eae21683270e35ba8d4d167820eb2ae65dd410ab535f94a7ba50134
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54cf093ae098cc2fbc2b38067ffeeec9fa7a513107b00a4cb7822b8c0b65e273b016be3465dffed59403a9f88ce9f4cfb3c750236fb8c1354ffa9347511b26ca
|
7
|
+
data.tar.gz: 92c5635e38a717f4ba9f0e036d081463b4d84bb5bd3d1788d99b191b54e8bcd09f6a44bc114f5495302a191fc47b8887f8c97934696c7a5b6f3ad9d6217fc544
|
data/lib/atco/version.rb
CHANGED
data/lib/atco.rb
CHANGED
@@ -9,6 +9,8 @@ require_relative "atco/version"
|
|
9
9
|
|
10
10
|
# Public: Atco is a module that provides a parser for the ATCO-CIF data format.
|
11
11
|
module Atco # rubocop:disable Metrics/ModuleLength
|
12
|
+
class UnidentifiedRecordError < StandardError; end
|
13
|
+
|
12
14
|
class << self # rubocop:disable Metrics/ClassLength
|
13
15
|
@path = nil
|
14
16
|
METHODS = {
|
@@ -21,6 +23,7 @@ module Atco # rubocop:disable Metrics/ModuleLength
|
|
21
23
|
origin: "QO",
|
22
24
|
journey_header: "QS"
|
23
25
|
}.freeze
|
26
|
+
METHODS_BY_RECORD_IDENTITY = METHODS.invert.freeze
|
24
27
|
|
25
28
|
def parse(file) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
26
29
|
@path = File.expand_path(file)
|
@@ -32,13 +35,20 @@ module Atco # rubocop:disable Metrics/ModuleLength
|
|
32
35
|
locations = []
|
33
36
|
journeys = {}
|
34
37
|
header = nil
|
38
|
+
unparsed = []
|
35
39
|
|
36
|
-
data.
|
40
|
+
data.each_with_index do |line, line_number| # rubocop:disable Metrics/BlockLength
|
37
41
|
if line == data.first
|
38
42
|
header = parse_header(line)
|
39
43
|
next
|
40
44
|
end
|
41
|
-
|
45
|
+
|
46
|
+
identifier = line[0, 2]
|
47
|
+
method = METHODS_BY_RECORD_IDENTITY[identifier]
|
48
|
+
|
49
|
+
begin
|
50
|
+
raise UnidentifiedRecordError, "Unidentified record: #{identifier}" unless method
|
51
|
+
|
42
52
|
object = send("parse_#{method}", line)
|
43
53
|
next unless object[:record_identity] && object[:record_identity] == identifier
|
44
54
|
|
@@ -59,9 +69,12 @@ module Atco # rubocop:disable Metrics/ModuleLength
|
|
59
69
|
end
|
60
70
|
end
|
61
71
|
objects << object
|
72
|
+
rescue UnidentifiedRecordError
|
73
|
+
unparsed << {line: line, line_number: line_number}
|
74
|
+
next
|
62
75
|
end
|
63
76
|
end
|
64
|
-
{ header: header, locations: locations, journeys: journeys }
|
77
|
+
{ header: header, locations: locations, journeys: journeys, unparsed: unparsed }
|
65
78
|
end
|
66
79
|
|
67
80
|
def parse_header(string)
|
data/spec/atco_spec.rb
CHANGED
@@ -1,175 +1,217 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "#{File.dirname(__FILE__)}/spec_helper"
|
4
3
|
require "json"
|
5
4
|
|
6
|
-
describe Atco do # rubocop:disable Metrics/BlockLength
|
5
|
+
RSpec.describe Atco do # rubocop:disable Metrics/BlockLength
|
7
6
|
it "has a version number" do
|
8
7
|
expect(Atco::VERSION).not_to be nil
|
9
8
|
end
|
10
9
|
|
11
|
-
it "should output file for debugging!" do
|
12
|
-
result = Atco.parse("spec/fixtures/example.cif")
|
13
|
-
File.open("test.output", "w+") do |f|
|
14
|
-
f.flush
|
15
|
-
f.write(JSON.pretty_generate(result))
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
10
|
it "should parse header from fixture" do
|
20
11
|
result = Atco.parse("spec/fixtures/example.cif")
|
21
|
-
expect
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
12
|
+
expect(result[:header]).to eq(
|
13
|
+
{
|
14
|
+
file_type: "ATCO-CIF",
|
15
|
+
file_originator: "Electronic Registration",
|
16
|
+
source_product: "MIA 4.20.18",
|
17
|
+
version: "5.0",
|
18
|
+
production_datetime: "20090915113809"
|
19
|
+
}
|
20
|
+
)
|
28
21
|
end
|
29
22
|
|
30
23
|
it "should parse locations from fixture" do
|
31
24
|
result = Atco.parse("spec/fixtures/example.cif")
|
32
|
-
expect
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
25
|
+
expect(result[:header]).to eq(
|
26
|
+
{
|
27
|
+
file_type: "ATCO-CIF",
|
28
|
+
file_originator: "Electronic Registration",
|
29
|
+
source_product: "MIA 4.20.18",
|
30
|
+
version: "5.0",
|
31
|
+
production_datetime: "20090915113809"
|
32
|
+
}
|
33
|
+
)
|
39
34
|
end
|
40
35
|
|
41
36
|
it "should parse header" do
|
42
|
-
expect
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
expect(Atco.parse_header("ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n")).to eq(
|
38
|
+
{
|
39
|
+
file_type: "ATCO-CIF",
|
40
|
+
version: "5.0",
|
41
|
+
file_originator: "Electronic Registration",
|
42
|
+
source_product: "MIA 4.20.18",
|
43
|
+
production_datetime: "20090915113809"
|
44
|
+
}
|
45
|
+
)
|
49
46
|
end
|
50
47
|
|
51
48
|
it "should parse bank holiday" do
|
52
|
-
expect
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
expect(Atco.parse_bank_holiday("QHN20061225")).to eq(
|
50
|
+
{
|
51
|
+
record_identity: "QH",
|
52
|
+
transaction_type: "N",
|
53
|
+
date_of_bank_holiday: "20061225"
|
54
|
+
}
|
55
|
+
)
|
57
56
|
end
|
58
57
|
|
59
58
|
it "should parse operator" do
|
60
|
-
expect
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
59
|
+
expect(Atco.parse_operator("QPNTM Translink Metro Translink Metro \r\n")).to eq(
|
60
|
+
{
|
61
|
+
record_identity: "QP",
|
62
|
+
transaction_type: "N",
|
63
|
+
operator: "TM",
|
64
|
+
operator_short_form: "Translink Metro",
|
65
|
+
operator_legal_name: "Translink Metro"
|
66
|
+
}
|
67
|
+
)
|
67
68
|
end
|
68
69
|
|
69
70
|
it "should parse additional location information" do
|
70
|
-
expect
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
expect(Atco.parse_additional_location_info("QBN700000001252 328622 367433 \r\n")).to eq(
|
72
|
+
{
|
73
|
+
record_identity: "QB",
|
74
|
+
transaction_type: "N",
|
75
|
+
location: "700000001252",
|
76
|
+
grid_reference_easting: "328622",
|
77
|
+
grid_reference_northing: "367433"
|
78
|
+
}
|
79
|
+
)
|
77
80
|
end
|
78
81
|
|
79
82
|
it "should parse location" do
|
80
|
-
expect
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
expect(Atco.parse_location("QLN700000001252Conway (River Rd) 1\r\n")).to eq(
|
84
|
+
{
|
85
|
+
record_identity: "QL",
|
86
|
+
transaction_type: "N",
|
87
|
+
location: "700000001252",
|
88
|
+
full_location: "Conway (River Rd)",
|
89
|
+
gazetteer_code: "1"
|
90
|
+
}
|
91
|
+
)
|
87
92
|
end
|
88
93
|
|
89
94
|
# QT7000000012520605 T1F0
|
90
95
|
it "should parse destination" do
|
91
|
-
expect
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
expect(Atco.parse_destination("QT7000000012520605 T1F0\r\n")).to eq(
|
97
|
+
{
|
98
|
+
record_identity: "QT",
|
99
|
+
location: "700000001252",
|
100
|
+
published_arrival_time: "0605",
|
101
|
+
bay_number: "",
|
102
|
+
timing_point_indicator: "T1",
|
103
|
+
fare_stage_indicator: "F0"
|
104
|
+
}
|
105
|
+
)
|
99
106
|
end
|
100
107
|
|
101
108
|
it "should parse intermediate" do
|
102
|
-
expect
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
expect(Atco.parse_intermediate("QI70000000125607120712B T1F0\r\n")).to eq(
|
110
|
+
{
|
111
|
+
record_identity: "QI",
|
112
|
+
location: "700000001256",
|
113
|
+
published_arrival_time: "0712",
|
114
|
+
published_departure_time: "0712",
|
115
|
+
activity_flag: "B",
|
116
|
+
bay_number: "",
|
117
|
+
timing_point_indicator: "T1",
|
118
|
+
fare_stage_indicator: "F0"
|
119
|
+
}
|
120
|
+
)
|
112
121
|
end
|
113
122
|
|
114
123
|
it "should parse origin" do
|
115
|
-
expect
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
124
|
+
expect(Atco.parse_origin("QO7000000012520730 T1F0\r\n")).to eq(
|
125
|
+
{
|
126
|
+
record_identity: "QO",
|
127
|
+
location: "700000001252",
|
128
|
+
published_departure_time: "0730",
|
129
|
+
bay_number: "",
|
130
|
+
timing_point_indicator: "T1",
|
131
|
+
fare_stage_indicator: "F0"
|
132
|
+
}
|
133
|
+
)
|
123
134
|
end
|
124
135
|
|
125
136
|
it "should parse journey header" do
|
126
|
-
expect
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
137
|
+
expect(Atco.parse_journey_header("QSNTM 13986520091005 1111100 9A 9018 0 I\r\n")).to eq(
|
138
|
+
{
|
139
|
+
record_identity: "QS",
|
140
|
+
transaction_type: "N",
|
141
|
+
operator: "TM",
|
142
|
+
unique_journey_identifier: "139865",
|
143
|
+
first_date_of_operation: "20091005",
|
144
|
+
last_date_of_operation: "",
|
145
|
+
operates_on_mondays: "1",
|
146
|
+
operates_on_tuesdays: "1",
|
147
|
+
operates_on_wednesdays: "1",
|
148
|
+
operates_on_thursdays: "1",
|
149
|
+
operates_on_fridays: "1",
|
150
|
+
operates_on_saturdays: "0",
|
151
|
+
operates_on_sundays: "0",
|
152
|
+
school_term_time: "",
|
153
|
+
bank_holidays: "",
|
154
|
+
route_number: "9A",
|
155
|
+
running_board: "9018",
|
156
|
+
vehicle_type: "0",
|
157
|
+
registration_number: "",
|
158
|
+
route_direction: "I"
|
159
|
+
}
|
160
|
+
)
|
148
161
|
end
|
149
162
|
|
150
|
-
describe "with example.cif" do
|
163
|
+
describe "with example.cif" do # rubocop:disable Metrics/BlockLength
|
151
164
|
before(:all) do
|
152
165
|
@atco = Atco.parse("spec/fixtures/example.cif")
|
153
166
|
end
|
154
167
|
|
155
168
|
it "should parse 1 journey" do
|
156
|
-
expect
|
169
|
+
expect(@atco[:journeys].size).to eq(1)
|
157
170
|
end
|
158
171
|
|
159
172
|
it "should parse journeys into Atco::Joruney objects" do
|
160
173
|
expect(@atco[:journeys]["139748"]).to be_a_kind_of(Atco::Journey)
|
161
174
|
end
|
162
175
|
|
163
|
-
it "should parse 6 stops for
|
164
|
-
expect
|
176
|
+
it "should parse 6 stops for journey 139748" do
|
177
|
+
expect(@atco[:journeys]["139748"].stops.size).to eq(6)
|
165
178
|
end
|
166
179
|
|
167
|
-
it "should parse
|
168
|
-
expect
|
180
|
+
it "should parse 2 locations" do
|
181
|
+
expect(@atco[:locations].size).to eq(2)
|
169
182
|
end
|
170
183
|
|
171
|
-
it "should
|
172
|
-
|
184
|
+
it "should output file as JSON" do
|
185
|
+
output = File.join(File.dirname(__FILE__), "artefacts", "test.json")
|
186
|
+
File.open(output, "w+") do |f|
|
187
|
+
f.flush
|
188
|
+
f.write(JSON.pretty_generate(@atco))
|
189
|
+
end
|
190
|
+
|
191
|
+
expect(File.exist?(output)).to be true
|
192
|
+
|
193
|
+
data = File.read(output)
|
194
|
+
json = JSON.parse(data)
|
195
|
+
expect(json).to be_a(Hash)
|
173
196
|
end
|
197
|
+
|
198
|
+
it "should return 17 unparsed lines" do
|
199
|
+
expect(@atco[:unparsed].size).to eq(17)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should not parse GS records" do
|
203
|
+
expect(@atco[:unparsed][0]).to eq({
|
204
|
+
line: "GS00001433 N Belfast Metro Ops 7000\n",
|
205
|
+
line_number: 3
|
206
|
+
})
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should not parse GR records" do
|
210
|
+
expect(@atco[:unparsed][1]).to eq({
|
211
|
+
line: "GR00001433Donegall Square East 7000\n",
|
212
|
+
line_number: 4
|
213
|
+
})
|
214
|
+
end
|
215
|
+
|
174
216
|
end
|
175
217
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
require "rspec"
|
3
|
+
require "atco"
|
5
4
|
|
6
|
-
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# Enable flags like --only-failures and --next-failure
|
7
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
8
|
+
|
9
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
10
|
+
config.disable_monkey_patching!
|
11
|
+
|
12
|
+
config.expect_with :rspec do |c|
|
13
|
+
c.syntax = :expect
|
14
|
+
end
|
15
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atco
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Rice
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|