rail_feeds 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +26 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/Guardfile +25 -0
- data/LICENSE.md +32 -0
- data/README.md +77 -0
- data/Rakefile +3 -0
- data/doc/guides/Logging.md +13 -0
- data/doc/guides/Network Rail/CORPUS.md +34 -0
- data/doc/guides/Network Rail/SMART.md +39 -0
- data/doc/guides/Network Rail/Schedule.md +138 -0
- data/file +0 -0
- data/lib/rail_feeds/credentials.rb +45 -0
- data/lib/rail_feeds/logging.rb +51 -0
- data/lib/rail_feeds/network_rail/corpus.rb +77 -0
- data/lib/rail_feeds/network_rail/credentials.rb +22 -0
- data/lib/rail_feeds/network_rail/http_client.rb +57 -0
- data/lib/rail_feeds/network_rail/schedule/association.rb +208 -0
- data/lib/rail_feeds/network_rail/schedule/data.rb +215 -0
- data/lib/rail_feeds/network_rail/schedule/days.rb +95 -0
- data/lib/rail_feeds/network_rail/schedule/fetcher.rb +193 -0
- data/lib/rail_feeds/network_rail/schedule/header/cif.rb +102 -0
- data/lib/rail_feeds/network_rail/schedule/header/json.rb +79 -0
- data/lib/rail_feeds/network_rail/schedule/header.rb +22 -0
- data/lib/rail_feeds/network_rail/schedule/parser/cif.rb +141 -0
- data/lib/rail_feeds/network_rail/schedule/parser/json.rb +87 -0
- data/lib/rail_feeds/network_rail/schedule/parser.rb +108 -0
- data/lib/rail_feeds/network_rail/schedule/stp_indicator.rb +72 -0
- data/lib/rail_feeds/network_rail/schedule/tiploc.rb +100 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/change_en_route.rb +158 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location/intermediate.rb +119 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location/origin.rb +91 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location/terminating.rb +72 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location.rb +76 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule.rb +392 -0
- data/lib/rail_feeds/network_rail/schedule.rb +33 -0
- data/lib/rail_feeds/network_rail/smart.rb +186 -0
- data/lib/rail_feeds/network_rail/stomp_client.rb +77 -0
- data/lib/rail_feeds/network_rail.rb +16 -0
- data/lib/rail_feeds/version.rb +14 -0
- data/lib/rail_feeds.rb +10 -0
- data/rail_feeds.gemspec +32 -0
- data/spec/fixtures/network_rail/schedule/data/full.yaml +60 -0
- data/spec/fixtures/network_rail/schedule/data/starting.yaml +131 -0
- data/spec/fixtures/network_rail/schedule/data/update-gap.yaml +10 -0
- data/spec/fixtures/network_rail/schedule/data/update-next.yaml +13 -0
- data/spec/fixtures/network_rail/schedule/data/update-old.yaml +10 -0
- data/spec/fixtures/network_rail/schedule/data/update.yaml +112 -0
- data/spec/fixtures/network_rail/schedule/parser/train_create.json +1 -0
- data/spec/fixtures/network_rail/schedule/parser/train_delete.json +1 -0
- data/spec/fixtures/network_rail/schedule/train_schedule/json-data.yaml +67 -0
- data/spec/rail_feeds/credentials_spec.rb +46 -0
- data/spec/rail_feeds/logging_spec.rb +81 -0
- data/spec/rail_feeds/network_rail/corpus_spec.rb +92 -0
- data/spec/rail_feeds/network_rail/credentials_spec.rb +22 -0
- data/spec/rail_feeds/network_rail/http_client_spec.rb +88 -0
- data/spec/rail_feeds/network_rail/schedule/association_spec.rb +205 -0
- data/spec/rail_feeds/network_rail/schedule/data_spec.rb +219 -0
- data/spec/rail_feeds/network_rail/schedule/days_shared.rb +99 -0
- data/spec/rail_feeds/network_rail/schedule/days_spec.rb +4 -0
- data/spec/rail_feeds/network_rail/schedule/fetcher_spec.rb +228 -0
- data/spec/rail_feeds/network_rail/schedule/header/cif_spec.rb +72 -0
- data/spec/rail_feeds/network_rail/schedule/header/json_spec.rb +51 -0
- data/spec/rail_feeds/network_rail/schedule/header_spec.rb +19 -0
- data/spec/rail_feeds/network_rail/schedule/parser/cif_spec.rb +197 -0
- data/spec/rail_feeds/network_rail/schedule/parser/json_spec.rb +172 -0
- data/spec/rail_feeds/network_rail/schedule/parser_spec.rb +34 -0
- data/spec/rail_feeds/network_rail/schedule/stp_indicator_shared.rb +49 -0
- data/spec/rail_feeds/network_rail/schedule/stp_indicator_spec.rb +4 -0
- data/spec/rail_feeds/network_rail/schedule/tiploc_spec.rb +77 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/change_en_route_spec.rb +121 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location/intermediate_spec.rb +95 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location/origin_spec.rb +87 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location/terminating_spec.rb +81 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location_spec.rb +35 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule_spec.rb +284 -0
- data/spec/rail_feeds/network_rail/schedule_spec.rb +41 -0
- data/spec/rail_feeds/network_rail/smart_spec.rb +194 -0
- data/spec/rail_feeds/network_rail/stomp_client_spec.rb +151 -0
- data/spec/rail_feeds/network_rail_spec.rb +7 -0
- data/spec/rail_feeds_spec.rb +11 -0
- data/spec/spec_helper.rb +47 -0
- metadata +282 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Intermediate do
|
4
|
+
subject { described_class.new tiploc: 'ccccccc', tiploc_suffix: 3 }
|
5
|
+
let(:line) do
|
6
|
+
'LIttttttt1aaaaadddddpppppAAAADDDDPlaLinPataaaaaaaaaaaa123456 '
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '::from_cif' do
|
10
|
+
it 'Sets attributes' do
|
11
|
+
subject = described_class.from_cif line
|
12
|
+
|
13
|
+
expect(subject.tiploc).to eq 'ttttttt'
|
14
|
+
expect(subject.tiploc_suffix).to eq 1
|
15
|
+
expect(subject.scheduled_arrival).to eq 'aaaaa'
|
16
|
+
expect(subject.scheduled_departure).to eq 'ddddd'
|
17
|
+
expect(subject.scheduled_pass).to eq 'ppppp'
|
18
|
+
expect(subject.public_arrival).to eq 'AAAA'
|
19
|
+
expect(subject.public_departure).to eq 'DDDD'
|
20
|
+
expect(subject.platform).to eq 'Pla'
|
21
|
+
expect(subject.line).to eq 'Lin'
|
22
|
+
expect(subject.path).to eq 'Pat'
|
23
|
+
expect(subject.activity).to eq 'aaaaaaaaaaaa'
|
24
|
+
expect(subject.engineering_allowance).to eq 12.0
|
25
|
+
expect(subject.pathing_allowance).to eq 34.0
|
26
|
+
expect(subject.performance_allowance).to eq 56.0
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'Fails for invalid line' do
|
30
|
+
expect { described_class.from_cif('bad line') }
|
31
|
+
.to raise_error ArgumentError, "Invalid line:\nbad line"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it '#to_cif' do
|
36
|
+
subject = described_class.from_cif line
|
37
|
+
expect(subject.to_cif).to eq "#{line}\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
it '#to_hash_for_json' do
|
41
|
+
subject = described_class.from_cif line
|
42
|
+
expect(subject.to_hash_for_json).to eq(
|
43
|
+
location_type: 'LI',
|
44
|
+
record_identity: 'LI',
|
45
|
+
tiploc_code: 'ttttttt',
|
46
|
+
tiploc_instance: 1,
|
47
|
+
arrival: 'aaaaa',
|
48
|
+
departure: 'ddddd',
|
49
|
+
pass: 'ppppp',
|
50
|
+
public_arrival: 'AAAA',
|
51
|
+
public_departure: 'DDDD',
|
52
|
+
platform: 'Pla',
|
53
|
+
line: 'Lin',
|
54
|
+
path: 'Pat',
|
55
|
+
engineering_allowance: '12',
|
56
|
+
pathing_allowance: '34',
|
57
|
+
performance_allowance: '56'
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#hash' do
|
62
|
+
it 'Uses tiploc and tiploc_suffix' do
|
63
|
+
expect(subject.hash).to eq 'ccccccc-3'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#==' do
|
68
|
+
let(:location1) { described_class.new tiploc: 'a', tiploc_suffix: 1 }
|
69
|
+
let(:location2) { described_class.new tiploc: 'a', tiploc_suffix: 1 }
|
70
|
+
|
71
|
+
it 'Neither tiploc or tiploc_suffix match' do
|
72
|
+
location1.tiploc = 'b'
|
73
|
+
location1.tiploc_suffix = 2
|
74
|
+
expect(location1).to_not eq location2
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'Tiploc matches but tiploc_suffix doesn\'t' do
|
78
|
+
location1.tiploc_suffix = 2
|
79
|
+
expect(location1).to_not eq location2
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'Tiploc_suffix matches but tiploc doesn\'t' do
|
83
|
+
location1.tiploc = 'b'
|
84
|
+
expect(location1).to_not eq location2
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'Both tiploc and tiploc_suffix match' do
|
88
|
+
expect(location1).to eq location2
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'Compares to nil without error' do
|
92
|
+
expect(location1).to_not eq nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Origin do
|
4
|
+
subject { described_class.new tiploc: 'aaaaaaa', tiploc_suffix: 1 }
|
5
|
+
let(:line) do
|
6
|
+
'LOttttttt1dddddDDDDPlaLin2H3 aaaaaaaaaaaa45 '
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '::from_cif' do
|
10
|
+
it 'Sets attributes' do
|
11
|
+
subject = described_class.from_cif line
|
12
|
+
|
13
|
+
expect(subject.tiploc).to eq 'ttttttt'
|
14
|
+
expect(subject.tiploc_suffix).to eq 1
|
15
|
+
expect(subject.scheduled_departure).to eq 'ddddd'
|
16
|
+
expect(subject.public_departure).to eq 'DDDD'
|
17
|
+
expect(subject.platform).to eq 'Pla'
|
18
|
+
expect(subject.line).to eq 'Lin'
|
19
|
+
expect(subject.engineering_allowance).to eq 2.5
|
20
|
+
expect(subject.pathing_allowance).to eq 3.0
|
21
|
+
expect(subject.activity).to eq 'aaaaaaaaaaaa'
|
22
|
+
expect(subject.performance_allowance).to eq 45.0
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'Fails for invalid line' do
|
26
|
+
expect { described_class.from_cif('bad line') }
|
27
|
+
.to raise_error ArgumentError, "Invalid line:\nbad line"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it '#to_cif' do
|
32
|
+
subject = described_class.from_cif line
|
33
|
+
expect(subject.to_cif).to eq "#{line}\n"
|
34
|
+
end
|
35
|
+
|
36
|
+
it '#to_hash_for_json' do
|
37
|
+
subject = described_class.from_cif line
|
38
|
+
expect(subject.to_hash_for_json).to eq(
|
39
|
+
location_type: 'LO',
|
40
|
+
record_identity: 'LO',
|
41
|
+
tiploc_code: 'ttttttt',
|
42
|
+
tiploc_instance: 1,
|
43
|
+
departure: 'ddddd',
|
44
|
+
public_departure: 'DDDD',
|
45
|
+
platform: 'Pla',
|
46
|
+
line: 'Lin',
|
47
|
+
engineering_allowance: '2H',
|
48
|
+
pathing_allowance: '3',
|
49
|
+
performance_allowance: '45'
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#hash' do
|
54
|
+
it 'Uses tiploc and tiploc_suffix' do
|
55
|
+
expect(subject.hash).to eq 'aaaaaaa-1'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '#==' do
|
60
|
+
let(:location1) { described_class.new tiploc: 'a', tiploc_suffix: 1 }
|
61
|
+
let(:location2) { described_class.new tiploc: 'a', tiploc_suffix: 1 }
|
62
|
+
|
63
|
+
it 'Neither tiploc or tiploc_suffix match' do
|
64
|
+
location1.tiploc = 'b'
|
65
|
+
location1.tiploc_suffix = 2
|
66
|
+
expect(location1).to_not eq location2
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'Tiploc matches but tiploc_suffix doesn\'t' do
|
70
|
+
location1.tiploc_suffix = 2
|
71
|
+
expect(location1).to_not eq location2
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'Tiploc_suffix matches but tiploc doesn\'t' do
|
75
|
+
location1.tiploc = 'b'
|
76
|
+
expect(location1).to_not eq location2
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'Both tiploc and tiploc_suffix match' do
|
80
|
+
expect(location1).to eq location2
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'Compares to nil without error' do
|
84
|
+
expect(location1).to_not eq nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Terminating do
|
4
|
+
subject { described_class.new tiploc: 'bbbbbbb', tiploc_suffix: 2 }
|
5
|
+
let(:line) do
|
6
|
+
'LTttttttt1aaaaaAAAAPlaPataaaaaaaaaaaa '
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '::from_cif' do
|
10
|
+
it 'Sets attributes' do
|
11
|
+
subject = described_class.from_cif line
|
12
|
+
|
13
|
+
expect(subject.tiploc).to eq 'ttttttt'
|
14
|
+
expect(subject.tiploc_suffix).to eq 1
|
15
|
+
expect(subject.scheduled_arrival).to eq 'aaaaa'
|
16
|
+
expect(subject.public_arrival).to eq 'AAAA'
|
17
|
+
expect(subject.platform).to eq 'Pla'
|
18
|
+
expect(subject.path).to eq 'Pat'
|
19
|
+
expect(subject.activity).to eq 'aaaaaaaaaaaa'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'Fails for invalid line' do
|
23
|
+
expect { described_class.from_cif('bad line') }
|
24
|
+
.to raise_error ArgumentError, "Invalid line:\nbad line"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it '#to_cif' do
|
29
|
+
subject = described_class.from_cif line
|
30
|
+
expect(subject.to_cif).to eq "#{line}\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
it '#to_hash_for_json' do
|
34
|
+
subject = described_class.from_cif line
|
35
|
+
expect(subject.to_hash_for_json).to eq(
|
36
|
+
location_type: 'LT',
|
37
|
+
record_identity: 'LT',
|
38
|
+
tiploc_code: 'ttttttt',
|
39
|
+
tiploc_instance: 1,
|
40
|
+
arrival: 'aaaaa',
|
41
|
+
public_arrival: 'AAAA',
|
42
|
+
platform: 'Pla',
|
43
|
+
path: 'Pat'
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#hash' do
|
48
|
+
it 'Uses tiploc and tiploc_suffix' do
|
49
|
+
expect(subject.hash).to eq 'bbbbbbb-2'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#==' do
|
54
|
+
let(:location1) { described_class.new tiploc: 'a', tiploc_suffix: 1 }
|
55
|
+
let(:location2) { described_class.new tiploc: 'a', tiploc_suffix: 1 }
|
56
|
+
|
57
|
+
it 'Neither tiploc or tiploc_suffix match' do
|
58
|
+
location1.tiploc = 'b'
|
59
|
+
location1.tiploc_suffix = 2
|
60
|
+
expect(location1).to_not eq location2
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'Tiploc matches but tiploc_suffix doesn\'t' do
|
64
|
+
location1.tiploc_suffix = 2
|
65
|
+
expect(location1).to_not eq location2
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'Tiploc_suffix matches but tiploc doesn\'t' do
|
69
|
+
location1.tiploc = 'b'
|
70
|
+
expect(location1).to_not eq location2
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'Both tiploc and tiploc_suffix match' do
|
74
|
+
expect(location1).to eq location2
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'Compares to nil without error' do
|
78
|
+
expect(location1).to_not eq nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RailFeeds::NetworkRail::Schedule::TrainSchedule::Location do
|
4
|
+
it 'Can\'t be instantiated' do
|
5
|
+
expect { described_class.new }.to raise_error RuntimeError, 'This class should never be instantiated'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'Make relevant location type from line' do
|
9
|
+
it 'Origin' do
|
10
|
+
line = 'LO'
|
11
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Origin)
|
12
|
+
.to receive(:from_cif).with(line).and_return(:location)
|
13
|
+
expect(described_class.from_cif(line)).to eq :location
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'Intermediate' do
|
17
|
+
line = 'LI'
|
18
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Intermediate)
|
19
|
+
.to receive(:from_cif).with(line).and_return(:location)
|
20
|
+
expect(described_class.from_cif(line)).to eq :location
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'Terminating' do
|
24
|
+
line = 'LT'
|
25
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Terminating)
|
26
|
+
.to receive(:from_cif).with(line).and_return(:location)
|
27
|
+
expect(described_class.from_cif(line)).to eq :location
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'Fails on bad line' do
|
31
|
+
line = 'bad_line'
|
32
|
+
expect { described_class.from_cif(line) }.to raise_error ArgumentError, 'Improper line type ba: bad_line'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,284 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RailFeeds::NetworkRail::Schedule::TrainSchedule do
|
4
|
+
let(:line_basic) do
|
5
|
+
'BSNa123450102030405061010101bscciiii2222111111111 PPPtttt333ooooooSFR catebran P'
|
6
|
+
end
|
7
|
+
let(:line_extra) do
|
8
|
+
'BX 11111TTY '
|
9
|
+
end
|
10
|
+
let :json do
|
11
|
+
file = File.join RSPEC_FIXTURES, 'network_rail', 'schedule', 'train_schedule', 'json-data.yaml'
|
12
|
+
YAML.load(File.read(file)).to_json
|
13
|
+
end
|
14
|
+
|
15
|
+
subject do
|
16
|
+
described_class.new(
|
17
|
+
uid: 'a12345',
|
18
|
+
start_date: Date.new(2001, 2, 3),
|
19
|
+
end_date: Date.new(2004, 5, 6),
|
20
|
+
days: [true, false, true, false, true, false, true],
|
21
|
+
bank_holiday_running: 'b',
|
22
|
+
status: 's',
|
23
|
+
category: 'cc',
|
24
|
+
signalling_headcode: 'iiii',
|
25
|
+
reservation_headcode: 2222,
|
26
|
+
service_code: 11111111,
|
27
|
+
power_type: 'PPP',
|
28
|
+
timing_load: 'tttt',
|
29
|
+
speed: 333,
|
30
|
+
operating_characteristics: 'oooooo',
|
31
|
+
seating_class: 'S',
|
32
|
+
sleeping_class: 'F',
|
33
|
+
reservations: 'R',
|
34
|
+
catering: 'cate',
|
35
|
+
branding: 'bran',
|
36
|
+
stp_indicator: :permanent,
|
37
|
+
uic: 11111,
|
38
|
+
atoc: 'TT',
|
39
|
+
applicable_timetable: true
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
it '::from_json' do
|
44
|
+
subject = described_class.from_json json
|
45
|
+
expect(subject.uid).to eq 'W20309'
|
46
|
+
expect(subject.category).to eq 'OO'
|
47
|
+
expect(subject.status).to eq 'S'
|
48
|
+
expect(subject.reservation_headcode).to eq 1234
|
49
|
+
expect(subject.signalling_headcode).to eq '2U10'
|
50
|
+
expect(subject.service_code).to eq '24627006'
|
51
|
+
expect(subject.start_date).to eq Date.new(2018, 5, 21)
|
52
|
+
expect(subject.end_date).to eq Date.new(2018, 12, 7)
|
53
|
+
expect(subject.days).to eq [true, true, true, true, true, false, false]
|
54
|
+
expect(subject.bank_holiday_running).to eq 'B'
|
55
|
+
expect(subject.power_type).to eq 'EMU'
|
56
|
+
expect(subject.timing_load).to eq '483'
|
57
|
+
expect(subject.speed).to eq 45
|
58
|
+
expect(subject.operating_characteristics).to eq 'OPER-CHAR'
|
59
|
+
expect(subject.seating_class).to eq 'S'
|
60
|
+
expect(subject.sleeping_class).to eq 'B'
|
61
|
+
expect(subject.reservations).to eq 'R'
|
62
|
+
expect(subject.catering).to eq 'C'
|
63
|
+
expect(subject.branding).to eq 'Br'
|
64
|
+
expect(subject.uic).to eq 12345
|
65
|
+
expect(subject.atoc).to eq 'IL'
|
66
|
+
expect(subject.applicable_timetable).to eq true
|
67
|
+
expect(subject.stp_indicator).to eq :permanent
|
68
|
+
expect(subject.journey.size).to eq 3
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#update_from_line' do
|
72
|
+
it 'Standard information' do
|
73
|
+
subject.update_from_cif line_basic
|
74
|
+
expect(subject.uid).to eq 'a12345'
|
75
|
+
expect(subject.start_date).to eq Date.new(2001, 2, 3)
|
76
|
+
expect(subject.end_date).to eq Date.new(2004, 5, 6)
|
77
|
+
expect(subject.days).to eq [true, false, true, false, true, false, true]
|
78
|
+
expect(subject.bank_holiday_running).to eq 'b'
|
79
|
+
expect(subject.status).to eq 's'
|
80
|
+
expect(subject.category).to eq 'cc'
|
81
|
+
expect(subject.signalling_headcode).to eq 'iiii'
|
82
|
+
expect(subject.reservation_headcode).to eq 2222
|
83
|
+
expect(subject.service_code).to eq 11111111
|
84
|
+
expect(subject.power_type).to eq 'PPP'
|
85
|
+
expect(subject.timing_load).to eq 'tttt'
|
86
|
+
expect(subject.speed).to eq 333
|
87
|
+
expect(subject.operating_characteristics).to eq 'oooooo'
|
88
|
+
expect(subject.seating_class).to eq 'S'
|
89
|
+
expect(subject.sleeping_class).to eq 'F'
|
90
|
+
expect(subject.reservations).to eq 'R'
|
91
|
+
expect(subject.catering).to eq 'cate'
|
92
|
+
expect(subject.branding).to eq 'bran'
|
93
|
+
expect(subject.stp_indicator).to eq :permanent
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'Extra information' do
|
97
|
+
subject.update_from_cif line_extra
|
98
|
+
expect(subject.uic).to eq 11111
|
99
|
+
expect(subject.atoc).to eq 'TT'
|
100
|
+
expect(subject.applicable_timetable).to eq true
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'Origin location' do
|
104
|
+
line = 'LO'
|
105
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
106
|
+
.to receive(:from_cif).with(line).and_return(:origin)
|
107
|
+
subject.update_from_cif line
|
108
|
+
expect(subject.journey).to eq [:origin]
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'Intermediate location' do
|
112
|
+
line = 'LI'
|
113
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
114
|
+
.to receive(:from_cif).with(line).and_return(:intermediate)
|
115
|
+
subject.update_from_cif line
|
116
|
+
expect(subject.journey).to eq [:intermediate]
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'Terminating location' do
|
120
|
+
line = 'LT'
|
121
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
122
|
+
.to receive(:from_cif).with(line).and_return(:terminating)
|
123
|
+
subject.update_from_cif line
|
124
|
+
expect(subject.journey).to eq [:terminating]
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'Series of locations' do
|
128
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
129
|
+
.to receive(:from_cif).with('LO').and_return(:origin)
|
130
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
131
|
+
.to receive(:from_cif).with('LI').and_return(:intermediate)
|
132
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
133
|
+
.to receive(:from_cif).with('LT').and_return(:terminating)
|
134
|
+
subject.update_from_cif 'LO'
|
135
|
+
subject.update_from_cif 'LI'
|
136
|
+
subject.update_from_cif 'LT'
|
137
|
+
expect(subject.journey).to eq %i[origin intermediate terminating]
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'Change en route' do
|
141
|
+
line = 'CR'
|
142
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::ChangeEnRoute)
|
143
|
+
.to receive(:from_cif).with(line).and_return(:change)
|
144
|
+
subject.update_from_cif line
|
145
|
+
expect(subject.journey).to eq [:change]
|
146
|
+
end
|
147
|
+
|
148
|
+
it '#journey contains locations and change en routes' do
|
149
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
150
|
+
.to receive(:from_cif).with('LO').and_return(:origin)
|
151
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
152
|
+
.to receive(:from_cif).with('LI').and_return(:intermediate)
|
153
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::Location)
|
154
|
+
.to receive(:from_cif).with('LT').and_return(:terminating)
|
155
|
+
expect(RailFeeds::NetworkRail::Schedule::TrainSchedule::ChangeEnRoute)
|
156
|
+
.to receive(:from_cif).with('CR').and_return(:change)
|
157
|
+
subject.update_from_cif 'LO'
|
158
|
+
subject.update_from_cif 'CR'
|
159
|
+
subject.update_from_cif 'LI'
|
160
|
+
subject.update_from_cif 'LT'
|
161
|
+
expect(subject.journey).to eq %i[origin change intermediate terminating]
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'Fails on bad line' do
|
165
|
+
line = 'bad line'
|
166
|
+
expect { subject.update_from_cif line }
|
167
|
+
.to raise_error ArgumentError, 'Improper line type ba: bad line'
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'Delete line' do
|
171
|
+
line = 'BSDC77714180526 P'
|
172
|
+
subject.update_from_cif line
|
173
|
+
expect(subject.uid).to eq 'C77714'
|
174
|
+
expect(subject.start_date).to eq Date.new(2018, 5, 26)
|
175
|
+
expect(subject.end_date).to be_nil
|
176
|
+
expect(subject.days).to eq [false, false, false, false, false, false, false]
|
177
|
+
expect(subject.bank_holiday_running).to be_nil
|
178
|
+
expect(subject.status).to be_nil
|
179
|
+
expect(subject.category).to be_nil
|
180
|
+
expect(subject.signalling_headcode).to be_nil
|
181
|
+
expect(subject.reservation_headcode).to be_nil
|
182
|
+
expect(subject.service_code).to be_nil
|
183
|
+
expect(subject.power_type).to be_nil
|
184
|
+
expect(subject.timing_load).to be_nil
|
185
|
+
expect(subject.speed).to be_nil
|
186
|
+
expect(subject.operating_characteristics).to be_nil
|
187
|
+
expect(subject.seating_class).to be_nil
|
188
|
+
expect(subject.sleeping_class).to be_nil
|
189
|
+
expect(subject.reservations).to be_nil
|
190
|
+
expect(subject.catering).to be_nil
|
191
|
+
expect(subject.branding).to be_nil
|
192
|
+
expect(subject.stp_indicator).to eq :permanent
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
it '#to_cif' do
|
197
|
+
origin = double RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Origin
|
198
|
+
change = double RailFeeds::NetworkRail::Schedule::TrainSchedule::ChangeEnRoute
|
199
|
+
intermediate = double RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Intermediate
|
200
|
+
terminating = double RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Terminating
|
201
|
+
subject.journey = [origin, change, intermediate, terminating]
|
202
|
+
|
203
|
+
expect(origin).to receive(:to_cif).and_return("origin\n")
|
204
|
+
expect(change).to receive(:to_cif).and_return("change\n")
|
205
|
+
expect(intermediate).to receive(:to_cif).and_return("intermediate\n")
|
206
|
+
expect(terminating).to receive(:to_cif).and_return("terminating\n")
|
207
|
+
|
208
|
+
expect(subject.to_cif).to eq [
|
209
|
+
line_basic,
|
210
|
+
line_extra,
|
211
|
+
'origin',
|
212
|
+
'change',
|
213
|
+
'intermediate',
|
214
|
+
'terminating'
|
215
|
+
].map { |i| "#{i}\n" }.join
|
216
|
+
end
|
217
|
+
|
218
|
+
it '#to_json' do
|
219
|
+
subject = described_class.from_json json
|
220
|
+
expect(subject.to_json).to eq json
|
221
|
+
end
|
222
|
+
|
223
|
+
describe '#<=>' do
|
224
|
+
# By start daste then uid
|
225
|
+
let(:train1) { described_class.new start_date: Date.new(2000, 1, 1), uid: 9999 }
|
226
|
+
let(:train2) { described_class.new start_date: Date.new(2000, 1, 2), uid: 1000 }
|
227
|
+
let(:train3) { described_class.new start_date: Date.new(2000, 1, 2), uid: 2000 }
|
228
|
+
|
229
|
+
it 'Match' do
|
230
|
+
train1a = described_class.new start_date: Date.new(2000, 1, 1), uid: 9999
|
231
|
+
expect(train1 <=> train1a).to eq 0
|
232
|
+
expect(train1a <=> train1).to eq 0
|
233
|
+
end
|
234
|
+
|
235
|
+
it 'Doesn\'t match' do
|
236
|
+
expect(train1 <=> train2).to eq(-1)
|
237
|
+
expect(train1 <=> train3).to eq(-1)
|
238
|
+
expect(train2 <=> train1).to eq 1
|
239
|
+
expect(train2 <=> train3).to eq(-1)
|
240
|
+
expect(train3 <=> train1).to eq 1
|
241
|
+
expect(train3 <=> train2).to eq 1
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'Compares to nil without error' do
|
245
|
+
expect { train1 <=> nil }.to_not raise_error
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe '#==' do
|
250
|
+
let(:train1) { described_class.new }
|
251
|
+
let(:train2) { described_class.new }
|
252
|
+
before :each do
|
253
|
+
train1.uid = train2.uid = 'a01234'
|
254
|
+
train1.start_date = train2.start_date = Date.new(1, 2, 3)
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'Matches on neither :uid or :start_date' do
|
258
|
+
train1.uid = nil
|
259
|
+
train1.start_date = nil
|
260
|
+
expect(train1).to_not eq train2
|
261
|
+
end
|
262
|
+
|
263
|
+
it 'Matches on :uid only' do
|
264
|
+
train1.start_date = nil
|
265
|
+
expect(train1).to_not eq train2
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'Matches on :start_date only' do
|
269
|
+
train1.uid = nil
|
270
|
+
expect(train1).to_not eq train2
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'Matches on both :uid or :start_date' do
|
274
|
+
expect(train1).to eq train2
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'Compares to nil without error' do
|
278
|
+
expect(train1).to_not eq nil
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
it_behaves_like 'it has an STP indicator'
|
283
|
+
it_behaves_like 'it has a days array'
|
284
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe RailFeeds::NetworkRail::Schedule do
|
4
|
+
describe '::nil_or_i' do
|
5
|
+
it 'Empty value' do
|
6
|
+
expect(described_class.nil_or_i(' ')).to be_nil
|
7
|
+
end
|
8
|
+
it 'Nonempty value' do
|
9
|
+
expect(described_class.nil_or_i(' 1 ')).to eq 1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '::nil_or_strip' do
|
14
|
+
it 'Empty value' do
|
15
|
+
expect(described_class.nil_or_strip(' ')).to be_nil
|
16
|
+
end
|
17
|
+
it 'Nonempty value' do
|
18
|
+
expect(described_class.nil_or_strip(' 1 ')).to eq '1'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '::make_date' do
|
23
|
+
context 'Empty value' do
|
24
|
+
it 'Empty values not allowed' do
|
25
|
+
expect { described_class.make_date(' ') }.to raise_error ArgumentError
|
26
|
+
end
|
27
|
+
it 'Empty values allowed' do
|
28
|
+
expect(described_class.make_date(' ', allow_nil: true)).to be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'Nonempty value' do
|
33
|
+
it 'Normal date' do
|
34
|
+
expect(described_class.make_date('050607')).to eq Date.new(2005, 6, 7)
|
35
|
+
end
|
36
|
+
it '999999' do
|
37
|
+
expect(described_class.make_date('999999')).to eq Date.new(9999, 12, 31)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|