Cache home location and weather across page navigation
ci-cd / verify (push) Successful in 6s
ci-cd / deploy (push) Skipped

This commit is contained in:
2026-10-05 11:08:11 +08:00
parent 42aea10101
commit f0ee63e642
5 changed files with 205 additions and 57 deletions
+84
View File
@@ -0,0 +1,84 @@
const test = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const vm = require("node:vm");
function runtime(storage = new Map()) {
const counts = { location: 0, request: 0 };
let fail = false;
let release;
const module = { exports: {} };
vm.runInNewContext(fs.readFileSync("pets-fe/utils/environment.js", "utf8"), {
module,
wx: {
getStorageSync: (key) => storage.get(key),
setStorageSync: (key, value) => storage.set(key, value),
getSetting: (opts) => opts.success({ authSetting: {} }),
getLocation: (opts) => {
counts.location++;
opts.success({ latitude: 25, longitude: 102 });
},
},
require: () => ({
secure: async () => {
counts.request++;
if (fail) throw new Error("offline");
if (release) await release;
return {
location_name: "昆明市 · 五华区",
weather: { description: "晴", temperature: "22" },
};
},
}),
});
return {
api: module.exports,
counts,
storage,
fail: () => {
fail = true;
},
hold: (promise) => {
release = promise;
},
};
}
test("页面重建与返回复用同一轮天气请求,点击可以刷新", async () => {
const r = runtime();
let finish;
r.hold(
new Promise((resolve) => {
finish = resolve;
}),
);
const first = r.api.refresh();
assert.equal(r.api.refresh(), first);
finish();
await first;
await r.api.refresh();
await r.api.refresh();
assert.equal(r.counts.location, 1);
assert.equal(r.counts.request, 1);
await r.api.refresh(true);
assert.equal(r.counts.request, 2);
assert.equal(r.api.cached().weatherLabel, "晴 22°C");
const saved = r.storage.get("pet_environment_v1");
assert.equal("latitude" in saved, false);
assert.equal("longitude" in saved, false);
});
test("冷启动先读取上次缓存,再请求一次;失败保留缓存且不会返回就重试", async () => {
const previous = runtime();
await previous.api.refresh();
const next = runtime(previous.storage);
assert.equal(next.api.cached().locationName, "昆明市 · 五华区");
assert.equal(next.counts.request, 0);
next.fail();
await assert.rejects(next.api.refresh(), /offline/);
await assert.rejects(next.api.refresh(), /offline/);
assert.equal(next.counts.request, 1);
assert.equal(next.api.cached().weatherLabel, "晴 22°C");
await assert.rejects(next.api.refresh(true), /offline/);
assert.equal(next.counts.request, 2);
});
+3
View File
@@ -5,6 +5,9 @@ const path = require("node:path");
const apiPath = require.resolve("../pets-fe/utils/api");
function page(name, secure, wx = {}) {
// Each test represents a fresh app session; page navigation within a test
// still shares the environment module.
delete require.cache[require.resolve("../pets-fe/utils/environment")];
global.wx = {
getStorageSync: () => [],
setStorageSync: () => {},
+5 -3
View File
@@ -99,9 +99,11 @@ function home(login, secure) {
definition = value;
},
require: (name) =>
name.includes("date")
? { localDate: () => "2026-10-05" }
: { secure, toast: () => {} },
name.includes("environment")
? { cached: () => null }
: name.includes("date")
? { localDate: () => "2026-10-05" }
: { secure, toast: () => {} },
});
const page = {
...definition,