Skip to content

Commit b3b3430

Browse files
committed
#355 Fix OSI link of MTR style terminal stations
1 parent e37653f commit b3b3430

File tree

2 files changed

+179
-39
lines changed

2 files changed

+179
-39
lines changed

src/svgs/mtr/station-icon.test.tsx

Lines changed: 158 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,177 @@ import { screen } from '@testing-library/react';
33
import StationIcon from './station-icon';
44
import { render } from '../../test-utils';
55

6+
const setup = (within: number, outStation: number, isTerminal: boolean = false) =>
7+
render(
8+
<svg>
9+
<StationIcon
10+
withinTransfer={within}
11+
outStationTransfer={outStation}
12+
isTerminal={isTerminal}
13+
isPassed={false}
14+
/>
15+
</svg>
16+
);
17+
618
describe('MTR StationIcon', () => {
19+
describe('MTR StationIcon - OSI link', () => {
20+
const osiLinkSelector = 'path[stroke-width="2.69"]';
21+
22+
it('Can render OSI link for 0-1 station as expected', () => {
23+
setup(0, 1, false);
24+
const wrapper = screen.getByTestId('station-icon-wrapper');
25+
expect(wrapper.querySelector(osiLinkSelector)?.getAttribute('d')).toContain('V26');
26+
});
27+
28+
it('Can render OSI link for 0-2 station as expected', () => {
29+
setup(0, 2, false);
30+
const wrapper = screen.getByTestId('station-icon-wrapper');
31+
expect(wrapper.querySelector(osiLinkSelector)?.getAttribute('d')).toContain('V26');
32+
});
33+
34+
it('Can render OSI link for 0-1 terminal station as expected', () => {
35+
setup(0, 1, true);
36+
const wrapper = screen.getByTestId('station-icon-wrapper');
37+
expect(wrapper.querySelector(osiLinkSelector)?.getAttribute('d')).toContain('V26');
38+
});
39+
40+
it('Can render OSI link for 0-2 terminal station as expected', () => {
41+
setup(0, 2, true);
42+
const wrapper = screen.getByTestId('station-icon-wrapper');
43+
expect(wrapper.querySelector(osiLinkSelector)?.getAttribute('d')).toContain('V26');
44+
});
45+
46+
it('Can render OSI link for 1-1 terminal station as expected', () => {
47+
setup(1, 1, true);
48+
const wrapper = screen.getByTestId('station-icon-wrapper');
49+
expect(wrapper.querySelector(osiLinkSelector)?.getAttribute('d')).toContain('H41');
50+
});
51+
52+
it('Can render OSI link for 1-2 terminal station as expected', () => {
53+
setup(1, 2, true);
54+
const wrapper = screen.getByTestId('station-icon-wrapper');
55+
expect(wrapper.querySelector(osiLinkSelector)?.getAttribute('d')).toContain('H41');
56+
});
57+
});
58+
759
it('Can draw circle for station with 1 within station interchange as expected', () => {
8-
render(
9-
<svg>
10-
<StationIcon withinTransfer={1} outStationTransfer={0} isPassed={false} />
11-
</svg>
12-
);
60+
setup(1, 0);
1361

1462
const wrapper = screen.getByTestId('station-icon-wrapper');
15-
expect(wrapper.children).toHaveLength(1);
16-
expect(screen.getByTestId('station-icon-wrapper').querySelector('circle')).toBeInTheDocument();
63+
expect(wrapper.querySelectorAll('path')).toHaveLength(1);
1764
});
1865

1966
it('Can draw pill for station with 3 within station interchange as expected', () => {
20-
render(
21-
<svg>
22-
<StationIcon withinTransfer={3} outStationTransfer={0} isPassed={false} />
23-
</svg>
24-
);
67+
setup(3, 0);
2568

2669
const wrapper = screen.getByTestId('station-icon-wrapper');
27-
expect(wrapper.children).toHaveLength(1);
28-
expect(screen.getByTestId('station-icon-wrapper').querySelector('path')).toBeInTheDocument();
70+
expect(wrapper.querySelectorAll('path')).toHaveLength(1);
2971
});
3072

3173
it('Can draw circle for station with 1 out of station interchange as expected', () => {
32-
render(
33-
<svg>
34-
<StationIcon withinTransfer={0} outStationTransfer={1} isPassed={false} />
35-
</svg>
36-
);
74+
setup(0, 1);
3775

3876
const wrapper = screen.getByTestId('station-icon-wrapper');
39-
expect(wrapper.children).toHaveLength(3);
40-
expect(screen.getByTestId('station-icon-wrapper').querySelectorAll('circle')).toHaveLength(2);
77+
expect(wrapper.querySelectorAll('path')).toHaveLength(3);
78+
});
79+
80+
describe('MTR StationIcon - OSI Icon', () => {
81+
const osiIconSelector = 'path:last-of-type';
82+
83+
it('Can render OSI icon for 0-1 station as expected', () => {
84+
setup(0, 1, false);
85+
const [x, y, , scaleY] = screen
86+
.getByTestId('station-icon-wrapper')
87+
.querySelector(osiIconSelector)
88+
?.getAttribute('transform')
89+
?.match(/-?\d+/g)!;
90+
expect(x).toBe('0');
91+
expect(y).toBe('26');
92+
expect(scaleY).toBe('1');
93+
});
94+
95+
it('Can render OSI icon for 0-2 station as expected', () => {
96+
setup(0, 2, false);
97+
const [x, y, , scaleY] = screen
98+
.getByTestId('station-icon-wrapper')
99+
.querySelector(osiIconSelector)
100+
?.getAttribute('transform')
101+
?.match(/-?\d+/g)!;
102+
expect(x).toBe('0');
103+
expect(y).toBe('26');
104+
expect(scaleY).toBe('1');
105+
});
106+
107+
it('Can render OSI icon for 0-1 terminal station as expected', () => {
108+
setup(0, 1, true);
109+
const [x, y, , scaleY] = screen
110+
.getByTestId('station-icon-wrapper')
111+
.querySelector(osiIconSelector)
112+
?.getAttribute('transform')
113+
?.match(/-?\d+/g)!;
114+
expect(x).toBe('0');
115+
expect(y).toBe('26');
116+
expect(scaleY).toBe('1');
117+
});
118+
119+
it('Can render OSI icon for 0-2 terminal station as expected', () => {
120+
setup(0, 2, true);
121+
const [x, y, , scaleY] = screen
122+
.getByTestId('station-icon-wrapper')
123+
.querySelector(osiIconSelector)
124+
?.getAttribute('transform')
125+
?.match(/-?\d+/g)!;
126+
expect(x).toBe('0');
127+
expect(y).toBe('26');
128+
expect(scaleY).toBe('1');
129+
});
130+
131+
it('Can render OSI icon for 1-1 station as expected', () => {
132+
setup(1, 1, false);
133+
const [x, y, , scaleY] = screen
134+
.getByTestId('station-icon-wrapper')
135+
.querySelector(osiIconSelector)
136+
?.getAttribute('transform')
137+
?.match(/-?\d+/g)!;
138+
expect(x).toBe('0');
139+
expect(y).toBe('26');
140+
expect(scaleY).toBe('1');
141+
});
142+
143+
it('Can render OSI icon for 1-2 station as expected', () => {
144+
setup(1, 2, false);
145+
const [x, y, , scaleY] = screen
146+
.getByTestId('station-icon-wrapper')
147+
.querySelector(osiIconSelector)
148+
?.getAttribute('transform')
149+
?.match(/-?\d+/g)!;
150+
expect(x).toBe('0');
151+
expect(y).toBe('26');
152+
expect(scaleY).toBe('1');
153+
});
154+
155+
it('Can render OSI icon for 1-1 terminal station as expected', () => {
156+
setup(1, 1, true);
157+
const [x, y, , scaleY] = screen
158+
.getByTestId('station-icon-wrapper')
159+
.querySelector(osiIconSelector)
160+
?.getAttribute('transform')
161+
?.match(/-?\d+/g)!;
162+
expect(x).toBe('41');
163+
expect(y).toBe('0');
164+
expect(scaleY).toBe('-1');
165+
});
166+
167+
it('Can render OSI icon for 1-2 terminal station as expected', () => {
168+
setup(1, 2, true);
169+
const [x, y, , scaleY] = screen
170+
.getByTestId('station-icon-wrapper')
171+
.querySelector(osiIconSelector)
172+
?.getAttribute('transform')
173+
?.match(/-?\d+/g)!;
174+
expect(x).toBe('41');
175+
expect(y).toBe('0');
176+
expect(scaleY).toBe('-1');
177+
});
41178
});
42179
});

src/svgs/mtr/station-icon.tsx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,40 @@ interface StationIconProps {
1111
export default function StationIcon(props: StationIconProps) {
1212
const { withinTransfer, outStationTransfer, isTerminal, isPassed, isPaidArea } = props;
1313

14+
const transforms = {
15+
icon: {
16+
v: withinTransfer <= 1 ? 0 : 18 * withinTransfer,
17+
},
18+
osiIcon: {
19+
v: 18 * (outStationTransfer - 1),
20+
x: isTerminal && withinTransfer ? 41 : 0,
21+
y: isTerminal && withinTransfer ? 0 : 26,
22+
scaleY: isTerminal && withinTransfer ? -1 : 1,
23+
},
24+
};
25+
1426
return (
1527
<g stroke={isPassed ? 'var(--rmg-grey)' : 'var(--rmg-black)'} data-testid="station-icon-wrapper">
1628
{outStationTransfer && (
1729
<path
18-
d={isTerminal ? 'M0,0H41' : 'M0,0V26'}
30+
d={isTerminal && withinTransfer ? 'M0,0H41' : 'M0,0V26'}
1931
strokeWidth={2.69}
2032
strokeDasharray={isPaidArea ? 0 : 2.5}
2133
/>
2234
)}
2335

24-
{withinTransfer <= 1 ? (
25-
<circle r={8} className="rmg-stn__mtr" />
26-
) : (
36+
<path
37+
d={`M-8,0 v${transforms.icon.v} a8,8 0 0,0 16,0 v-${transforms.icon.v} a8,8 0 0,0 -16,0Z`}
38+
className="rmg-stn__mtr"
39+
/>
40+
41+
{outStationTransfer && (
2742
<path
28-
d={`M-8,0 v${18 * withinTransfer} a8,8 0 0,0 16,0 v-${18 * withinTransfer} a8,8 0 0,0 -16,0Z`}
43+
d={`M-8,0 v${transforms.osiIcon.v} a8,8 0 0,0 16,0 v-${transforms.osiIcon.v} a8,8 0 0,0 -16,0Z`}
2944
className="rmg-stn__mtr"
45+
transform={`translate(${transforms.osiIcon.x},${transforms.osiIcon.y})scale(1,${transforms.osiIcon.scaleY})`}
3046
/>
3147
)}
32-
33-
{outStationTransfer &&
34-
(outStationTransfer === 1 ? (
35-
<circle r={8} cy={26} className="rmg-stn__mtr" />
36-
) : (
37-
<path
38-
d={`M-8,0 v${18 * (outStationTransfer - 1)} a8,8 0 0,0 16,0 v-${
39-
18 * (outStationTransfer - 1)
40-
} a8,8 0 0,0 -16,0Z`}
41-
className="rmg-stn__mtr"
42-
transform={`translate(${isTerminal ? 41 : 0},${isTerminal ? -18 : 26})`}
43-
/>
44-
))}
4548
</g>
4649
);
4750
}

0 commit comments

Comments
 (0)