move to pkg
This commit is contained in:
53
packages/system/tests/NoteCollection.test.ts
Normal file
53
packages/system/tests/NoteCollection.test.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { TaggedRawEvent } from "../src/Nostr";
|
||||
import { describe, expect } from "@jest/globals";
|
||||
import { FlatNoteStore, ReplaceableNoteStore } from "../src/NoteCollection";
|
||||
|
||||
describe("NoteStore", () => {
|
||||
describe("flat", () => {
|
||||
test("one event", () => {
|
||||
const ev = { id: "one" } as TaggedRawEvent;
|
||||
const c = new FlatNoteStore();
|
||||
c.add(ev);
|
||||
expect(c.getSnapshotData()).toEqual([ev]);
|
||||
});
|
||||
test("still one event", () => {
|
||||
const ev = { id: "one" } as TaggedRawEvent;
|
||||
const c = new FlatNoteStore();
|
||||
c.add(ev);
|
||||
c.add(ev);
|
||||
expect(c.getSnapshotData()).toEqual([ev]);
|
||||
});
|
||||
test("clears", () => {
|
||||
const ev = { id: "one" } as TaggedRawEvent;
|
||||
const c = new FlatNoteStore();
|
||||
c.add(ev);
|
||||
expect(c.getSnapshotData()).toEqual([ev]);
|
||||
c.clear();
|
||||
expect(c.getSnapshotData()).toEqual([]);
|
||||
});
|
||||
});
|
||||
describe("replacable", () => {
|
||||
test("one event", () => {
|
||||
const ev = { id: "test", created_at: 69 } as TaggedRawEvent;
|
||||
const c = new ReplaceableNoteStore();
|
||||
c.add(ev);
|
||||
expect(c.getSnapshotData()).toEqual(ev);
|
||||
});
|
||||
test("dont replace with older", () => {
|
||||
const ev = { id: "test", created_at: 69 } as TaggedRawEvent;
|
||||
const evOlder = { id: "test2", created_at: 68 } as TaggedRawEvent;
|
||||
const c = new ReplaceableNoteStore();
|
||||
c.add(ev);
|
||||
c.add(evOlder);
|
||||
expect(c.getSnapshotData()).toEqual(ev);
|
||||
});
|
||||
test("replace with newer", () => {
|
||||
const ev = { id: "test", created_at: 69 } as TaggedRawEvent;
|
||||
const evNewer = { id: "test2", created_at: 70 } as TaggedRawEvent;
|
||||
const c = new ReplaceableNoteStore();
|
||||
c.add(ev);
|
||||
c.add(evNewer);
|
||||
expect(c.getSnapshotData()).toEqual(evNewer);
|
||||
});
|
||||
});
|
||||
});
|
113
packages/system/tests/Query.test.ts
Normal file
113
packages/system/tests/Query.test.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import { Connection } from "../src";
|
||||
import { describe, expect } from "@jest/globals";
|
||||
import { Query } from "../src/Query";
|
||||
import { getRandomValues } from "crypto";
|
||||
import { FlatNoteStore } from "../src/NoteCollection";
|
||||
import { RequestStrategy } from "../src/RequestBuilder";
|
||||
|
||||
window.crypto = {} as any;
|
||||
window.crypto.getRandomValues = getRandomValues as any;
|
||||
|
||||
describe("query", () => {
|
||||
test("progress", () => {
|
||||
const q = new Query("test", new FlatNoteStore());
|
||||
const opt = {
|
||||
read: true,
|
||||
write: true,
|
||||
};
|
||||
const c1 = new Connection("wss://one.com", opt);
|
||||
c1.Down = false;
|
||||
const c2 = new Connection("wss://two.com", opt);
|
||||
c2.Down = false;
|
||||
const c3 = new Connection("wss://three.com", opt);
|
||||
c3.Down = false;
|
||||
|
||||
const f = {
|
||||
relay: "",
|
||||
strategy: RequestStrategy.DefaultRelays,
|
||||
filters: [
|
||||
{
|
||||
kinds: [1],
|
||||
authors: ["test"],
|
||||
},
|
||||
],
|
||||
};
|
||||
const qt1 = q.sendToRelay(c1, f);
|
||||
const qt2 = q.sendToRelay(c2, f);
|
||||
const qt3 = q.sendToRelay(c3, f);
|
||||
|
||||
expect(q.progress).toBe(0);
|
||||
q.eose(qt1!.id, c1);
|
||||
expect(q.progress).toBe(1 / 3);
|
||||
q.eose(qt1!.id, c1);
|
||||
expect(q.progress).toBe(1 / 3);
|
||||
q.eose(qt2!.id, c2);
|
||||
expect(q.progress).toBe(2 / 3);
|
||||
q.eose(qt3!.id, c3);
|
||||
expect(q.progress).toBe(1);
|
||||
|
||||
const qs = {
|
||||
relay: "",
|
||||
strategy: RequestStrategy.DefaultRelays,
|
||||
filters: [
|
||||
{
|
||||
kinds: [1],
|
||||
authors: ["test-sub"],
|
||||
},
|
||||
],
|
||||
};
|
||||
const qt = q.sendToRelay(c1, qs);
|
||||
|
||||
expect(q.progress).toBe(3 / 4);
|
||||
q.eose(qt!.id, c1);
|
||||
expect(q.progress).toBe(1);
|
||||
q.sendToRelay(c2, qs);
|
||||
expect(q.progress).toBe(4 / 5);
|
||||
});
|
||||
|
||||
it("should merge all sub-query filters", () => {
|
||||
const q = new Query("test", new FlatNoteStore());
|
||||
const c0 = new Connection("wss://test.com", { read: true, write: true });
|
||||
q.sendToRelay(c0, {
|
||||
filters: [
|
||||
{
|
||||
authors: ["a"],
|
||||
kinds: [1],
|
||||
},
|
||||
],
|
||||
relay: "",
|
||||
strategy: RequestStrategy.DefaultRelays,
|
||||
});
|
||||
q.sendToRelay(c0, {
|
||||
filters: [
|
||||
{
|
||||
authors: ["b"],
|
||||
kinds: [1, 2],
|
||||
},
|
||||
],
|
||||
relay: "",
|
||||
strategy: RequestStrategy.DefaultRelays,
|
||||
});
|
||||
q.sendToRelay(c0, {
|
||||
filters: [
|
||||
{
|
||||
authors: ["c"],
|
||||
kinds: [2],
|
||||
},
|
||||
],
|
||||
relay: "",
|
||||
strategy: RequestStrategy.DefaultRelays,
|
||||
});
|
||||
|
||||
expect(q.filters).toEqual([
|
||||
{
|
||||
authors: ["a", "b"],
|
||||
kinds: [1],
|
||||
},
|
||||
{
|
||||
authors: ["b", "c"],
|
||||
kinds: [2],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
163
packages/system/tests/RequestBuilder.test.ts
Normal file
163
packages/system/tests/RequestBuilder.test.ts
Normal file
@ -0,0 +1,163 @@
|
||||
import { RelayCache } from "../src/GossipModel";
|
||||
import { RequestBuilder, RequestStrategy } from "../src/RequestBuilder";
|
||||
import { describe, expect } from "@jest/globals";
|
||||
|
||||
const DummyCache = {
|
||||
get: (pk?: string) => {
|
||||
if (!pk) return undefined;
|
||||
|
||||
return [
|
||||
{
|
||||
url: `wss://${pk}.com/`,
|
||||
settings: {
|
||||
read: true,
|
||||
write: true,
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
} as RelayCache;
|
||||
|
||||
describe("RequestBuilder", () => {
|
||||
describe("basic", () => {
|
||||
test("empty filter", () => {
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter();
|
||||
expect(b.buildRaw()).toEqual([{}]);
|
||||
});
|
||||
test("only kind", () => {
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().kinds([0]);
|
||||
expect(b.buildRaw()).toMatchObject([{ kinds: [0] }]);
|
||||
});
|
||||
test("empty authors", () => {
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().authors([]);
|
||||
expect(b.buildRaw()).toMatchObject([{ authors: [] }]);
|
||||
});
|
||||
test("authors/kinds/ids", () => {
|
||||
const authors = ["a1", "a2"];
|
||||
const kinds = [0, 1, 2, 3];
|
||||
const ids = ["id1", "id2", "id3"];
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().authors(authors).kinds(kinds).ids(ids);
|
||||
expect(b.buildRaw()).toMatchObject([{ ids, authors, kinds }]);
|
||||
});
|
||||
test("authors and kinds, duplicates removed", () => {
|
||||
const authors = ["a1", "a2"];
|
||||
const kinds = [0, 1, 2, 3];
|
||||
const ids = ["id1", "id2", "id3"];
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().ids(ids).authors(authors).kinds(kinds).ids(ids).authors(authors).kinds(kinds);
|
||||
expect(b.buildRaw()).toMatchObject([{ ids, authors, kinds }]);
|
||||
});
|
||||
test("search", () => {
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().kinds([1]).search("test-search");
|
||||
expect(b.buildRaw()).toMatchObject([{ kinds: [1], search: "test-search" }]);
|
||||
});
|
||||
test("timeline", () => {
|
||||
const authors = ["a1", "a2"];
|
||||
const kinds = [0, 1, 2, 3];
|
||||
const until = 10;
|
||||
const since = 5;
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().kinds(kinds).authors(authors).since(since).until(until);
|
||||
expect(b.buildRaw()).toMatchObject([{ kinds, authors, until, since }]);
|
||||
});
|
||||
test("multi-filter timeline", () => {
|
||||
const authors = ["a1", "a2"];
|
||||
const kinds = [0, 1, 2, 3];
|
||||
const until = 10;
|
||||
const since = 5;
|
||||
const b = new RequestBuilder("test");
|
||||
b.withFilter().kinds(kinds).authors(authors).since(since).until(until);
|
||||
b.withFilter().kinds(kinds).authors(authors).since(since).until(until);
|
||||
expect(b.buildRaw()).toMatchObject([
|
||||
{ kinds, authors, until, since },
|
||||
{ kinds, authors, until, since },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("diff basic", () => {
|
||||
const rb = new RequestBuilder("test");
|
||||
const f0 = rb.withFilter();
|
||||
|
||||
const a = rb.buildRaw();
|
||||
f0.authors(["a"]);
|
||||
expect(a).toEqual([{}]);
|
||||
|
||||
const b = rb.buildDiff(DummyCache, a);
|
||||
expect(b).toMatchObject([
|
||||
{
|
||||
filters: [{ authors: ["a"] }],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe("build gossip simply", () => {
|
||||
const rb = new RequestBuilder("test");
|
||||
rb.withFilter().authors(["a", "b"]).kinds([0]);
|
||||
|
||||
const a = rb.build(DummyCache);
|
||||
expect(a).toEqual([
|
||||
{
|
||||
strategy: RequestStrategy.AuthorsRelays,
|
||||
relay: "wss://a.com/",
|
||||
filters: [
|
||||
{
|
||||
kinds: [0],
|
||||
authors: ["a"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
strategy: RequestStrategy.AuthorsRelays,
|
||||
relay: "wss://b.com/",
|
||||
filters: [
|
||||
{
|
||||
kinds: [0],
|
||||
authors: ["b"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
describe("build gossip merged similar filters", () => {
|
||||
const rb = new RequestBuilder("test");
|
||||
rb.withFilter().authors(["a", "b"]).kinds([0]);
|
||||
rb.withFilter().authors(["a", "b"]).kinds([10002]);
|
||||
rb.withFilter().authors(["a"]).limit(10).kinds([4]);
|
||||
|
||||
const a = rb.build(DummyCache);
|
||||
expect(a).toEqual([
|
||||
{
|
||||
strategy: RequestStrategy.AuthorsRelays,
|
||||
relay: "wss://a.com/",
|
||||
filters: [
|
||||
{
|
||||
kinds: [0, 10002],
|
||||
authors: ["a"],
|
||||
},
|
||||
{
|
||||
kinds: [4],
|
||||
authors: ["a"],
|
||||
limit: 10,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
strategy: RequestStrategy.AuthorsRelays,
|
||||
relay: "wss://b.com/",
|
||||
filters: [
|
||||
{
|
||||
kinds: [0, 10002],
|
||||
authors: ["b"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
34
packages/system/tests/RequestExpander.test.ts
Normal file
34
packages/system/tests/RequestExpander.test.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { expandFilter } from "../src/RequestExpander";
|
||||
|
||||
describe("RequestExpander", () => {
|
||||
test("expand filter", () => {
|
||||
const a = {
|
||||
authors: ["a", "b", "c"],
|
||||
kinds: [1, 2, 3],
|
||||
ids: ["x", "y"],
|
||||
"#p": ["a"],
|
||||
since: 99,
|
||||
limit: 10,
|
||||
};
|
||||
expect(expandFilter(a)).toEqual([
|
||||
{ authors: "a", kinds: 1, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "a", kinds: 1, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "a", kinds: 2, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "a", kinds: 2, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "a", kinds: 3, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "a", kinds: 3, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "b", kinds: 1, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "b", kinds: 1, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "b", kinds: 2, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "b", kinds: 2, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "b", kinds: 3, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "b", kinds: 3, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "c", kinds: 1, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "c", kinds: 1, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "c", kinds: 2, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "c", kinds: 2, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "c", kinds: 3, ids: "x", "#p": "a", since: 99, limit: 10 },
|
||||
{ authors: "c", kinds: 3, ids: "y", "#p": "a", since: 99, limit: 10 },
|
||||
]);
|
||||
});
|
||||
});
|
23
packages/system/tests/RequestMatcher.test.ts
Normal file
23
packages/system/tests/RequestMatcher.test.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { eventMatchesFilter } from "../src/RequestMatcher";
|
||||
|
||||
describe("RequestMatcher", () => {
|
||||
it("should match simple filter", () => {
|
||||
const ev = {
|
||||
id: "test",
|
||||
kind: 1,
|
||||
pubkey: "pubkey",
|
||||
created_at: 99,
|
||||
tags: [],
|
||||
content: "test",
|
||||
sig: "",
|
||||
};
|
||||
const filter = {
|
||||
ids: ["test"],
|
||||
authors: ["pubkey", "other"],
|
||||
kinds: [1, 2, 3],
|
||||
since: 1,
|
||||
before: 100,
|
||||
};
|
||||
expect(eventMatchesFilter(ev, filter)).toBe(true);
|
||||
});
|
||||
});
|
110
packages/system/tests/RequestMerger.test.ts
Normal file
110
packages/system/tests/RequestMerger.test.ts
Normal file
@ -0,0 +1,110 @@
|
||||
import { ReqFilter } from "../src";
|
||||
import { filterIncludes, flatMerge, mergeSimilar, simpleMerge } from "../src/RequestMerger";
|
||||
import { FlatReqFilter, expandFilter } from "../src/RequestExpander";
|
||||
import { distance } from "../src/Util";
|
||||
|
||||
describe("RequestMerger", () => {
|
||||
it("should simple merge authors", () => {
|
||||
const a = {
|
||||
authors: ["a"],
|
||||
} as ReqFilter;
|
||||
const b = {
|
||||
authors: ["b"],
|
||||
} as ReqFilter;
|
||||
|
||||
const merged = mergeSimilar([a, b]);
|
||||
expect(merged).toEqual([
|
||||
{
|
||||
authors: ["a", "b"],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("should append non-mergable filters", () => {
|
||||
const a = {
|
||||
authors: ["a"],
|
||||
} as ReqFilter;
|
||||
const b = {
|
||||
authors: ["b"],
|
||||
} as ReqFilter;
|
||||
const c = {
|
||||
limit: 5,
|
||||
authors: ["a"],
|
||||
};
|
||||
|
||||
const merged = mergeSimilar([a, b, c]);
|
||||
expect(merged).toEqual([
|
||||
{
|
||||
authors: ["a", "b"],
|
||||
},
|
||||
{
|
||||
limit: 5,
|
||||
authors: ["a"],
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("filterIncludes", () => {
|
||||
const bigger = {
|
||||
authors: ["a", "b", "c"],
|
||||
since: 99,
|
||||
} as ReqFilter;
|
||||
const smaller = {
|
||||
authors: ["c"],
|
||||
since: 100,
|
||||
} as ReqFilter;
|
||||
expect(filterIncludes(bigger, smaller)).toBe(true);
|
||||
});
|
||||
|
||||
it("simpleMerge", () => {
|
||||
const a = {
|
||||
authors: ["a", "b", "c"],
|
||||
since: 99,
|
||||
} as ReqFilter;
|
||||
const b = {
|
||||
authors: ["c", "d", "e"],
|
||||
since: 100,
|
||||
} as ReqFilter;
|
||||
expect(simpleMerge([a, b])).toEqual({
|
||||
authors: ["a", "b", "c", "d", "e"],
|
||||
since: 100,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("flatMerge", () => {
|
||||
it("should flat merge simple", () => {
|
||||
const input = [
|
||||
{ ids: 0, authors: "a" },
|
||||
{ ids: 0, authors: "b" },
|
||||
{ kinds: 1 },
|
||||
{ kinds: 2 },
|
||||
{ kinds: 2 },
|
||||
{ ids: 0, authors: "c" },
|
||||
{ authors: "c", kinds: 1 },
|
||||
{ authors: "c", limit: 100 },
|
||||
{ ids: 1, authors: "c" },
|
||||
] as Array<FlatReqFilter>;
|
||||
const output = [
|
||||
{ ids: [0], authors: ["a", "b", "c"] },
|
||||
{ kinds: [1, 2] },
|
||||
{ authors: ["c"], kinds: [1] },
|
||||
{ authors: ["c"], limit: 100 },
|
||||
{ ids: [1], authors: ["c"] },
|
||||
] as Array<ReqFilter>;
|
||||
|
||||
expect(flatMerge(input)).toEqual(output);
|
||||
});
|
||||
|
||||
it("should expand and flat merge complex same", () => {
|
||||
const input = [
|
||||
{ kinds: [1, 6969, 6], authors: ["kieran", "snort", "c", "d", "e"], since: 1, until: 100 },
|
||||
{ kinds: [4], authors: ["kieran"] },
|
||||
{ kinds: [4], "#p": ["kieran"] },
|
||||
{ kinds: [1000], authors: ["snort"], "#p": ["kieran"] },
|
||||
] as Array<ReqFilter>;
|
||||
|
||||
const dut = flatMerge(input.flatMap(expandFilter).sort(() => (Math.random() > 0.5 ? 1 : -1)));
|
||||
expect(dut.every(a => input.some(b => distance(b, a) === 0))).toEqual(true);
|
||||
});
|
||||
});
|
87
packages/system/tests/RequestSplitter.test.ts
Normal file
87
packages/system/tests/RequestSplitter.test.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import { ReqFilter } from "../src";
|
||||
import { describe, expect } from "@jest/globals";
|
||||
import { diffFilters } from "../src/RequestSplitter";
|
||||
|
||||
describe("RequestSplitter", () => {
|
||||
test("single filter add value", () => {
|
||||
const a: Array<ReqFilter> = [{ kinds: [0], authors: ["a"] }];
|
||||
const b: Array<ReqFilter> = [{ kinds: [0], authors: ["a", "b"] }];
|
||||
const diff = diffFilters(a, b);
|
||||
expect(diff).toEqual({
|
||||
added: [{ kinds: [0], authors: ["b"] }],
|
||||
removed: [],
|
||||
changed: true,
|
||||
});
|
||||
});
|
||||
test("single filter remove value", () => {
|
||||
const a: Array<ReqFilter> = [{ kinds: [0], authors: ["a"] }];
|
||||
const b: Array<ReqFilter> = [{ kinds: [0], authors: ["b"] }];
|
||||
const diff = diffFilters(a, b);
|
||||
expect(diff).toEqual({
|
||||
added: [{ kinds: [0], authors: ["b"] }],
|
||||
removed: [{ kinds: [0], authors: ["a"] }],
|
||||
changed: true,
|
||||
});
|
||||
});
|
||||
test("single filter change critical key", () => {
|
||||
const a: Array<ReqFilter> = [{ kinds: [0], authors: ["a"], since: 100 }];
|
||||
const b: Array<ReqFilter> = [{ kinds: [0], authors: ["a", "b"], since: 101 }];
|
||||
const diff = diffFilters(a, b);
|
||||
expect(diff).toEqual({
|
||||
added: [{ kinds: [0], authors: ["a", "b"], since: 101 }],
|
||||
removed: [{ kinds: [0], authors: ["a"], since: 100 }],
|
||||
changed: true,
|
||||
});
|
||||
});
|
||||
test("multiple filter add value", () => {
|
||||
const a: Array<ReqFilter> = [
|
||||
{ kinds: [0], authors: ["a"] },
|
||||
{ kinds: [69], authors: ["a"] },
|
||||
];
|
||||
const b: Array<ReqFilter> = [
|
||||
{ kinds: [0], authors: ["a", "b"] },
|
||||
{ kinds: [69], authors: ["a", "c"] },
|
||||
];
|
||||
const diff = diffFilters(a, b);
|
||||
expect(diff).toEqual({
|
||||
added: [
|
||||
{ kinds: [0], authors: ["b"] },
|
||||
{ kinds: [69], authors: ["c"] },
|
||||
],
|
||||
removed: [],
|
||||
changed: true,
|
||||
});
|
||||
});
|
||||
test("multiple filter remove value", () => {
|
||||
const a: Array<ReqFilter> = [
|
||||
{ kinds: [0], authors: ["a"] },
|
||||
{ kinds: [69], authors: ["a"] },
|
||||
];
|
||||
const b: Array<ReqFilter> = [
|
||||
{ kinds: [0], authors: ["b"] },
|
||||
{ kinds: [69], authors: ["c"] },
|
||||
];
|
||||
const diff = diffFilters(a, b);
|
||||
expect(diff).toEqual({
|
||||
added: [
|
||||
{ kinds: [0], authors: ["b"] },
|
||||
{ kinds: [69], authors: ["c"] },
|
||||
],
|
||||
removed: [{ kinds: [0, 69], authors: ["a"] }],
|
||||
changed: true,
|
||||
});
|
||||
});
|
||||
test("add filter", () => {
|
||||
const a: Array<ReqFilter> = [{ kinds: [0], authors: ["a"] }];
|
||||
const b: Array<ReqFilter> = [
|
||||
{ kinds: [0], authors: ["a"] },
|
||||
{ kinds: [69], authors: ["c"] },
|
||||
];
|
||||
const diff = diffFilters(a, b);
|
||||
expect(diff).toEqual({
|
||||
added: [{ kinds: [69], authors: ["c"] }],
|
||||
removed: [],
|
||||
changed: true,
|
||||
});
|
||||
});
|
||||
});
|
117
packages/system/tests/Util.test.ts
Normal file
117
packages/system/tests/Util.test.ts
Normal file
@ -0,0 +1,117 @@
|
||||
import { distance } from "../src/Util";
|
||||
|
||||
describe("distance", () => {
|
||||
it("should have 0 distance", () => {
|
||||
const a = {
|
||||
ids: "a",
|
||||
};
|
||||
const b = {
|
||||
ids: "a",
|
||||
};
|
||||
expect(distance(a, b)).toEqual(0);
|
||||
});
|
||||
it("should have 1 distance", () => {
|
||||
const a = {
|
||||
ids: "a",
|
||||
};
|
||||
const b = {
|
||||
ids: "b",
|
||||
};
|
||||
expect(distance(a, b)).toEqual(1);
|
||||
});
|
||||
it("should have 10 distance", () => {
|
||||
const a = {
|
||||
ids: "a",
|
||||
};
|
||||
const b = {
|
||||
ids: "a",
|
||||
kinds: 1,
|
||||
};
|
||||
expect(distance(a, b)).toEqual(10);
|
||||
});
|
||||
it("should have 11 distance", () => {
|
||||
const a = {
|
||||
ids: "a",
|
||||
};
|
||||
const b = {
|
||||
ids: "b",
|
||||
kinds: 1,
|
||||
};
|
||||
expect(distance(a, b)).toEqual(11);
|
||||
});
|
||||
it("should have 1 distance, arrays", () => {
|
||||
const a = {
|
||||
since: 1,
|
||||
until: 100,
|
||||
kinds: [1],
|
||||
authors: ["kieran", "snort", "c", "d", "e"],
|
||||
};
|
||||
const b = {
|
||||
since: 1,
|
||||
until: 100,
|
||||
kinds: [6969],
|
||||
authors: ["kieran", "snort", "c", "d", "e"],
|
||||
};
|
||||
expect(distance(a, b)).toEqual(1);
|
||||
});
|
||||
it("should have 1 distance, array change extra", () => {
|
||||
const a = {
|
||||
since: 1,
|
||||
until: 100,
|
||||
kinds: [1],
|
||||
authors: ["f", "kieran", "snort", "c", "d"],
|
||||
};
|
||||
const b = {
|
||||
since: 1,
|
||||
until: 100,
|
||||
kinds: [1],
|
||||
authors: ["kieran", "snort", "c", "d", "e"],
|
||||
};
|
||||
expect(distance(a, b)).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("tryParseNostrLink", () => {
|
||||
it("is a valid nostr link", () => {
|
||||
expect(parseNostrLink("nostr:npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg")).toMatchObject({
|
||||
id: "7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e",
|
||||
type: NostrPrefix.PublicKey,
|
||||
});
|
||||
expect(parseNostrLink("web+nostr:npub10elfcs4fr0l0r8af98jlmgdh9c8tcxjvz9qkw038js35mp4dma8qzvjptg")).toMatchObject({
|
||||
id: "7e7e9c42a91bfef19fa929e5fda1b72e0ebc1a4c1141673e2794234d86addf4e",
|
||||
type: NostrPrefix.PublicKey,
|
||||
});
|
||||
expect(parseNostrLink("nostr:note15449edq4qa5wzgqvh8td0q0dp6hwtes4pknsrm7eygeenhlj99xsq94wu9")).toMatchObject({
|
||||
id: "a56a5cb4150768e1200cb9d6d781ed0eaee5e6150da701efd9223399dff2294d",
|
||||
type: NostrPrefix.Note,
|
||||
});
|
||||
expect(
|
||||
parseNostrLink(
|
||||
"nostr:nprofile1qqsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8gpp4mhxue69uhhytnc9e3k7mgpz4mhxue69uhkg6nzv9ejuumpv34kytnrdaksjlyr9p"
|
||||
)
|
||||
).toMatchObject({
|
||||
id: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
|
||||
type: NostrPrefix.Profile,
|
||||
relays: ["wss://r.x.com", "wss://djbas.sadkb.com"],
|
||||
});
|
||||
expect(parseNostrLink("nostr:nevent1qqs226juks2sw68pyqxtn4khs8ksath9uc2smfcpalvjyvuemlezjngrd87dq")).toMatchObject({
|
||||
id: "a56a5cb4150768e1200cb9d6d781ed0eaee5e6150da701efd9223399dff2294d",
|
||||
type: NostrPrefix.Event,
|
||||
});
|
||||
expect(
|
||||
parseNostrLink(
|
||||
"nostr:naddr1qqzkjurnw4ksz9thwden5te0wfjkccte9ehx7um5wghx7un8qgs2d90kkcq3nk2jry62dyf50k0h36rhpdtd594my40w9pkal876jxgrqsqqqa28pccpzu"
|
||||
)
|
||||
).toMatchObject({
|
||||
id: "ipsum",
|
||||
type: NostrPrefix.Address,
|
||||
relays: ["wss://relay.nostr.org"],
|
||||
author: "a695f6b60119d9521934a691347d9f78e8770b56da16bb255ee286ddf9fda919",
|
||||
kind: 30023,
|
||||
});
|
||||
});
|
||||
test.each(["nostr:npub", "web+nostr:npub", "nostr:nevent1xxx"])("should return false for invalid nostr links", lb => {
|
||||
expect(tryParseNostrLink(lb)).toBeUndefined();
|
||||
});
|
||||
});
|
3
packages/system/tests/setupTests.ts
Normal file
3
packages/system/tests/setupTests.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { TextEncoder, TextDecoder } from "util";
|
||||
|
||||
Object.assign(global, { TextDecoder, TextEncoder });
|
Reference in New Issue
Block a user