TypeScript 87.7%
CSS 12.3%
1/**2 * Author: Simon-Pierre Boucher3 * Contact: contact@spboucher.ai4 * Project: Groupe Ka / Ka Maps5 */67import { describe, expect, it } from "vitest";8import {9 computeLensStats,10 propertiesInBBox,11 propertiesInPolygon,12} from "../src/utils/lens.js";13import type { MapProperty } from "../src/types/index.js";1415function prop(over: Partial<MapProperty>): MapProperty {16 return {17 id: over.id ?? Math.random().toString(36),18 appSource: "lou-ka",19 latitude: 46.8,20 longitude: -71.2,21 kind: "listing",22 ...over,23 };24}2526describe("computeLensStats", () => {27 it("computes medians and type mix from real fields only", () => {28 const stats = computeLensStats([29 prop({ price: 300_000, propertyType: "Maison", daysOnMarket: 10 }),30 prop({ price: 500_000, propertyType: "Maison", daysOnMarket: 100 }),31 prop({ price: 700_000, propertyType: "Condo", priceChange: -0.05 }),32 ]);33 expect(stats.count).toBe(3);34 expect(stats.medianPrice).toBe(500_000);35 expect(stats.medianDaysOnMarket).toBe(55);36 expect(stats.stale90dShare).toBe(0.5);37 expect(stats.priceCutShare).toBeCloseTo(1 / 3);38 expect(stats.typeMix?.["Maison"]).toBeCloseTo(2 / 3);39 // pas de valeurs estimées dans les données → pas de médiane inventée40 expect(stats.medianEstimatedValue).toBeUndefined();41 });4243 it("returns bare count on empty/opaque data", () => {44 const stats = computeLensStats([]);45 expect(stats).toEqual({ count: 0 });46 });47});4849describe("geographic selection", () => {50 const items = [51 prop({ id: "in", latitude: 46.8, longitude: -71.2 }),52 prop({ id: "out", latitude: 45.5, longitude: -73.6 }),53 ];5455 it("filters by bbox", () => {56 const sel = propertiesInBBox(items, {57 west: -71.4,58 south: 46.7,59 east: -71.0,60 north: 46.9,61 });62 expect(sel.map((p) => p.id)).toEqual(["in"]);63 });6465 it("filters by polygon (ray casting)", () => {66 const sel = propertiesInPolygon(items, {67 type: "Polygon",68 coordinates: [[[-71.4, 46.7], [-71.0, 46.7], [-71.0, 46.9], [-71.4, 46.9], [-71.4, 46.7]]],69 });70 expect(sel.map((p) => p.id)).toEqual(["in"]);71 });72});73