mirror of
https://github.com/Permissionless-Software-Foundation/psf-memo.git
synced 2026-09-21 16:52:01 -07:00
- Replace the ternary follower delta in recordTopicFollow with Number(isActive) - Number(wasActive), dropping its cyclomatic complexity from 8 to 6 (CRAP 8.0 -> 6.0). No behavior change. - Extend the indexer topic property test to conserve lastSeen (newest post time) and followerCount (each address's final active follow state) alongside postCount/lastHeight, with varying post seen times. - Extend the DB backfill and topic-query property tests to conserve lastSeen and followerCount; generated follows now include unfollows. - Add a client topic-metadata property test covering relativeTime bucket classification, pluralization, monotonicity, and getLastSeenLabel consistency, and cover ensureTopicRoom's existing-summary path plus recordTopicFollow's legacy-follower-count fallback. - Share one in-memory DB double per component (indexer test/support/ memory-db.js, DB test/support/level-double.js) and table-drive the parallel topic-follow/topic-message/topic-query cases, clearing every dry4javascript candidate in the changed files. Verification: indexer 113 unit / 12 property / 7 acceptance; db 387 unit / 57 property / 16 acceptance; client 441 unit / 90 property / 33 acceptance + build; lint clean. CRAP max 6.0; mutation scans under 100 sites/file. By refactorer.
65 lines
1.6 KiB
JavaScript
65 lines
1.6 KiB
JavaScript
/*
|
|
In-memory LevelDB double shared by the txid repair and topic index unit and
|
|
property tests.
|
|
|
|
FakeDb implements the get/put/del/iterator surface the libraries use, honors
|
|
the `gte`/`lte`/`limit` iterator options the topic read path relies on, and
|
|
exposes the backing Map as `store` for assertions. makeLevel() wires the same
|
|
store names the real psf-memo-db exposes so the repair library can be driven
|
|
without opening any real LevelDB files.
|
|
*/
|
|
|
|
export class FakeDb {
|
|
constructor (records = []) {
|
|
this.map = new Map(records)
|
|
}
|
|
|
|
get store () {
|
|
return this.map
|
|
}
|
|
|
|
async get (key) {
|
|
if (!this.map.has(key)) {
|
|
const err = new Error(`not found: ${key}`)
|
|
err.notFound = true
|
|
throw err
|
|
}
|
|
return this.map.get(key)
|
|
}
|
|
|
|
async put (key, value) {
|
|
this.map.set(key, value)
|
|
}
|
|
|
|
async del (key) {
|
|
this.map.delete(key)
|
|
}
|
|
|
|
async * iterator (opts = {}) {
|
|
let keys = [...this.map.keys()].sort()
|
|
if (opts.gte !== undefined) keys = keys.filter((key) => key >= opts.gte)
|
|
if (opts.lte !== undefined) keys = keys.filter((key) => key <= opts.lte)
|
|
const limit = opts.limit === undefined ? keys.length : opts.limit
|
|
for (const key of keys.slice(0, limit)) {
|
|
yield [key, this.map.get(key)]
|
|
}
|
|
}
|
|
|
|
keys () {
|
|
return [...this.map.keys()].sort()
|
|
}
|
|
}
|
|
|
|
export function makeLevel () {
|
|
return {
|
|
postsDb: new FakeDb(),
|
|
pollsDb: new FakeDb(),
|
|
likesDb: new FakeDb(),
|
|
postLikesDb: new FakeDb(),
|
|
postParentsDb: new FakeDb(),
|
|
postChildrenDb: new FakeDb(),
|
|
pollOptionsDb: new FakeDb(),
|
|
pollVotesDb: new FakeDb()
|
|
}
|
|
}
|