test(ember): drive addon/ coverage behind a per-file 100% gate - #310
Draft
roncodes wants to merge 104 commits into
Draft
test(ember): drive addon/ coverage behind a per-file 100% gate#310roncodes wants to merge 104 commits into
roncodes wants to merge 104 commits into
Conversation
Phase A of the addon/ coverage campaign. Ports the ember-ui coverage setup (ember-cli-code-coverage 3.1.0 behind COVERAGE=true, per-file 100% gate with artifact-freshness check and its self-test, Testem afterTests upload, codecov.yml with backend+frontend flags, a "Test with coverage" CI job that uploads with if: always()) and repairs the harness so the existing suite can run at all. Baseline before: 775/827 tests red, no coverage artifact possible. Baseline after: 832 tests, 502 pass / 330 fail (223 of the failures are untouched `ember generate` scaffolds, DEFECTS #4). Coverage baseline (denominator for the campaign): Statements 3213/18831 (17.1%) · Branches 1862/12335 (15.1%) Functions 1092/5526 (19.8%) · Lines 3123/17868 (17.5%) 530/746 addon files have gaps; 3 never load (see ledger). Harness root causes fixed (DEFECTS #1-#3, #5-#11): ember-core imports tracked-built-ins without declaring it; ember-core imports host-console modules (config/environment, extensions, the `fetch` AMD shim) and reads config.API at load; ember-intl hydrates every bundled locale and the browser lacks mn-mn ICU data; the dummy app had no file model, no hostRouter, and EXTEND_PROTOTYPES off while the console runs with it on; testem's bail_on_uncaught_error truncated runs; a test assigned the real window.location and navigated the browser away; eight tests imported non-existent dummy/ initializer paths. Coverage plumbing traps: ember-cli-code-coverage 3.x has no included hook, so the istanbul plugin is wired in index.js; for an ember-engines buildEngine addon the babel key must be top-level in that config; the json reporter must be requested; and both plugin and middleware read coverage.js from ember-addon.configPath (tests/dummy/config).
…currency-decorators import - addon/helpers/is-active-route.js re-exported @fleetbase/console/helpers/is-active-route, a module that exists nowhere; nothing referenced the helper (DEFECTS #12). - order/details/proof.js imported ember-concurrency-decorators, which this package does not declare; ember-concurrency (already used everywhere else) exports the same task decorator (DEFECTS #13). Both modules threw on evaluation and were absent from the coverage report.
All 20 real tests in layout/fleet-ops-sidebar-test.js now pass (13 were red). Every failure was test-side, against ember-ui's current navigator markup: - the nested view's back control is a sibling <button>, so :first-of-type and :nth-of-type(n) never addressed menu items; items are now looked up by their own index through findAll - qunit-dom includesText only inspects the first match; container-level checks are used where the test meant "any item" - search results are portaled to #application-root-wormhole; the suite mounts that inside #ember-testing (ember-ui's idiom) and asserts on the full result list, since branch items legitimately match by keyword - the universe stub lacked the Evented surface the component subscribes to - common.create-new-resource is a host-console translation; added tests/helpers/host-translations.js, applied via addTranslations for every rendering test Coverage: 3213/18831 -> 3219/18856 statements (17.07%); tests 502 -> 513 pass. fleet-ops-sidebar.js 77/94 statements, 43/48 functions.
addon/helpers/format-duration.js only re-exported ember-ui's helper; nothing imports the addon module and templates resolve the helper from ember-ui's own app re-export. Being a pure re-export it also never entered the coverage report (DEFECTS #14).
Replaces the two blueprint scaffolds under layout/fleet-ops-sidebar/ with real rendering suites: store queries and their params, error reporting, universe-driven reloads, live-map focusing (ready and deferred, including a failed transition), panel-title routing with the fleets-index collapse, permission-gated panel dropdown, and every row dropdown action delegating to the actions services. FleetListingPanel is replaced by a template-only stand-in so the listing is tested in isolation. Coverage: 3219 -> 3280/18856 statements (17.39%); tests 513 -> 534 pass (851 total). driver-listing.js 43/43 statements, fleet-listing.js 40/43.
Adds a registry-and-search suite for the sidebar: items and panels other extensions register through the universe menu registry (root, per-section, in-place footer components, nested panels, pinned items, priority ties), the API search provider (merged after local matches; empty and failing responses swallowed), the primary action, and the default-orders-landing predicate including a null router URL. Removes nine fallbacks in the component that no caller can reach (DEFECTS #15): five default arguments, the eight @Tracked list initializers the constructor always overwrites before any read, the ?? [] in withRegistryItems, the console.-prefix guard in fullRoute and the ?? 0 in defaultPriorityForRoute. The empty-query guard in searchNavigation stays behind an istanbul ignore naming the navigator's own filter. fleet-ops-sidebar.js: 83/83 statements, 41/41 branches, 48/48 functions. Coverage: 3280 -> 3290/18845 statements (17.45%); tests 534 -> 543 pass (860 total).
Adds an actions-and-layout suite for the sidebar operations monitor: store normalisation (including hosts without pushPayload and record-like fleets), request failure, universe-driven reloads, live-map sources, per-tab filters and empty states, fleet expansion with embedded members, filtered fleet rows, every row dropdown action, locate flows, alternative fleet identifiers and null entries, and the list-height observers with all three boundary fallbacks. Removes code no path can reach (DEFECTS #16): three unreferenced getters, the empty-query guard in resourceMatches, the expandedFleetIds initializer, two never-nullish ?? 0 fallbacks and nine default arguments; the trailing tab check in performEmptyStateAction is now unconditional. Non-browser host guards, the did-insert ordering guard and the EXTEND_PROTOTYPES-shadowed Array.isArray branch carry istanbul ignores naming their reason. operations-monitor.js: 242/242 statements, 98/98 branches, 113/113 functions. Coverage: 3290 -> 3359/18827 statements (17.84%); tests 543 -> 563 pass (880 total).
Real suites for order-route-type, part-identity, equipment-identity, driver-identity, device-identity and vehicle-identity; the driver-name, vehicle-name and place-address scaffolds replaced; residue cases appended to attached-vehicle, telematic-device and telematic-provider. The pre-existing resource-identities suite passes again: its red tests passed @column={{hash}}, and a bare helper as a named argument is rejected at template compile time in Ember 5 ({{(hash)}} invokes it). Removes three click guards the templates already enforce (DEFECTS #17): the attached-vehicle hasVehicle check, the telematic-provider `?? row` fallback and the driver-identity `column ?? {}` in a compact-only getter. All 12 files in addon/components/cell/ are at 100% statements, branches and functions. Coverage: 3359 -> 3462/18825 statements (18.39%); tests 563 -> 627 pass (935 total).
…fully Rewrites the 14 red `Unit | Utility` suites (13 of them `assert.ok(result)` scaffolds, one stale against commit f784e71) and adds order-route-summary, to-calendar-date and waypoint-label tests. All 16 utils are at 100% on every metric; the loader suite is deterministic (no network, no free-running timers). Source, all recorded in DEFECTS #18-#22: - leaflet-to-geojson: createFeatureCollectionFromLayers passed an object to a constructor that needs an array and always threw; fixed. normalizeToRings' duplicate trailing return merged. - utils/geojson/geo-json.js: dead duplicate importing a missing sibling; deleted with its app shim and scaffold. - map-drawer-dropdown-position: reads window via ember-window-mock. - leaflet-plugin-loader: dead defaults at single-caller internals deleted, non-browser guards istanbul-ignored with reasons. - setup-customer-portal, to-calendar-date, to-multi-polygon: unreachable defensive fallbacks deleted. - utils/leaflet: Leaflet global resolved lazily instead of at module load. Coverage: statements 3462/18825 -> 3682/18813, branches 2135 -> 2364, functions 1197 -> 1243; tests 627 pass / 308 fail -> 690 / 290; files fully covered 229 -> 246.
Two harness root causes, recorded in DEFECTS #23: - ember-local-storage caches storageFor proxies at module level; the first test app destroys them and later apps assert "Cannot create a new tag ... after it has been destroyed" on any currentUser/appCache read. The shared setup helpers now reset that cache after every test. - route-optimization and leaflet-routing-control register through universe.getApplicationInstance(), which only the console sets; those suites hand the universe the test owner. Six suites corrected to the source contract (DEFECTS #24): stubs moved off getter-only @action members onto the host router, the contextmenu removal count, device panel.view's warning return, and geofence's multi-hop reload wait. Coverage: statements 3682 -> 3808/18813, branches 2364 -> 2412, functions 1243 -> 1277; tests 690 pass / 290 fail -> 709 / 271. No source change.
…r/route suites - Move 16 unit tests from connectivity/telematics/index/* to the current connectivity/telematics/* paths (the subtree was moved without its tests); drop one stale duplicate and one mis-generated duplicate (DEFECTS #25). - Add the two missing app/ re-export shims for controllers/operations/orders/ index and controllers/operations/routes/index; the dummy app could not resolve either (#26). - Correct the orders-details route test to the route's delegation to the controller teardown methods, fix the attachments assertion count, and replace the register-osrm scaffold with a real registration test (#27). - Record the pre-existing "Failed to fetch" spill from form scaffolds (#28). Coverage: statements 3808 -> 3891/18813, branches 2412 -> 2449, functions 1277 -> 1299; tests 709 pass / 271 fail -> 735 / 244.
Eight tests corrected to the source contract (DEFECTS #29): the vehicle-details controller passes the vehicle public id (a9eed9c), the map settings payload carries the tile-url keys, two prototype-based fakes shadow getters / bind @action through an inheriting object, and the three helper scaffolds became real tests. Both Leaflet initializer tests now drive the initializer's 100ms poll through a captured setInterval. They used to leak that poll into the next test, and in a full run the polyfill's leaked poll crashed on the stub Leaflet global the next test installed. Both initializers are at 100%. Everything outside `Integration | Component` is green. Coverage: statements 3891 -> 3904/18813, branches 2449 -> 2459, functions 1299 -> 1300; tests 735 pass / 244 fail -> 747 / 236; files fully covered 246 -> 249. No source change.
…p tile-url arguments Replaces the scaffolds for fuel-report, warranty, place, integrated-vendor, service-area and zone details with real suites (13 tests) and adds a shared register-template-only helper that stands in ember-ui's network-backed CustomField::Yield and CountryName. Source (DEFECTS #30): five map templates passed `@url={{leaflet-tile-url}}` as a bare named argument, which Ember 5 rejects at render, so the place, service-area and zone details views and the two map modals could not render. All five now use `{{(leaflet-tile-url)}}`. The helper's dead `= {}` hash default is trimmed and it has its own test. Coverage: statements 3904 -> 3916/18813, branches 2459 -> 2465, functions 1300 -> 1304; tests 747 pass / 236 fail -> 761 / 230; files fully covered 249 -> 250.
Replaces the fuel-report, warranty, place, integrated-vendor, service-area and zone form scaffolds with real suites (13 tests). A shared helper stands in the store-backed ember-ui inputs and provides a record-like fixture whose modelName/isNew let `cannot-write` resolve a real permission, so both the enabled and disabled states are exercised. All six form components are at 100%. Source (DEFECTS #31): fuel-report/form's onAutocomplete and integrated-vendor/form's showAdvancedOptions/toggleAdvancedOptions were referenced by no template; deleted. Coverage: statements 3916 -> 3921/18808, branches 2465 -> 2469, functions 1304 -> 1306; tests 761 pass / 230 fail -> 772 / 224; files fully covered 250 -> 253.
…omponents Replaces nine scaffolds with real rendering suites: modals/place-details, modals/point-map, device/pill, driver/pill, vehicle/pill, entity/card, vehicle/card, driver/panel-header and vehicle/panel-header (23 tests). Source (DEFECTS #32): vehicle/pill.hbs passed `@this.resource=` instead of `@resource=` to the Pill, so click handlers got no vehicle and the online dot was always offline, and its tooltip invoked a string as a helper. Both fixed. Coverage unchanged (these components carry no JS to count); tests 772 pass / 224 fail -> 791 / 215.
Real suites for route-optimization-engine-select-button, order-progress-bar, display-place, order-list-overlay/order and fleet/form (15 tests); all five components are at 100% on every metric. The shared model-select stand-in gained a clear button so relationship-clearing paths are testable. Source (DEFECTS #33): fleet/form's unread `writePermission` getter and `statusOptions` field, and order-progress-bar's dead lazy `progress` initializer and unread `order` field, are deleted. Coverage: statements 3920 -> 3930/18804, branches 2469 -> 2484, functions 1306 -> 1311; tests 791 pass / 215 fail -> 806 / 210; files fully covered 253 -> 258.
…order progress card Real suites for vendor/form, sensor/form, contact/form and order-progress-card (14 tests); all four components are at 100%. Source (DEFECTS #34): the sensor form's never-invoked photo-upload task and its injections are deleted, and the progress card's tracker guard tests the order before dereferencing it, so a card without an order returns instead of throwing 100ms after render. Coverage: statements 3930 -> 3977/18800, branches 2484 -> 2507, functions 1311 -> 1325; tests 806 pass / 210 fail -> 818 / 206; files fully covered 258 -> 262.
…he entity form Real suites for vendor/details, customer/details, driver/details and entity/form (10 tests); all four components are at 100%. Source (DEFECTS #35): vendor/details now branches on `@resource.isIntegratedVendor` and passes `@vendor` to IntegratedVendor::Details (the integrated view was unreachable and mis-wired); customer/details labels the phone field correctly; driver/details and order/details/detail call `join` with the separator first; entity/form loses a dead lazy initializer and an unreachable null-clear guard. Coverage: statements 3977 -> 3986/18799, branches 2507 -> 2511, functions 1325 -> 1330; tests 818 pass / 206 fail -> 828 / 202; files fully covered 262 -> 264.
…nd global search Real suites for driver-onboard-settings, widget/fleet-ops-key-metrics and global-search (8 tests); all three components are at 100%. Both fetching components were origins of the DEFECTS #28 fetch spill, which halves. Source (DEFECTS #36): the onboarding settings load coalesces a null payload instead of throwing on it; unreachable guards, parameter defaults and lazy tracked initializers in both components are deleted. Coverage: statements 3986 -> 4039/18794, branches 2511 -> 2541, functions 1330 -> 1349; tests 828 pass / 202 fail -> 836 / 199; files fully covered 264 -> 267.
…atar picker and custom entity form The last "Failed to fetch" origin was ember-ui's CountryName mounted by Vendor::PanelHeader; its suite now stands the component in and a full run logs zero spills (DEFECTS #28 closed). Real suites replace the scaffolds for device/form, avatar-picker and custom-entity/form. A dead post-load guard in the avatar picker and an uncalled save action in the custom entity form are deleted (#39). Two findings are recorded for decision: the custom entity image upload reads a config nothing provides (#37) and its dasherized type handler is overwritten by the two-way Input (#38). Coverage: statements 21.49% -> 21.66%, branches 20.71% -> 20.9%, functions 24.42% -> 24.55%, lines 21.83% -> 22.01%; 850 pass / 194 fail (+14 pass); 271 files fully covered (+4).
…completes The admin settings passed `@disable` to ember-ui's Toggle, which only knows `@disabled`, so the toggle stayed active while the panel below it said onboarding had to finish first.
…activity form and event selector Real suites replace the scaffolds for customer/admin-settings, device/manager, activity/event-selector and activity/form; all four are at 100% on every metric. Dead code found while profiling is deleted (DEFECTS #41): an unread field, an uncalled save task, twelve optional- chain branches around an injected intl service, a lazy initializer and two guards for a no-resource render the template cannot survive. DEFECTS #38 is amended with the activity form's key/code inputs, which share the two-way Input race. customer/admin-settings now reads `window` through ember-window-mock and the dummy config mirrors the console's `stripe` block. Coverage: statements 21.66% -> 22.09%, branches 20.9% -> 21.12%, functions 24.55% -> 24.91%, lines 22.01% -> 22.45%; 862 pass / 190 fail (+12 pass); 275 files fully covered (+4).
…ate every vehicle field on write permission Both forms handed `this.controller` to their RegistryYield components, a property neither component defines, so registered extensions always received `undefined` even though both routes pass `@controller`. The vehicle form also left four `<Input>`s and nineteen shorthand InputGroups without the `cannot-write` gate the rest of the form uses.
A real suite replaces the vehicle/form scaffold: every bound text input in DOM order, the eleven selects, the unit/money/date pickers, the five registries, driver assignment, status pick, checkbox toggle, upload success and failure, and the no-write state. Two unused actions and an unused field are deleted (DEFECTS #44); the template fixes for the controller argument and the ungated fields landed separately (#42, #43). Coverage: statements 22.09% -> 22.13%, branches 21.12% -> 21.14%, functions 24.91% -> 24.98%, lines 22.45% -> 22.49%; 864 pass / 189 fail (+2 pass); 276 files fully covered (+1).
Both "create user" action buttons sent `subject_uui` for the upload's subject, so the uploaded avatar was never associated with the user record.
A real suite replaces the driver/form scaffold: bindings, the user details block, the three model selects, status, upload success and failure, the create-user action button through its modal callbacks, and the no-write state. The `subject_uui` typo it exposed landed separately (DEFECTS #45). Coverage: statements 22.13% -> 22.16%, functions 24.98% -> 25.05%, lines 22.49% -> 22.53%; 867 pass / 188 fail (+3 pass); 277 files fully covered (+1).
…ction buttons The customer/form integration suite is rewritten on real record fixtures and per-suite stand-ins: bindings, the address flow, the welcome-email opt-in with and without existing meta, the hidden states and the read-only state. The form's never-rendered "create user" action-button block and its two injections are deleted (DEFECTS #47); the translation typo it exposed landed separately (#46). Coverage: statements 22.16% -> 22.24%, functions 25.05% -> 25.16%, lines 22.53% -> 22.61%; 871 pass / 183 fail (+4 pass, -5 fail); 278 files fully covered (+1).
…ides carry `matchesStop` compared `stop.id === activeStop.id` even when neither had an `id`, so `undefined === undefined` made the first stop the active one whenever stops were keyed by `uuid`/`public_id` alone; the "now heading to" label and marker then pointed at stop 1 regardless of progress.
…hole component Three harness faults kept all eleven order/details/tracking tests red: a stub without `viewLabel`, an order builder whose trailing spread replaced its merged tracker payload, and a "Due now" expectation for a rendering removed in 9356fb6 (DEFECTS #49). Nine tests are added over the lifecycle fallbacks, confidence and diagnostics, active-stop labelling, reported ETA lookup, progress fallbacks, ping driver and the assign-driver no-op; three unrendered getters and seven guards the template already makes are deleted (#50). The active-stop matching bug the suite exposed landed separately (#48). Coverage: statements 22.24% -> 22.47%, branches 21.16% -> 21.5%, functions 25.16% -> 25.28%, lines 22.61% -> 22.84%; 891 pass / 172 fail (+20 pass, -11 fail); 280 files fully covered (+2).
Profiled the residue by kind first, then wrote one test per shape rather than walking methods. services/map-adapter/google.js goes 992/1117 -> 1033/1117 statements, 639/791 -> 674/781 branches, 126/148 -> 134/148 functions on eight tests. The coordinate readers and map centring across a usable point, an unusable one and no event; invalidateSize; applyViewSettings adding, reusing and detaching the traffic and transit layers and appending caller styles to the base set; toggleDrawControl; panBy; a labelled route marker drawn as a badge on the advanced path; and the API loader both short-circuiting on an API already present and reporting a script that will not load. Statements 6327 -> 6368, branches 4160 -> 4195, functions 1838 -> 1846, lines 6010 -> 6047.
Seven tests for the public editPolygon (the one geofence reaches through map-manager): its three refusals, a focus fitted before the edit opens, Save resolving with the ring as it now stands, Cancel restoring the captured ring, and the settled guard. The classic marker tooltip's pointer tracking end to end, the context menu's outside-click close, and a defaults sweep across applyViewSettings, showContextMenu, addPolyline, fitBounds padding and an unreadable environment config. Five gaps were unreachable rather than untested and were deleted, not covered (DEFECTS #87, #88): #ensureTooltipOverlayView, a private method whose name appears once in the file — its own declaration — along with the permanently-null _tooltipOverlayView it was the only writer of; and four defaults their callers always supply, including addRoutingControl's `?? []` below a guard that has already proved route.waypoints non-empty. map-adapter/google.js 1033/1117 -> 1065/1105 stmts, 674/781 -> 702/772 branches, 134/148 -> 143/145 functions Totals statements 6368 -> 6400 (34.41%) branches 4195 -> 4223 (34.96%) functions 1846 -> 1855 lines 6047 -> 6076 Tests 1322 -> 1329, passing 1239 -> 1246; failures unchanged at 83.
Seven tests: a marker tooltip carrying markup and a pointerless move falling back to the origin; a layer stamped with __labelText after it was drawn getting its label when next shown — the real google-live-map path for a service area first drawn while it had no name; the three ways a label cannot be built; a ring of plain numbers and a ring of rings; the overlay left alone when the projection gives nothing; bounds collected through a null; and a polygon hovered after its map has gone. Most of this block's residue was unreachable and was deleted, not covered (DEFECTS #89): #normalizeDrawEvent, a second private method whose name appears once in the file, and five `if (!x) return` guards that each duplicate a test the immediate caller already makes. One fallback was kept behind an istanbul ignore instead — it is the contract for the __labelText stamping google-live-map.js does from outside this file. map-adapter/google.js 1065/1105 -> 1068/1094 stmts, 702/772 -> 706/747 branches Totals statements 6400 -> 6403 (34.45%) branches 4223 -> 4227 (35.06%) lines 6076 -> 6072 functions 1855 (unchanged) Line coverage reads 34.44% -> 34.43%: the deletions and the pragma took covered lines out of the numerator along with the uncovered ones. Tests 1329 -> 1336, passing 1246 -> 1253; failures unchanged at 83.
Eleven tests close the last four pieces and the defensive arms under them: rectangle and circle drafts saving as their own geometry through editPolygon; a draft with no __overlayType announced as a polygon; the API loader resolving when the injected script calls back; the classic marker path; an advanced marker moved by assignment and a frame already dispatched when the cancel lands — driven through a hand-stubbed requestAnimationFrame so no platform gets a vote on that race; polyline points given as objects; destroyMap cancelling a running animation; and the small defensive arms around them. Nine redundant arms and #drawEvent were deleted rather than covered (DEFECTS #90) — the third private method in this file whose name appears exactly once, after #87 and #89. map-adapter/google.js is now 100% on all four metrics: 1076/1076 stmts, 718/718 branches, 145/145 fns, 995/995 lines. It is the addon's largest file; iterations 48-55 took it from 113/1114. Totals statements 6403 -> 6411 (34.52%) branches 4227 -> 4238 (35.24%) functions 1855 -> 1857 lines 6072 -> 6080 Files fully covered 309 -> 310. Tests 1336 -> 1347, passing 1253 -> 1264; failures unchanged at 83.
The workbench had no test file at all. This adds the rendering harness —
the five Orchestrator panels and LeafletMap stubbed as template-only
stand-ins, since ember-leaflet is not installed here and <LeafletMap>
cannot otherwise resolve — and thirteen tests over the lifecycle and
orchestration flow: the five parallel loads and what each asks for, every
load failing, the toolbar panels, both side panels collapsing, a run
proposing a plan and drawing one routing control per vehicle, the
formatters the plan viewer is handed, a run that places nothing, a run
and a commit the server refuses, committing and reloading, and discarding
taking the routes off the map.
The plan-viewer stub calls the formatter callbacks it is handed, exactly
as the real one does, so the wiring is what is under test.
orchestrator-workbench.js 0/428 -> 274/428 stmts,
13/261 -> 127/261 branches,
17/94 -> 51/94 functions
Totals statements 6411 -> 6685 (36.00%) branches 4238 -> 4366 (36.30%)
functions 1857 -> 1908 lines 6080 -> 6334
Tests 1347 -> 1360, passing 1264 -> 1277; failures unchanged at 83.
…hases Thirteen more tests: all three selection toggles and clears, with clearing drivers releasing their vehicles; a selection narrowing the run, including the driver-tab resolution to a vehicle_id; an order dragged onto a vehicle joining the plan, one already in it rewritten in place, and two drops that change nothing; two phases running in sequence with prior_assignments carried forward and autoCommit landing between them; the run message dismissed, the import modal reloading the pool, card fields saving, the left panel collapsing, and both resize handles dragged through their stops. The phase-builder and map stubs became real components reading from a test-bed service: a template-only stand-in has only @Args, so it cannot hand the component a value the test chose, and onMapLoad needs a real map instance to call setView on. orchestrator-workbench.js 274/428 -> 377/428 stmts, 127/261 -> 174/261 branches, 51/94 -> 84/94 functions Totals statements 6685 -> 6788 (36.55%) branches 4366 -> 4413 (36.70%) functions 1908 -> 1941 lines 6334 -> 6430 Tests 1360 -> 1373, passing 1277 -> 1290; failures unchanged at 83.
Builds the yielding LeafletMap stand-in — it yields (hash tile= marker=) and the marker yields (hash popup= tooltip=), matching ember-leaflet's shape, with div-icon/icon/point-to-coordinates registered as helpers that hand back their named args. That unlocked the half of the template that had never rendered. Ten tests: order stops pinned as P/D badges with popups and tooltips; a multi-drop order pinned per waypoint in its own order, with 0,0 dropped; _placeCoords across the shapes it accepts and three it does not; a driver pinned with their status; several stops fitted as a box and one zoomed to; the browser location centring the map, arriving late and being ignored, and being refused; a plan's A1/A2/B stop labels; and a driver matched to a group by vehicle_id. Three selection getters were deleted rather than covered (DEFECTS #91) — the callers a grep appears to find are the sub-components' own identically-named getters, and the workbench template never reads them. orchestrator-workbench.js 377/428 -> 409/425 stmts, 174/261 -> 223/261 branches, 84/94 -> 91/91 functions (all of them) Totals statements 6788 -> 6820 (36.73%) branches 4413 -> 4462 (37.10%) functions 1941 -> 1948 lines 6430 -> 6458 Tests 1373 -> 1383, passing 1290 -> 1300; failures unchanged at 83.
Eight tests, one per shape: a response missing the key it was asked for; a selected driver with no vehicle; a commit reporting no count; a route returned with no geometry skipped while the other is still drawn; a plan naming an unknown vehicle tagged through the whole ?? chain; a waypoint that is itself the place; a group with no timings getting an empty summary; a map mounting after the orders and re-centring on them; and the formatters at their edges. DEFECTS #92 (NEEDS DECISION): formatIsoTime's try/catch cannot fire — new Date() does not throw on bad input and toLocaleTimeString returns the string "Invalid Date" rather than throwing, so the '' the catch exists to produce is unreachable and an unparseable time window is shown to a dispatcher as the words "Invalid Date". The dead catch is deleted (behaviour-neutral); the one-line real fix is left for Ron, since it changes behaviour on a path no test exercises against real data. orchestrator-workbench.js 409/425 -> 415/423 stmts, 223/261 -> 246/261 branches Totals statements 6820 -> 6826 (36.77%) branches 4462 -> 4484 (37.29%) lines 6458 -> 6460 functions 1948 (unchanged) Tests 1383 -> 1391, passing 1300 -> 1308; failures unchanged at 83.
Seven tests close the last reachable residue: a run reporting no assignments key; a drop onto a plan of several; the dark tile theme; a stop on the equator pinned but unable to anchor a route leg; null island rejected in all four shapes; unnumbered waypoints keeping their order; and a card-fields read that raises before returning a promise. Traced-dead and deleted: commitPlan's plan-length guard and onDropOnVehicle's two ?? operands (every caller has already proved them), the _resizing field, and _draggingOrder with its three writes — nothing reads either. Five @Tracked initialisers are pragma'd with the specific writer that beats them: with the decorator transform an initialiser evaluates on first read, so a field written first never runs it. orchestrator-workbench.js 255/255 branches, 91/91 functions (both done) 415/423 -> 409/411 stmts (99.51%) Two initialisers remain, recorded as DEFECTS #93 (OPEN): the statementMap is offset from the source, and I could not place them to the standard §4 asks for. Not pragma'd on inference — an untrue reason is worse than an uncovered line. Totals statements 6826 -> 6820 (36.76%) branches 4484 -> 4493 (37.38%) lines 6460 -> 6454 functions 1948 (unchanged) Tests 1391 -> 1398, passing 1308 -> 1315; failures unchanged at 83.
Closes DEFECTS #93. The two remaining statements could not be placed from the coverage map — its positions land on the divider comments — so they were identified by bisection: pragma a candidate, re-run, and watch whether the uncovered count falls or only the denominator does. They were not the same kind of thing. availableEngines is genuinely unreachable: its only reader is the phase builder, rendered only while that panel is open, so loadEngines assigns it before anything reads it and the lazy @Tracked initialiser never evaluates. It now carries a pragma naming that gate. cardFields was the harness, not the component. The real OrderPool reads @cardFields; the stand-in for it did not, and Ember argument references are lazy — the getter runs only when a child consumes the argument. The stub now renders it as the real component does, and a test asserts the settings endpoint's fields arrive. orchestrator-workbench.js is now 100% on all four: 410/410 stmts, 255/255 branches, 91/91 fns, 375/375 lines. Iterations 56-61 took it from 0/428. Files fully covered 310 -> 311. Totals statements 6820 -> 6821 branches 4493 -> 4494 lines 6454 -> 6455 Tests 1398, passing 1315; failures unchanged at 83.
Stands up the harness for the 962-line customer order form and covers its lifecycle: the enabled-order-configs filter picking only what the customer is entitled to and applying the first to the order, both settings reads failing and being reported, the payments config, and an order carrying its own customer versus falling back to the session. This replaces the generated `it renders` stub, which failed because the component reads this.order.customer in its constructor while the stub rendered it with no arguments — so this is the first of the 83 blueprint scaffolds to be retired, and DEFECTS #4's count is now 82. Harness notes: ember-file-upload and ember-model-select are not installed here, so FileDropzone and friends need stand-ins; order.customer is a polymorphic belongsTo and rejects a plain object; and the component calls order.set(), so the order must be a real record. create-order-form.js 5/395 -> 56/395 stmts, 7/197 -> 13/197 branches, 6/67 -> 10/67 functions Totals statements 6821 -> 6872 (37.04%) branches 4494 -> 4506 (37.49%) functions 1948 -> 1957 lines 6455 -> 6505 Tests 1398 -> 1403, passing 1315 -> 1321, failures 83 -> 82.
A thin iteration: create-order-form.js 56/395 -> 75/395 statements on one
new test. Most of the time went on harness discovery.
What landed: an abilities stub, without which every control on this form
is disabled — `cannot "fleet-ops create order"` gates the entity buttons,
the notes textarea and the dropzone; a DragSortList stand-in that yields
|item index| and reports reorders through @dragEndAction; and a
ModelSelect stand-in reporting the choice from a test-bed service.
What did not: setPayloadPlace cannot be driven without a real Leaflet
map, because previewDraftOrderRoute does control.addTo(this.map) and
leaflet-routing-machine throws from its own onAdd when that is undefined.
Giving the harness an L.map is next iteration's setup and unlocks the
whole route-preview block.
create-order-form.js 56/395 -> 75/395 stmts, 13/197 -> 17/197 branches,
10/67 -> 12/67 functions
Totals statements 6872 -> 6891 (37.14%) branches 4506 -> 4510
functions 1957 -> 1959 lines 6505 -> 6524
Tests 1403 -> 1404, passing 1321 -> 1322; failures unchanged at 82.
A sized div inside #ember-testing with window.L.map() on it, passed as @Map and torn down in afterEach. That was the unlock: choosing a pickup and a dropoff through the place selects now runs setPayloadPlace, updatePayloadCoordinates, createPlaceArrayFromPayload, previewDraftOrderRoute, removeRoutingControlPreview and getRoute, and attaches a real routing control. DEFECTS #94 (OPEN), a live bug found while covering: previewDraftOrderRoute warns when there is nothing to route and then carries on — no return — so it calls map.flyToBounds([]) and Leaflet throws reading .lat off an undefined corner. The template's "remove address" links call setPayloadPlace(prop, null), so a customer clearing their only address takes the exception. The fix is a one-line return, left for Ron. The defect could not be pinned by a test: the throw escapes Ember's error handling — it neither rejects the click promise nor reaches setupOnerror, because Leaflet throws from flyToBounds' own animation frame. That path is left uncovered and the DEFECTS entry carries the testing note. create-order-form.js 75/395 -> 124/395 stmts, 17/197 -> 38/197 branches, 12/67 -> 23/67 functions Totals statements 6891 -> 6945 (37.43%) branches 4510 -> 4530 (37.69%) functions 1959 -> 1972 lines 6524 -> 6576 Tests 1404 -> 1405, passing 1322 -> 1323; failures unchanged at 82.
ember-ui's Toggle renders a <span role="checkbox" aria-checked> — neither a button nor an input, which is why an earlier probe missed it. Three tests: switching multiple-dropoffs on adds the first waypoint row; a waypoint takes a place through its own select, a second is added and one of the two removed; and proof of delivery takes `scan` by default and gives it up when switched off. DEFECTS #95 (OPEN), found while reading: clearWaypoints calls this.previewRoute(false), and previewRoute is not defined anywhere in the file — one call site, no declaration, no mixin supplying it. Since isViewingRoutePreview is set by previewDraftOrderRoute, turning multiple-dropoffs off after entering any waypoint address throws, leaves the waypoints uncleared and the pickup/dropoff half-applied. The intended call is almost certainly removeRoutingControlPreview(). Two live defects in this component now (#94, #95) shape how it can be tested: anything reaching previewDraftOrderRoute with nothing to route hits #94, so the removal test starts from two waypoints, and the multi-drop off path cannot be driven until #95 is fixed. create-order-form.js 124/395 -> 162/395 stmts, 38/197 -> 51/197 branches, 23/67 -> 31/67 functions Totals statements 6945 -> 6979 (37.62%) branches 4530 -> 4544 (37.80%) functions 1972 -> 1979 lines 6576 -> 6608 Tests 1405 -> 1408, passing 1323 -> 1326; failures unchanged at 82.
Four tests over createOrder: submitting with no route does nothing and
says nothing, since isValid refuses silently and the disabled controls
are the only feedback; a routed order saves once, fires the creating and
created universe events, is tracked, and is handed back through
@onOrderCreated; custom fields that fail validation stop the submission
and list every missing field in one message; and a save the server
refuses is reported with the order kept and no created event.
Harness: the custom-fields stand-in now answers validateRequired() and
saveTo(), the universe and events stubs record what they are told, and
order.save is overridden on the record itself rather than through an
adapter — the component calls it directly.
create-order-form.js 162/395 -> 202/395 stmts, 51/197 -> 68/197 branches,
31/67 -> 34/67 functions
Totals statements 6979 -> 7019 (37.83%) branches 4544 -> 4561 (37.95%)
functions 1979 -> 1982 lines 6608 -> 6647
Tests 1408 -> 1412, passing 1326 -> 1330; failures unchanged at 82.
Four tests over getQuotes: a routed order asks service-quotes/preliminary once there are two coordinates and normalises the response into records; a response that is not a list is taken as no quotes rather than an error; a refused request is reported; and no quotes are asked for while a checkout session is being completed, which also brought restoreFromServiceQuote into coverage. DEFECTS #96 (OPEN), found while reading: the quote request body includes a `service` key that is not a local. There is no declaration anywhere in the file — the only `service` in scope is line 4's `import { inject as service }`, so the request sends Ember's inject decorator, JSON drops it, and the field never reaches the wire. No linter catches it: no-undef is satisfied by the import and no-unused-vars sees it used. The test pins it with typeof body.service === 'function'. That is the third live defect in this component (#94, #95, #96), all found by reading or by asserting what the code does, all recorded rather than fixed. create-order-form.js 202/395 -> 231/395 stmts, 68/197 -> 93/197 branches Totals statements 7019 -> 7049 (37.99%) branches 4561 -> 4586 (38.15%) functions 1982 -> 1983 lines 6647 -> 6677 Tests 1412 -> 1416, passing 1330 -> 1334; failures unchanged at 82.
…locked An honest no-progress iteration on coverage. create-order-form.js is unchanged at 231/395 statements — the one test that landed asserts real behaviour (returning from a checkout puts up a dialog that cannot be dismissed by clicking away) but crosses only lines the previous iteration already reached. Three of the four tests I set out to write do not work yet. isPaymentRequired() needs four conditions, and from the test's side all four hold — verified by probe. The branch is still not taken. Two candidates remain and I did not separate them: the addon's ember-get-config may not be the module instance the test mutates, or selectedServiceQuote may not survive the quote round-trip. The ledger records both and the cheapest experiment to tell them apart. One real cause was found and fixed on the way: getQuotes reads serviceQuotes.firstObject, so a plain array response leaves selectedServiceQuote unset silently. Quote fixtures now use A([...]). Totals statements 7049 -> 7048 branches 4586 -> 4585 lines 6677 -> 6676 Tests 1416 -> 1417, passing 1334 -> 1335; failures unchanged at 82.
Four tests: returned quotes render as a radio group with the first chosen; a dropped file is queued, uploaded under the order-files path and attached on success; a file already sent is ignored while a failed one is retried and then dropped from the queue; and editing an item opens the entity modal, whose uploadNewPhoto holds a new item's photo aside and shows it from an object URL. Closes the iteration-68 blocker as untestable (DEFECTS #97). Both candidates are eliminated: the radio-group test proves selectedServiceQuote is set, and config was never at fault — dummy/config sets stripe.publishableKey to '', and typeof '' === 'string' passes that conjunct unaided, so last iteration's config mutation was wasted effort. What remains is paymentsEnabled/paymentsOnboardCompleted, which the template never references, so no rendering test can observe them. The block stays uncovered with the trace recorded. create-order-form.js 231/395 -> 249/395 stmts, 93/197 -> 99/197 branches, 35/67 -> 40/67 functions Totals statements 7048 -> 7066 (38.09%) branches 4585 -> 4592 (38.20%) functions 1983 -> 1988 lines 6676 -> 6693 Tests 1417 -> 1421, passing 1335 -> 1339; failures unchanged at 82.
Seven tests over `restoreFromServiceQuote` and the item surface it unlocks. The restore path is the only way a *saved* entity reaches `this.entities` (`addEntity` only ever createRecords), so `removeEntity`'s destroyRecord arm and `editEntity`'s immediate-upload arm had to come with it rather than as a separate batch. Found while writing the harness — DEFECTS #98: `confirm` replays a new item's held-back photo with `modal.invoke('uploadNewPhoto', pendingFileUpload)`, but `invoke`'s second positional is `modalId`, so no modal is found and the callback never runs. The photo is silently dropped. Recorded, not fixed; the test asserts current behaviour and names the entry. create-order-form.js 249/395 -> 301/395 statements, 99/197 -> 127/197 branches, 40/67 -> 48/67 functions. Global: statements 7066 -> 7118 (38.36%), branches 4592 -> 4620, functions 1988 -> 1996, lines 6693 -> 6744. Tests 1421 -> 1428; failures unchanged at 82, none new. Lint 0.
Seven tests: switching the order type, the overlay cancel, editing a chosen address, reordering stops (and the no-op drop), the map's re-centre down both the single-point and fitted arms, deleting an attached file, and the quote payload's per-model serialisation. Two wrong assumptions the tests caught: only configs named by the settings call are offered, and `sortWaypoints` redraws the preview without re-pricing. Also §4, in the source: `isServicable` deleted (DEFECTS #99) — its only apparent caller reads `order/form/service-rate.js`'s own same-named getter. `createPlace` pragma'd, not deleted (DEFECTS #100, NEEDS DECISION) — nothing reaches it, but whether the form should offer "new address" is a product call. Both landed on uncovered code: denominators fell 395->392 statements and 67->65 functions while covered held. create-order-form.js 301/395 -> 321/392 statements, 127/197 -> 137/197 branches, 48/67 -> 56/65 functions. Global: statements 7118 -> 7138 (38.47%), branches 4620 -> 4630, functions 1996 -> 2004, lines 6744 -> 6763. Tests 1428 -> 1435; failures unchanged at 82, none new. Lint 0.
`createResponsiveHandler` registered a window `resize` listener as an inline arrow and the component had no `willDestroy`, so it outlived the component. The `if (!this.el) return` guard never fired because `el` was never cleared, leaving a detached element whose `parentElement` is null — `getFullGridSize` then threw on `parentElement.offsetWidth`. Latent until now: nothing in the suite could construct a `JointGraph`, because `joint` was undefined in the dummy app. Once it could, two unrelated `operations-monitor` tests went red — they are the next tests that dispatch a window resize. Stores the handler, removes it and nulls `el` in `willDestroy`, and also guards on `parentElement` so a detached element is skipped rather than throwing. DEFECTS #101.
…ad JointJS `index.js` copies `@joint/core` into the *host* app's public tree, so a real app has `joint` on the global before the engine boots. The dummy app has no host, so `joint` was undefined and neither `joint-graph.js` nor any of `activity-flow.js` could execute. One `app.import` in `ember-cli-build.js` fixes that, the same way Leaflet is already handled there; it builds only the dummy app and leaves the published addon untouched. Nothing about JointJS is stubbed — the tests drive a real paper and graph. Six tests: the default flow, a saved flow, zoom in/out including both limits, reset, save (children serialised by code, no node on the wire), and redraw on `onConfigChanged`. Retires one of the blueprint scaffolds from DEFECTS #4. activity-flow.js 0/369 -> 283/369 statements, 0/179 -> 107/179 branches, 0/79 -> 56/79 functions; joint-graph.js 0 -> 39/56. Global: statements 7138 -> 7438 (40.08%), branches 4630 -> 4742, functions 2004 -> 2062, lines 6763 -> 7061. Tests 1435 -> 1440; failures 82 -> 81, none new. Lint 0.
Ten tests over everything iteration 72 did not touch: opening an activity in the context panel, the immutable / core_service / permission guards, the add tool and its duplicate-code refusal, closing without saving, the remove tool (proved through a follow-up save, not just the drawing), the two-way scrollbar sync, and an activity opened by @context. The element tools are real `joint.elementTools` in the SVG and the tests click the actual markup; the context-panel stand-in keeps each definition so the component's own saveTask and onClose closures are what run. One wrong assumption corrected: `deserializeActivity` regenerates `internalId` on every deserialise, so it cannot be learned by rendering twice — a saved flow carries its own ids, which is how the real round-trip works. activity-flow.js 283/369 -> 352/369 statements, 107/179 -> 137/179 branches, 56/79 -> 77/79 functions. Global: statements 7438 -> 7508 (40.46%), branches 4742 -> 4772, functions 2062 -> 2084, lines 7061 -> 7125. Tests 1440 -> 1450; failures unchanged at 81, none new. Lint 0.
Seventeen unit tests over the scheduler controller: active and unscheduled orders, the sidebar search and its debounce, the type filter, driver rows and workload bars, the resource-label and event-tile HTML, selection, the view-range mapping, and calendar navigation (including with no calendar attached, which is the state before the template mounts). A unit test rather than a rendering one: the controller only ever talks to @event-calendar/core through setOption/getOption/prev/next, so a stand-in for that API exercises its own logic without pretending to run the calendar. Three findings, recorded not fixed. DEFECTS #102: `driver.max_daily_orders` appears on one line in the whole codebase and is not an attribute, so every capacity bar is measured against 10. #103: the priority filter reads `o.priority`, which OrderModel does not have. #104 (NEEDS DECISION): nothing ever assigns to `activeFilters`, so the filter block never runs at all — which is why #103 is harmless today. scheduler/index.js 0/325 -> 94/325 statements, 0/197 -> 55/197 branches, 0/79 -> 43/79 functions; create-full-calendar-event-from-order.js and to-calendar-date.js now fully covered. Global: statements 7508 -> 7609 (41.00%), branches 4772 -> 4834, functions 2084 -> 2128, lines 7125 -> 7210. Tests 1450 -> 1467; failures unchanged at 81, none new. Lint 0.
Twenty-three more unit tests: dragging a card from the sidebar, the drag-over highlight and drop cursor, leaving versus moving onto a child, and the drop — assigned to the row it landed on at the wall-clock time it was dropped at. Then every refusal (nothing dragged, no calendar, an unplaceable point, no driver row, a scheduler refusal, a clash). Rescheduling covers the same outcomes plus the shift-block arm. Sockets open one company channel and one per driver, and the handlers are invoked rather than just captured. The timezone assertions pin real instants — 22:30 in Asia/Singapore is 14:30Z — so an inverted conversion fails rather than passing quietly. Two fixtures of mine were wrong, neither a product bug: a timeline event always carries a resourceId, and `scheduler.shift-updated` does resolve. scheduler/index.js 94/325 -> 240/325 statements, 55/197 -> 126/197 branches, 43/79 -> 65/79 functions. Global: statements 7609 -> 7755 (41.79%), branches 4834 -> 4905, functions 2128 -> 2150, lines 7210 -> 7342. Tests 1467 -> 1490; failures unchanged at 81, none new. Lint 0.
Thirty-three tests. The modal block: opening an order, rescheduling from a date or a picker wrapper, saving (success, info when the date is cleared, a straight close when nothing changed, a refusal that keeps the modal open), unscheduling, the shift modal's save and delete including both failures, one-off and recurring shifts (new schedule and reusing an existing one), bulk assign, and the conflict modal's assignAnyway/autoAdjust. Then the residue: four statements were `@tracked` initialisers nothing reads, and thirty branches were sparse-data fallbacks — no id or tracking, no workload, an order answering through get(), a timeline with no inner grid or none at all, an event dragged off every resource row. The last branch is genuinely unreachable — DEFECTS #105. `formatToParts` is built from a literal options object requesting exactly the six types the helper asks for, so the `?? '0'` cannot run. Hoisted into a local const so the pragma attaches, with the trace in the comment. Behaviour unchanged. scheduler/index.js 240/325 -> 326/326 statements, 126/197 -> 195/195 branches, 65/79 -> 79/79 functions, 290/290 lines. Global: statements 7755 -> 7841 (42.25%), branches 4905 -> 4974, functions 2150 -> 2164, lines 7342 -> 7422. Fully covered files 312 -> 313. Tests 1490 -> 1523; failures unchanged at 81, none new. Lint 0.
Twenty-four tests replacing the blueprint scaffold. The component has two provider branches behind one class; the Google branch renders a single child, so standing that in reaches the lifecycle, load task and resource handlers without ember-leaflet or a real map. Covers the provider switch, initial position, zoom validation, the geofence subscription (company known at construction and arriving later), location updates, teardown of all four listeners, the load task and its permission and failure paths, bounds serialised from all three provider shapes plus four unusable ones, resources arriving with their layers, panel clicks, and the viewport-reload locks. Most of the time went on the harness: 21 injected services, and two of the gaps failed *silently* — an adapter with no `getBounds` (load falls through to `this.map.getBounds()` when the manager reports none) and a geofence stub with no `toggleDrawControl` (bound while building the context menu). Both throws are swallowed by `load`'s own try/catch. The universe event trail localises them. Checked before claiming: neither is a product bug. Also fixed two assertions of mine that compared a value with itself and could not fail. leaflet-live-map.js 39/345 -> 162/345 statements, 10/201 -> 85/201 branches, 4/70 -> 22/70 functions. Global: statements 7841 -> 7957 (42.87%), branches 4974 -> 5045, functions 2164 -> 2180, lines 7422 -> 7533. Tests 1523 -> 1546; failures 81 -> 80, none new. Lint 0.
Thirteen tests: the Leaflet branch registering its map with both managers, viewport watching and unwatching, the tile URL, the draw control and feature group, then the context menus — the map menu, driver and vehicle menus including items registered through menuService, and the service-area and zone menus with their edit and delete callbacks driven through to what they remove. A build change I made and reverted: `app.import`ing leaflet-draw and leaflet-contextmenu made the branch render, and broke fourteen existing map-adapter/leaflet tests — leaflet-draw 1.0.4 against Leaflet 1.9 leaves `layer.editing` without `enabled()`, and those tests had only run with the plugin absent. Rather than patch Leaflet globally to chase coverage, the test file now sets just the four readiness markers the component reads and restores the global afterwards. Same coverage, nothing else affected. The lazy-argument trap again: a layer stand-in that accepts `@url` without rendering it never causes `tileUrl` to be computed, so the getter reads as dead code. The stand-in has to consume it. leaflet-live-map.js 162/345 -> 254/345 statements, 85/201 -> 113/201 branches, 22/70 -> 40/70 functions. Global: statements 7957 -> 8049 (43.37%), branches 5045 -> 5073, functions 2180 -> 2198 (40.08%), lines 7533 -> 7622. Tests 1546 -> 1559; failures unchanged at 80, none new. Lint 0.
Ten tests: the driver and vehicle context-menu callbacks driven through to the panels and action services they call, a menu item registered elsewhere invoked with its resource and layer, the geofence enter/exit flashes, the viewport reload (only the spatially-filtered resources, the suspend/resume lock, and unusable bounds), and the plugin-loading path. `#flashGeofenceLayer` restores its style through a raw setTimeout guarded by `if (!layer._map) return`. Rather than add a second two-second wait to reach that guard, `eachLayer` yields two layers for the same geofence — one attached, one already removed — so one waitUntil proves both arms: the attached layer goes back to its drawn colours, the removed one is never restyled. leaflet-live-map.js 254/345 -> 296/345 statements, 113/201 -> 134/201 branches, 40/70 -> 53/70 functions. Global: statements 8049 -> 8091 (43.60%), branches 5073 -> 5094, functions 2198 -> 2211, lines 7622 -> 7661. Tests 1559 -> 1569; failures unchanged at 80, none new. Lint 0.
Nine tests: markers vs polygons on registration, re-centring on user.located, the service-area menu's blur/create-zone/edit-boundaries callbacks (and edit-boundaries correctly absent on Google Maps), the zone menu's boundary editing, a zone in a plain array removed through `set`, and loadResource's onLoaded/onFailure options — no in-repo caller, but reachable through the component published on the universe, so covered as an extension would. DEFECTS #106: `#getValidLatitude` and `#getValidLongitude` each appear exactly once — their own declarations — and are never called. The constructor reads `location.getLatitude()` raw, while the line above it wires the sibling `getValidZoom()`. A NaN or out-of-range coordinate reaches Leaflet as the map centre and the fallback is dead. Two lines would fix it, but that is a behaviour change; recorded, pragma'd with the trace, and the test pins current behaviour so the fix has an assertion to update. leaflet-live-map.js 296/345 -> 304/345 statements, 134/201 -> 141/201 branches, 53/70 -> 57/70 functions. Global: statements 8091 -> 8099 (43.64%), branches 5094 -> 5101, functions 2211 -> 2215, lines 7661 -> 7669. Tests 1569 -> 1578; failures unchanged at 80, none new. Lint 0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Drives
addon/toward 100% coverage behind a per-file gate, with the LCOV uploaded to Codecov under afrontendflag.This is a draft: the gate is still red on purpose.
pnpm run test:ciexits 1 because the campaign is not finished — 83 blueprintit rendersscaffolds have never been green (DEFECTS #4) and coverage is at 32%, not 100%. The branch is green in the sense that matters day to day: no test that passes today fails because of this work, and every iteration has been verified against a full run.Where it stands
309 files are at 100% on all four metrics. 69 commits: 48 test, 21 fix.
What is in it
Phase A — the gate.
ember-cli-code-coverage+ember-window-mock, coverage config with the pnpm-symlink excludes,stamp-coverage-run/check-coverage/check-coverage-test, theTestem.afterTestsupload (a plainQUnit.donetruncates the multi-MB POST size-dependently), thetest:ciscript set,codecov.ymlwithbackendandfrontendflags both carrying forward, and theTest with coveragejob. The gate enforces 100% on all four metrics per file, that every eligibleaddon/file appears in the report, and that the artifacts came from the run that just finished.Getting the baseline honest. It started at 775/827 red. Eight harness root causes are fixed and recorded (undeclared
tracked-built-ins, host-console module shims, initializer test paths, ember-intl locale hydration, a missing dummy model, testem'sbail_on_uncaught_error,fetch'sconfig.API).Phase B — the grind, file by file with each batch slice-verified before commit.
Production fixes found while covering
21 of them, each in its own commit, never bundled into a coverage commit. A representative few:
fix(order)— the route-optimization error reached nobody: the component calledintl.t(...)in a catch without injectingintl, and asked for a key that does not exist. Two commits.fix(map)— the device drawer showed the wrong list, and its Device column opened a panel bound to the event rather than the device.fix(order)— every selected document uploaded twice; the tracking lookup form reloaded the page; the active tracking stop matched on undefined ids.fix(components)— seven components had noapp/re-export at all, so the resolver could not find them; four app-tree templates were shadowing the addon's co-located ones.fix(vehicle,driver)— 23 form fields ignored the write permission.fix(map)—assignPanehanded a layer the whole{ pane, paneName }pair where Leaflet wants the name.Decisions waiting on you
DEFECTS.mdcarries the full worklist. Three entries are genuinely yours to call, and I have not picked for you:custom-entity/form— the image upload reads a config nothing provides, and the dasherized type never sticks.services/leaflet-draw-restriction.js— an entire service with no consumer anywhere inaddon/, readingthis.mapandthis.notificationsit never declares, so its guards cannot bind and its six user-facing warnings are all no-ops. Wire it up or delete it.One more is outside this package: #75, six
fleetops-datamodels declare acustom-field-valuerelationship no package defines. Worked around in the dummy app so the suite can run.Reviewing
The per-iteration ledger is
COVERAGE-PROGRESS.md— numbers, what each batch covered, and the traps found.DEFECTS.mdis the worklist, in the format the ember-ui campaign used: every unreachable-code claim is traced to the caller, template or constant that closes it off, never "appears unused".