@@ -2,6 +2,11 @@ import { render } from '@testing-library/react-native';
22import * as Application from 'expo-application' ;
33import { useAtomValue } from 'jotai' ;
44import type { Station } from '~/@types/graphql' ;
5+ import {
6+ accuracyHistoryAtom ,
7+ backgroundLocationTrackingAtom ,
8+ locationAtom ,
9+ } from '~/store/atoms/location' ;
510import DevOverlay from './DevOverlay' ;
611
712jest . mock ( 'jotai' , ( ) => {
@@ -62,20 +67,36 @@ const mockUseNextStation = useNextStation as jest.MockedFunction<
6267> ;
6368
6469describe ( 'DevOverlay' , ( ) => {
65- beforeEach ( ( ) => {
66- // Default mock implementations for useAtomValue
67- // locationAtom, accuracyHistoryAtom, backgroundLocationTrackingAtomの順で呼ばれる
68- // (useTelemetryEnabledは別途モック済み)
69- mockUseAtomValue
70- . mockReturnValueOnce ( {
71- coords : {
72- speed : 10 ,
73- accuracy : 15 ,
74- } ,
75- } ) // locationAtom
76- . mockReturnValueOnce ( [ 10 , 15 , 20 ] ) // accuracyHistoryAtom
77- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
70+ const setupAtomValues = ( {
71+ location = {
72+ coords : {
73+ speed : 10 ,
74+ accuracy : 15 ,
75+ } ,
76+ } ,
77+ accuracyHistory = [ 10 , 15 , 20 ] ,
78+ backgroundLocationTracking = false ,
79+ } : {
80+ location ?: unknown ;
81+ accuracyHistory ?: unknown ;
82+ backgroundLocationTracking ?: boolean ;
83+ } = { } ) => {
84+ mockUseAtomValue . mockImplementation ( ( atom ) => {
85+ if ( atom === locationAtom ) {
86+ return location as never ;
87+ }
88+ if ( atom === accuracyHistoryAtom ) {
89+ return accuracyHistory as never ;
90+ }
91+ if ( atom === backgroundLocationTrackingAtom ) {
92+ return backgroundLocationTracking as never ;
93+ }
94+ return undefined as never ;
95+ } ) ;
96+ } ;
7897
98+ beforeEach ( ( ) => {
99+ setupAtomValues ( ) ;
79100 mockUseDistanceToNextStation . mockReturnValue ( '500' ) ;
80101 mockUseNextStation . mockReturnValue ( {
81102 id : 1 ,
@@ -106,125 +127,139 @@ describe('DevOverlay', () => {
106127
107128 it ( 'テレメトリー状態を表示する' , ( ) => {
108129 const { getByText } = render ( < DevOverlay /> ) ;
109- expect ( getByText ( 'Telemetry: ON' ) ) . toBeTruthy ( ) ;
130+ expect ( getByText ( 'TELEMETRY' ) ) . toBeTruthy ( ) ;
131+ expect ( getByText ( 'ON' ) ) . toBeTruthy ( ) ;
110132 } ) ;
111133
112134 it ( 'バックグラウンド位置情報のOFF状態を表示する' , ( ) => {
113135 const { getByText } = render ( < DevOverlay /> ) ;
114- expect ( getByText ( 'BG Loc: OFF' ) ) . toBeTruthy ( ) ;
136+ expect ( getByText ( 'BG LOC' ) ) . toBeTruthy ( ) ;
137+ expect ( getByText ( 'OFF' ) ) . toBeTruthy ( ) ;
115138 } ) ;
116139
117140 it ( 'バックグラウンド位置情報のON状態を表示する' , ( ) => {
118- mockUseAtomValue . mockReset ( ) ;
119- mockUseAtomValue
120- . mockReturnValueOnce ( {
141+ setupAtomValues ( {
142+ location : {
121143 coords : { speed : 10 , accuracy : 15 } ,
122- } ) // locationAtom
123- . mockReturnValueOnce ( [ 10 , 15 , 20 ] ) // accuracyHistoryAtom
124- . mockReturnValue ( true ) ; // backgroundLocationTrackingAtom
144+ } ,
145+ accuracyHistory : [ 10 , 15 , 20 ] ,
146+ backgroundLocationTracking : true ,
147+ } ) ;
125148
126- const { getByText } = render ( < DevOverlay /> ) ;
127- expect ( getByText ( 'BG Loc: ON' ) ) . toBeTruthy ( ) ;
149+ const { getByText, getAllByText } = render ( < DevOverlay /> ) ;
150+ expect ( getByText ( 'BG LOC' ) ) . toBeTruthy ( ) ;
151+ expect ( getAllByText ( 'ON' ) ) . toHaveLength ( 2 ) ;
128152 } ) ;
129153 } ) ;
130154
131155 describe ( '位置情報の表示' , ( ) => {
132156 it ( '精度情報を表示する' , ( ) => {
133- const { getByText } = render ( < DevOverlay /> ) ;
134- expect ( getByText ( 'Accuracy: 15m' ) ) . toBeTruthy ( ) ;
157+ const { getByText, getByTestId } = render ( < DevOverlay /> ) ;
158+ expect ( getByText ( 'LOCATION ACCURACY' ) ) . toBeTruthy ( ) ;
159+ expect ( getByTestId ( 'dev-overlay-accuracy-value' ) ) . toHaveTextContent (
160+ '15m'
161+ ) ;
135162 } ) ;
136163
137164 it ( '速度情報をkm/hで表示する' , ( ) => {
138- const { getByText } = render ( < DevOverlay /> ) ;
139- // speed: 10 m/s = 36 km/h
140- expect ( getByText ( 'Speed: 36km/h' ) ) . toBeTruthy ( ) ;
165+ const { getByText, getByTestId } = render ( < DevOverlay /> ) ;
166+ expect ( getByText ( 'CURRENT SPEED' ) ) . toBeTruthy ( ) ;
167+ expect ( getByTestId ( 'dev-overlay-speed-value' ) ) . toHaveTextContent (
168+ '36km/h'
169+ ) ;
141170 } ) ;
142171
143172 it ( '次の駅までの距離を表示する' , ( ) => {
144- const { getByText } = render ( < DevOverlay /> ) ;
145- expect ( getByText ( / N e x t : 5 0 0 m テ ス ト 駅 / ) ) . toBeTruthy ( ) ;
173+ const { getByText, getByTestId } = render ( < DevOverlay /> ) ;
174+ expect ( getByText ( 'NEXT TARGET' ) ) . toBeTruthy ( ) ;
175+ expect ( getByTestId ( 'dev-overlay-next-value' ) ) . toHaveTextContent ( '500m' ) ;
176+ expect ( getByTestId ( 'dev-overlay-next-meta' ) ) . toHaveTextContent (
177+ 'テスト駅'
178+ ) ;
146179 } ) ;
147180
148181 it ( '精度チャートを表示する' , ( ) => {
149- const { getByText } = render ( < DevOverlay /> ) ;
150- // accuracyHistory: [10, 15, 20] -> '▇▇▇'
151- expect ( getByText ( '▇▇▇' ) ) . toBeTruthy ( ) ;
182+ const { getByTestId } = render ( < DevOverlay /> ) ;
183+ expect ( getByTestId ( 'dev-overlay-accuracy-history' ) ) . toHaveTextContent (
184+ '▇▇▇'
185+ ) ;
152186 } ) ;
153187 } ) ;
154188
155189 describe ( 'エッジケース' , ( ) => {
156190 it ( '位置情報がnullの場合にクラッシュしない' , ( ) => {
157- mockUseAtomValue . mockReset ( ) ;
158- mockUseAtomValue
159- . mockReturnValueOnce ( null ) // locationAtom
160- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
161- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
191+ setupAtomValues ( {
192+ location : null ,
193+ accuracyHistory : [ ] ,
194+ backgroundLocationTracking : false ,
195+ } ) ;
162196
163197 expect ( ( ) => {
164198 render ( < DevOverlay /> ) ;
165199 } ) . not . toThrow ( ) ;
166200 } ) ;
167201
168202 it ( '速度がnullの場合に0km/hを表示する' , ( ) => {
169- mockUseAtomValue . mockReset ( ) ;
170- mockUseAtomValue
171- . mockReturnValueOnce ( {
203+ setupAtomValues ( {
204+ location : {
172205 coords : { speed : null , accuracy : 15 } ,
173- } ) // locationAtom
174- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
175- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
206+ } ,
207+ accuracyHistory : [ ] ,
208+ backgroundLocationTracking : false ,
209+ } ) ;
176210
177- const { getByText } = render ( < DevOverlay /> ) ;
178- expect ( getByText ( 'Speed: 0km/h ') ) . toBeTruthy ( ) ;
211+ const { getByTestId } = render ( < DevOverlay /> ) ;
212+ expect ( getByTestId ( 'dev-overlay-speed-value ') ) . toHaveTextContent ( '0km/h' ) ;
179213 } ) ;
180214
181215 it ( '速度が負の値の場合に0km/hを表示する' , ( ) => {
182- mockUseAtomValue . mockReset ( ) ;
183- mockUseAtomValue
184- . mockReturnValueOnce ( {
216+ setupAtomValues ( {
217+ location : {
185218 coords : { speed : - 5 , accuracy : 15 } ,
186- } ) // locationAtom
187- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
188- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
219+ } ,
220+ accuracyHistory : [ ] ,
221+ backgroundLocationTracking : false ,
222+ } ) ;
189223
190- const { getByText } = render ( < DevOverlay /> ) ;
191- expect ( getByText ( 'Speed: 0km/h ') ) . toBeTruthy ( ) ;
224+ const { getByTestId } = render ( < DevOverlay /> ) ;
225+ expect ( getByTestId ( 'dev-overlay-speed-value ') ) . toHaveTextContent ( '0km/h' ) ;
192226 } ) ;
193227
194228 it ( '精度がnullの場合に空文字を表示する' , ( ) => {
195- mockUseAtomValue . mockReset ( ) ;
196- mockUseAtomValue
197- . mockReturnValueOnce ( {
229+ setupAtomValues ( {
230+ location : {
198231 coords : { speed : 10 , accuracy : null } ,
199- } ) // locationAtom
200- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
201- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
232+ } ,
233+ accuracyHistory : [ ] ,
234+ backgroundLocationTracking : false ,
235+ } ) ;
202236
203- const { getByText } = render ( < DevOverlay /> ) ;
204- expect ( getByText ( 'Accuracy: m ') ) . toBeTruthy ( ) ;
237+ const { getByTestId } = render ( < DevOverlay /> ) ;
238+ expect ( getByTestId ( 'dev-overlay-accuracy-value ') ) . toHaveTextContent ( '--' ) ;
205239 } ) ;
206240
207241 it ( 'accuracyHistoryが空配列の場合にクラッシュしない' , ( ) => {
208- mockUseAtomValue . mockReset ( ) ;
209- mockUseAtomValue
210- . mockReturnValueOnce ( {
242+ setupAtomValues ( {
243+ location : {
211244 coords : { speed : 10 , accuracy : 15 } ,
212- } ) // locationAtom
213- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
214- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
245+ } ,
246+ accuracyHistory : [ ] ,
247+ backgroundLocationTracking : false ,
248+ } ) ;
215249
216250 expect ( ( ) => {
217251 render ( < DevOverlay /> ) ;
218252 } ) . not . toThrow ( ) ;
219253 } ) ;
220254
221255 it ( 'accuracyHistoryがnullの場合にクラッシュしない' , ( ) => {
222- mockUseAtomValue . mockReset ( ) ;
223- mockUseAtomValue
224- . mockReturnValueOnce ( {
256+ setupAtomValues ( {
257+ location : {
225258 coords : { speed : 10 , accuracy : 15 } ,
226- } ) // locationAtom
227- . mockReturnValue ( null ) ; // accuracyHistoryAtom
259+ } ,
260+ accuracyHistory : null ,
261+ backgroundLocationTracking : false ,
262+ } ) ;
228263
229264 expect ( ( ) => {
230265 render ( < DevOverlay /> ) ;
@@ -234,51 +269,54 @@ describe('DevOverlay', () => {
234269 it ( '次の駅までの距離が0の場合に適切に表示する' , ( ) => {
235270 mockUseDistanceToNextStation . mockReturnValue ( 0 ) ;
236271
237- const { getByText } = render ( < DevOverlay /> ) ;
238- expect ( getByText ( 'Next:' ) ) . toBeTruthy ( ) ;
272+ const { getByText, getByTestId } = render ( < DevOverlay /> ) ;
273+ expect ( getByText ( 'NEXT TARGET' ) ) . toBeTruthy ( ) ;
274+ expect ( getByTestId ( 'dev-overlay-next-value' ) ) . toHaveTextContent ( '--' ) ;
239275 } ) ;
240276
241277 it ( '次の駅情報がundefinedの場合に距離のみ表示する' , ( ) => {
242278 mockUseNextStation . mockReturnValue ( undefined ) ;
243279
244- const { getByText } = render ( < DevOverlay /> ) ;
245- expect ( getByText ( / N e x t : 5 0 0 m $ / ) ) . toBeTruthy ( ) ;
280+ const { getByTestId } = render ( < DevOverlay /> ) ;
281+ expect ( getByTestId ( 'dev-overlay-next-value' ) ) . toHaveTextContent ( '500m' ) ;
246282 } ) ;
247283
248284 it ( '次の駅情報と距離の両方がundefined/0の場合' , ( ) => {
249285 mockUseDistanceToNextStation . mockReturnValue ( 0 ) ;
250286 mockUseNextStation . mockReturnValue ( undefined ) ;
251287
252- const { getByText } = render ( < DevOverlay /> ) ;
253- expect ( getByText ( 'Next: ') ) . toBeTruthy ( ) ;
288+ const { getByTestId } = render ( < DevOverlay /> ) ;
289+ expect ( getByTestId ( 'dev-overlay-next-value ') ) . toHaveTextContent ( '--' ) ;
254290 } ) ;
255291 } ) ;
256292
257293 describe ( '速度計算のロジック' , ( ) => {
258294 it ( '速度が0の場合に0km/hを表示する' , ( ) => {
259- mockUseAtomValue . mockReset ( ) ;
260- mockUseAtomValue
261- . mockReturnValueOnce ( {
295+ setupAtomValues ( {
296+ location : {
262297 coords : { speed : 0 , accuracy : 15 } ,
263- } ) // locationAtom
264- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
265- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
298+ } ,
299+ accuracyHistory : [ ] ,
300+ backgroundLocationTracking : false ,
301+ } ) ;
266302
267- const { getByText } = render ( < DevOverlay /> ) ;
268- expect ( getByText ( 'Speed: 0km/h ') ) . toBeTruthy ( ) ;
303+ const { getByTestId } = render ( < DevOverlay /> ) ;
304+ expect ( getByTestId ( 'dev-overlay-speed-value ') ) . toHaveTextContent ( '0km/h' ) ;
269305 } ) ;
270306
271307 it ( '速度が正の小数値の場合に正しく変換する' , ( ) => {
272- mockUseAtomValue . mockReset ( ) ;
273- mockUseAtomValue
274- . mockReturnValueOnce ( {
275- coords : { speed : 13.89 , accuracy : 15 } , // 約50 km/h
276- } ) // locationAtom
277- . mockReturnValueOnce ( [ ] ) // accuracyHistoryAtom
278- . mockReturnValue ( false ) ; // backgroundLocationTrackingAtom
279-
280- const { getByText } = render ( < DevOverlay /> ) ;
281- expect ( getByText ( 'Speed: 50km/h' ) ) . toBeTruthy ( ) ;
308+ setupAtomValues ( {
309+ location : {
310+ coords : { speed : 13.89 , accuracy : 15 } ,
311+ } ,
312+ accuracyHistory : [ ] ,
313+ backgroundLocationTracking : false ,
314+ } ) ;
315+
316+ const { getByTestId } = render ( < DevOverlay /> ) ;
317+ expect ( getByTestId ( 'dev-overlay-speed-value' ) ) . toHaveTextContent (
318+ '50km/h'
319+ ) ;
282320 } ) ;
283321 } ) ;
284322} ) ;
0 commit comments