• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OneBusAway / wayfinder / 21023558224

15 Jan 2026 07:44AM UTC coverage: 75.548% (+0.3%) from 75.239%
21023558224

push

github

web-flow
Merge pull request #307 from OneBusAway/trip-planner

Trip Planner Fit and Finish

1170 of 1321 branches covered (88.57%)

Branch coverage included in aggregate %.

629 of 899 new or added lines in 18 files covered. (69.97%)

5 existing lines in 4 files now uncovered.

8244 of 11140 relevant lines covered (74.0%)

3.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.45
/src/stores/tripOptionsStore.js
1
import { writable } from 'svelte/store';
1✔
2
import { browser } from '$app/environment';
3
import { parseTimeInput } from '$lib/otp';
4

5
// Modal visibility store
1✔
6
export const showTripOptionsModal = writable(false);
1✔
7

8
// Default walk distance for UI (1 mile in meters)
1✔
9
// Note: This is intentionally different from OTP_DEFAULTS.maxWalkDistance (3 miles)
1✔
10
// which serves as the API fallback. The UI default is more conservative.
1✔
11
export const DEFAULT_WALK_DISTANCE_METERS = 1609;
1✔
12

13
// Default values
1✔
14
const defaults = {
1✔
15
        // Session-only (not persisted)
1✔
16
        departureType: 'now', // 'now' | 'departAt' | 'arriveBy'
1✔
17
        departureTime: null, // Time string (e.g., "14:30") or null
1✔
18
        departureDate: null, // Date string (e.g., "2026-01-13") or null
1✔
19

20
        // Persisted in localStorage
1✔
21
        wheelchair: false,
1✔
22
        optimize: 'fastest', // 'fastest' | 'fewestTransfers'
1✔
23
        maxWalkDistance: DEFAULT_WALK_DISTANCE_METERS // meters (1 mile default)
1✔
24
};
1✔
25

26
// Walking distance options (in meters)
1✔
27
export const walkDistanceOptions = [
1✔
28
        { label: '¼ mile', value: 402 },
1✔
29
        { label: '½ mile', value: 805 },
1✔
30
        { label: '1 mile', value: 1609 },
1✔
31
        { label: '2 miles', value: 3219 },
1✔
32
        { label: '3 miles', value: 4828 }
1✔
33
];
1✔
34

35
function createTripOptionsStore() {
1✔
36
        // Load persisted values from localStorage
1✔
37
        let persisted = {};
1✔
38
        if (browser) {
1!
NEW
39
                const storedWheelchair = localStorage.getItem('tripOptions_wheelchair');
×
NEW
40
                const storedOptimize = localStorage.getItem('tripOptions_optimize');
×
NEW
41
                const storedMaxWalk = localStorage.getItem('tripOptions_maxWalkDistance');
×
42

NEW
43
                const parsedMaxWalk = storedMaxWalk ? parseInt(storedMaxWalk, 10) : NaN;
×
NEW
44
                persisted = {
×
NEW
45
                        wheelchair: storedWheelchair === 'true',
×
NEW
46
                        optimize: storedOptimize || 'fastest',
×
NEW
47
                        // Handle corrupted localStorage values (NaN, negative, etc.)
×
NEW
48
                        maxWalkDistance:
×
NEW
49
                                !isNaN(parsedMaxWalk) && parsedMaxWalk > 0 ? parsedMaxWalk : DEFAULT_WALK_DISTANCE_METERS
×
NEW
50
                };
×
NEW
51
        }
×
52

53
        const initial = { ...defaults, ...persisted };
1✔
54
        const { subscribe, set, update } = writable(initial);
1✔
55

56
        return {
1✔
57
                subscribe,
1✔
58
                set,
1✔
59
                update,
1✔
60

61
                // Reset only session values (departure time)
1✔
62
                resetSession: () => {
1✔
NEW
63
                        update((opts) => ({
×
NEW
64
                                ...opts,
×
NEW
65
                                departureType: 'now',
×
NEW
66
                                departureTime: null,
×
NEW
67
                                departureDate: null
×
NEW
68
                        }));
×
69
                },
1✔
70

71
                // Reset all values to defaults
1✔
72
                resetAll: () => {
1✔
NEW
73
                        if (browser) {
×
NEW
74
                                localStorage.removeItem('tripOptions_wheelchair');
×
NEW
75
                                localStorage.removeItem('tripOptions_optimize');
×
NEW
76
                                localStorage.removeItem('tripOptions_maxWalkDistance');
×
NEW
77
                        }
×
NEW
78
                        set(defaults);
×
79
                },
1✔
80

81
                // Update a persisted option (saves to localStorage)
1✔
82
                setPersisted: (key, value) => {
1✔
NEW
83
                        update((opts) => {
×
NEW
84
                                const newOpts = { ...opts, [key]: value };
×
NEW
85
                                if (browser && ['wheelchair', 'optimize', 'maxWalkDistance'].includes(key)) {
×
NEW
86
                                        localStorage.setItem(`tripOptions_${key}`, String(value));
×
NEW
87
                                }
×
NEW
88
                                return newOpts;
×
NEW
89
                        });
×
90
                },
1✔
91

92
                // Update a session option (not persisted)
1✔
93
                setSession: (key, value) => {
1✔
NEW
94
                        update((opts) => ({ ...opts, [key]: value }));
×
NEW
95
                }
×
96
        };
1✔
97
}
1✔
98

99
export const tripOptions = createTripOptionsStore();
1✔
100

101
// Helper to format walk distance for display
1✔
102
export function formatWalkDistance(meters) {
1✔
NEW
103
        const option = walkDistanceOptions.find((opt) => opt.value === meters);
×
NEW
104
        return option ? option.label : `${Math.round((meters / 1609) * 10) / 10} mi`;
×
NEW
105
}
×
106

107
// Helper to format departure time for pill display
1✔
108
// Accepts an optional translator function for i18n support
1✔
109
export function formatDepartureDisplay(opts, translator = null) {
1✔
NEW
110
        if (opts.departureType === 'now') return null;
×
111

NEW
112
        const timeStr = opts.departureTime || '';
×
NEW
113
        // Use translator if provided, otherwise fall back to English
×
NEW
114
        const prefix =
×
NEW
115
                opts.departureType === 'arriveBy'
×
NEW
116
                        ? translator
×
NEW
117
                                ? translator('trip-planner.arrive')
×
NEW
118
                                : 'Arrive'
×
NEW
119
                        : translator
×
NEW
120
                                ? translator('trip-planner.depart')
×
NEW
121
                                : 'Depart';
×
122

NEW
123
        if (timeStr) {
×
NEW
124
                // Use OTP module's parseTimeInput to format time (avoids duplicate logic)
×
NEW
125
                const formattedTime = parseTimeInput(timeStr);
×
NEW
126
                return formattedTime ? `${prefix} ${formattedTime}` : prefix;
×
NEW
127
        }
×
128

NEW
129
        return prefix;
×
NEW
130
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc