Convert all tests to TypeScript
This commit is contained in:
parent
64caef9cda
commit
18e8227123
|
@ -2,7 +2,7 @@
|
|||
"root": true,
|
||||
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"plugins": ["@typescript-eslint", "babel"],
|
||||
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 9,
|
||||
|
@ -18,8 +18,6 @@
|
|||
"node": true
|
||||
},
|
||||
|
||||
"plugins": ["babel"],
|
||||
|
||||
"globals": {
|
||||
"document": false,
|
||||
"navigator": false,
|
||||
|
@ -152,5 +150,13 @@
|
|||
"wrap-iife": [2, "any"],
|
||||
"yield-star-spacing": [2, "both"],
|
||||
"yoda": [0]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.test.ts"],
|
||||
"env": { "jest/globals": true },
|
||||
"plugins": ["jest"],
|
||||
"extends": ["plugin:jest/recommended"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const {
|
||||
import {
|
||||
getBlankEvent,
|
||||
finishEvent,
|
||||
serializeEvent,
|
||||
|
@ -8,7 +8,7 @@ const {
|
|||
getSignature,
|
||||
getPublicKey,
|
||||
Kind
|
||||
} = require('./lib/nostr.cjs')
|
||||
} from '.'
|
||||
|
||||
describe('Event', () => {
|
||||
describe('getBlankEvent', () => {
|
||||
|
@ -97,6 +97,7 @@ describe('Event', () => {
|
|||
}
|
||||
|
||||
expect(() => {
|
||||
// @ts-expect-error
|
||||
serializeEvent(invalidEvent)
|
||||
}).toThrow("can't serialize event with wrong or missing properties")
|
||||
})
|
||||
|
@ -307,6 +308,7 @@ describe('Event', () => {
|
|||
const sig = getSignature(unsignedEvent, privateKey)
|
||||
|
||||
// verify the signature
|
||||
// @ts-expect-error
|
||||
const isValid = verifySignature({
|
||||
...unsignedEvent,
|
||||
sig
|
||||
|
@ -336,6 +338,7 @@ describe('Event', () => {
|
|||
const sig = getSignature(unsignedEvent, wrongPrivateKey)
|
||||
|
||||
// verify the signature
|
||||
// @ts-expect-error
|
||||
const isValid = verifySignature({
|
||||
...unsignedEvent,
|
||||
sig
|
|
@ -1,6 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {fj} = require('./lib/nostr.cjs')
|
||||
import {fj} from '.'
|
||||
|
||||
test('match id', () => {
|
||||
expect(
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {matchFilter, matchFilters} = require('./lib/nostr.cjs.js')
|
||||
import {matchFilter, matchFilters} from '.'
|
||||
import {buildEvent} from './test-helpers'
|
||||
|
||||
describe('Filter', () => {
|
||||
describe('matchFilter', () => {
|
||||
|
@ -14,13 +13,13 @@ describe('Filter', () => {
|
|||
'#tag': ['value']
|
||||
}
|
||||
|
||||
const event = {
|
||||
const event = buildEvent({
|
||||
id: '123',
|
||||
kind: 1,
|
||||
pubkey: 'abc',
|
||||
created_at: 150,
|
||||
tags: [['tag', 'value']]
|
||||
}
|
||||
tags: [['tag', 'value']],
|
||||
})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -30,7 +29,7 @@ describe('Filter', () => {
|
|||
it('should return false when the event id is not in the filter', () => {
|
||||
const filter = {ids: ['123', '456']}
|
||||
|
||||
const event = {id: '789'}
|
||||
const event = buildEvent({id: '789'})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -40,7 +39,7 @@ describe('Filter', () => {
|
|||
it('should return true when the event id starts with a prefix', () => {
|
||||
const filter = {ids: ['22', '00']}
|
||||
|
||||
const event = {id: '001'}
|
||||
const event = buildEvent({id: '001'})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -50,7 +49,7 @@ describe('Filter', () => {
|
|||
it('should return false when the event kind is not in the filter', () => {
|
||||
const filter = {kinds: [1, 2, 3]}
|
||||
|
||||
const event = {kind: 4}
|
||||
const event = buildEvent({kind: 4})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -60,7 +59,7 @@ describe('Filter', () => {
|
|||
it('should return false when the event author is not in the filter', () => {
|
||||
const filter = {authors: ['abc', 'def']}
|
||||
|
||||
const event = {pubkey: 'ghi'}
|
||||
const event = buildEvent({pubkey: 'ghi'})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -70,7 +69,7 @@ describe('Filter', () => {
|
|||
it('should return false when a tag is not present in the event', () => {
|
||||
const filter = {'#tag': ['value1', 'value2']}
|
||||
|
||||
const event = {tags: [['not_tag', 'value1']]}
|
||||
const event = buildEvent({tags: [['not_tag', 'value1']]})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -80,7 +79,7 @@ describe('Filter', () => {
|
|||
it('should return false when a tag value is not present in the event', () => {
|
||||
const filter = {'#tag': ['value1', 'value2']}
|
||||
|
||||
const event = {tags: [['tag', 'value3']]}
|
||||
const event = buildEvent({tags: [['tag', 'value3']]})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -90,7 +89,7 @@ describe('Filter', () => {
|
|||
it('should return true when filter has tags that is present in the event', () => {
|
||||
const filter = {'#tag1': ['foo']}
|
||||
|
||||
const event = {
|
||||
const event = buildEvent({
|
||||
id: '123',
|
||||
kind: 1,
|
||||
pubkey: 'abc',
|
||||
|
@ -99,7 +98,7 @@ describe('Filter', () => {
|
|||
['tag1', 'foo'],
|
||||
['tag2', 'bar']
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -109,7 +108,7 @@ describe('Filter', () => {
|
|||
it('should return false when the event is before the filter since value', () => {
|
||||
const filter = {since: 100}
|
||||
|
||||
const event = {created_at: 50}
|
||||
const event = buildEvent({created_at: 50})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -119,7 +118,7 @@ describe('Filter', () => {
|
|||
it('should return false when the event is after the filter until value', () => {
|
||||
const filter = {until: 100}
|
||||
|
||||
const event = {created_at: 150}
|
||||
const event = buildEvent({created_at: 150})
|
||||
|
||||
const result = matchFilter(filter, event)
|
||||
|
||||
|
@ -135,7 +134,7 @@ describe('Filter', () => {
|
|||
{ids: ['789'], kinds: [3], authors: ['ghi']}
|
||||
]
|
||||
|
||||
const event = {id: '789', kind: 3, pubkey: 'ghi'}
|
||||
const event = buildEvent({id: '789', kind: 3, pubkey: 'ghi'})
|
||||
|
||||
const result = matchFilters(filters, event)
|
||||
|
||||
|
@ -149,7 +148,7 @@ describe('Filter', () => {
|
|||
{ids: ['9'], kinds: [3], authors: ['g']}
|
||||
]
|
||||
|
||||
const event = {id: '987', kind: 3, pubkey: 'ghi'}
|
||||
const event = buildEvent({id: '987', kind: 3, pubkey: 'ghi'})
|
||||
|
||||
const result = matchFilters(filters, event)
|
||||
|
||||
|
@ -163,7 +162,7 @@ describe('Filter', () => {
|
|||
{authors: ['abc'], limit: 3}
|
||||
]
|
||||
|
||||
const event = {id: '123', kind: 1, pubkey: 'abc', created_at: 150}
|
||||
const event = buildEvent({id: '123', kind: 1, pubkey: 'abc', created_at: 150})
|
||||
|
||||
const result = matchFilters(filters, event)
|
||||
|
||||
|
@ -177,7 +176,7 @@ describe('Filter', () => {
|
|||
{ids: ['789'], kinds: [3], authors: ['ghi']}
|
||||
]
|
||||
|
||||
const event = {id: '100', kind: 4, pubkey: 'jkl'}
|
||||
const event = buildEvent({id: '100', kind: 4, pubkey: 'jkl'})
|
||||
|
||||
const result = matchFilters(filters, event)
|
||||
|
||||
|
@ -190,7 +189,7 @@ describe('Filter', () => {
|
|||
{kinds: [1], limit: 2},
|
||||
{authors: ['abc'], limit: 3}
|
||||
]
|
||||
const event = {id: '456', kind: 2, pubkey: 'def', created_at: 200}
|
||||
const event = buildEvent({id: '456', kind: 2, pubkey: 'def', created_at: 200})
|
||||
|
||||
const result = matchFilters(filters, event)
|
||||
|
|
@ -1,16 +1,14 @@
|
|||
/* eslint-env jest */
|
||||
import {generatePrivateKey, getPublicKey} from '.'
|
||||
|
||||
const {generatePrivateKey, getPublicKey} = require('./lib/nostr.cjs')
|
||||
|
||||
test('test private key generation', () => {
|
||||
test('private key generation', () => {
|
||||
expect(generatePrivateKey()).toMatch(/[a-f0-9]{64}/)
|
||||
})
|
||||
|
||||
test('test public key generation', () => {
|
||||
test('public key generation', () => {
|
||||
expect(getPublicKey(generatePrivateKey())).toMatch(/[a-f0-9]{64}/)
|
||||
})
|
||||
|
||||
test('test public key from private key deterministic', () => {
|
||||
test('public key from private key deterministic', () => {
|
||||
let sk = generatePrivateKey()
|
||||
let pk = getPublicKey(sk)
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
/* eslint-env jest */
|
||||
import {nip04, getPublicKey, generatePrivateKey} from '.'
|
||||
import crypto from 'crypto'
|
||||
|
||||
globalThis.crypto = require('crypto')
|
||||
const {nip04, getPublicKey, generatePrivateKey} = require('./lib/nostr.cjs')
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undef
|
||||
globalThis.crypto = crypto
|
||||
|
||||
test('encrypt and decrypt message', async () => {
|
||||
let sk1 = generatePrivateKey()
|
|
@ -1,39 +0,0 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const fetch = require('node-fetch')
|
||||
const {nip05} = require('./lib/nostr.cjs')
|
||||
|
||||
test('fetch nip05 profiles', async () => {
|
||||
nip05.useFetchImplementation(fetch)
|
||||
|
||||
let p1 = await nip05.queryProfile('jb55.com')
|
||||
expect(p1.pubkey).toEqual(
|
||||
'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'
|
||||
)
|
||||
expect(p1.relays).toEqual(['wss://relay.damus.io'])
|
||||
|
||||
let p2 = await nip05.queryProfile('jb55@jb55.com')
|
||||
expect(p2.pubkey).toEqual(
|
||||
'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'
|
||||
)
|
||||
expect(p2.relays).toEqual(['wss://relay.damus.io'])
|
||||
|
||||
let p3 = await nip05.queryProfile('channel.ninja@channel.ninja')
|
||||
expect(p3.pubkey).toEqual(
|
||||
'36e65b503eba8a6b698e724a59137603101166a1cddb45ddc704247fc8aa0fce'
|
||||
)
|
||||
expect(p3.relays).toEqual(undefined)
|
||||
|
||||
let p4 = await nip05.queryProfile('_@fiatjaf.com')
|
||||
expect(p4.pubkey).toEqual(
|
||||
'3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'
|
||||
)
|
||||
expect(p4.relays).toEqual([
|
||||
'wss://relay.nostr.bg',
|
||||
'wss://nos.lol',
|
||||
'wss://nostr-verified.wellorder.net',
|
||||
'wss://nostr.zebedee.cloud',
|
||||
'wss://eden.nostr.land',
|
||||
'wss://nostr.milou.lol',
|
||||
])
|
||||
})
|
|
@ -1,5 +1,3 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
import fetch from 'node-fetch'
|
||||
import {nip05} from '.'
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
const {nip06} = require('./lib/nostr.cjs')
|
||||
import {nip06} from '.'
|
||||
|
||||
test('generate private key from a mnemonic', async () => {
|
||||
const mnemonic = 'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong'
|
|
@ -1,6 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {nip10} = require('./lib/nostr.cjs')
|
||||
import {nip10} from '.'
|
||||
|
||||
describe('parse NIP10-referenced events', () => {
|
||||
test('legacy + a lot of events', () => {
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
const {nip13} = require('./lib/nostr.cjs')
|
||||
import {nip13} from '.'
|
||||
|
||||
test('identifies proof-of-work difficulty', async () => {
|
||||
const id = '000006d8c378af1779d2feebc7603a125d99eca0ccf1085959b307f64e5dd358'
|
|
@ -1,6 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {nip18, finishEvent, getPublicKey, Kind} = require('./lib/nostr.cjs')
|
||||
import {nip18, finishEvent, getPublicKey, Kind} from '.'
|
||||
|
||||
const relayUrl = 'https://relay.example.com'
|
||||
|
||||
|
@ -48,9 +46,9 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
|
||||
const repostedEventPointer = nip18.getRepostedEventPointer(event)
|
||||
|
||||
expect(repostedEventPointer.id).toEqual(repostedEvent.id)
|
||||
expect(repostedEventPointer.author).toEqual(repostedEvent.pubkey)
|
||||
expect(repostedEventPointer.relays).toEqual([relayUrl])
|
||||
expect(repostedEventPointer!.id).toEqual(repostedEvent.id)
|
||||
expect(repostedEventPointer!.author).toEqual(repostedEvent.pubkey)
|
||||
expect(repostedEventPointer!.relays).toEqual([relayUrl])
|
||||
|
||||
const repostedEventFromContent = nip18.getRepostedEvent(event)
|
||||
|
||||
|
@ -60,7 +58,7 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
it('should create a signed event from a filled template', () => {
|
||||
const template = {
|
||||
tags: [['nonstandard', 'tag']],
|
||||
content: '',
|
||||
content: '' as const,
|
||||
created_at: 1617932115
|
||||
}
|
||||
|
||||
|
@ -85,9 +83,9 @@ describe('finishRepostEvent + getRepostedEventPointer + getRepostedEvent', () =>
|
|||
|
||||
const repostedEventPointer = nip18.getRepostedEventPointer(event)
|
||||
|
||||
expect(repostedEventPointer.id).toEqual(repostedEvent.id)
|
||||
expect(repostedEventPointer.author).toEqual(repostedEvent.pubkey)
|
||||
expect(repostedEventPointer.relays).toEqual([relayUrl])
|
||||
expect(repostedEventPointer!.id).toEqual(repostedEvent.id)
|
||||
expect(repostedEventPointer!.author).toEqual(repostedEvent.pubkey)
|
||||
expect(repostedEventPointer!.relays).toEqual([relayUrl])
|
||||
|
||||
const repostedEventFromContent = nip18.getRepostedEvent(event)
|
||||
|
||||
|
@ -99,13 +97,18 @@ describe('getRepostedEventPointer', () => {
|
|||
it('should parse an event with only an `e` tag', () => {
|
||||
const event = {
|
||||
kind: Kind.Repost,
|
||||
tags: [['e', 'reposted event id', relayUrl]]
|
||||
tags: [['e', 'reposted event id', relayUrl]],
|
||||
content: '',
|
||||
created_at: 0,
|
||||
pubkey: '',
|
||||
id: '',
|
||||
sig: '',
|
||||
}
|
||||
|
||||
const repostedEventPointer = nip18.getRepostedEventPointer(event)
|
||||
|
||||
expect(repostedEventPointer.id).toEqual('reposted event id')
|
||||
expect(repostedEventPointer.author).toEqual(undefined)
|
||||
expect(repostedEventPointer.relays).toEqual([relayUrl])
|
||||
expect(repostedEventPointer!.id).toEqual('reposted event id')
|
||||
expect(repostedEventPointer!.author).toEqual(undefined)
|
||||
expect(repostedEventPointer!.relays).toEqual([relayUrl])
|
||||
})
|
||||
})
|
|
@ -1,6 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {nip19, generatePrivateKey, getPublicKey} = require('./lib/nostr.cjs')
|
||||
import {nip19, generatePrivateKey, getPublicKey} from '.'
|
||||
|
||||
test('encode and decode nsec', () => {
|
||||
let sk = generatePrivateKey()
|
||||
|
@ -30,9 +28,10 @@ test('encode and decode nprofile', () => {
|
|||
expect(nprofile).toMatch(/nprofile1\w+/)
|
||||
let {type, data} = nip19.decode(nprofile)
|
||||
expect(type).toEqual('nprofile')
|
||||
expect(data.pubkey).toEqual(pk)
|
||||
expect(data.relays).toContain(relays[0])
|
||||
expect(data.relays).toContain(relays[1])
|
||||
const pointer = data as nip19.ProfilePointer
|
||||
expect(pointer.pubkey).toEqual(pk)
|
||||
expect(pointer.relays).toContain(relays[0])
|
||||
expect(pointer.relays).toContain(relays[1])
|
||||
})
|
||||
|
||||
test('decode nprofile without relays', () => {
|
||||
|
@ -65,11 +64,12 @@ test('encode and decode naddr', () => {
|
|||
expect(naddr).toMatch(/naddr1\w+/)
|
||||
let {type, data} = nip19.decode(naddr)
|
||||
expect(type).toEqual('naddr')
|
||||
expect(data.pubkey).toEqual(pk)
|
||||
expect(data.relays).toContain(relays[0])
|
||||
expect(data.relays).toContain(relays[1])
|
||||
expect(data.kind).toEqual(30023)
|
||||
expect(data.identifier).toEqual('banana')
|
||||
const pointer = data as nip19.AddressPointer
|
||||
expect(pointer.pubkey).toEqual(pk)
|
||||
expect(pointer.relays).toContain(relays[0])
|
||||
expect(pointer.relays).toContain(relays[1])
|
||||
expect(pointer.kind).toEqual(30023)
|
||||
expect(pointer.identifier).toEqual('banana')
|
||||
})
|
||||
|
||||
test('decode naddr from habla.news', () => {
|
||||
|
@ -77,11 +77,12 @@ test('decode naddr from habla.news', () => {
|
|||
'naddr1qq98yetxv4ex2mnrv4esygrl54h466tz4v0re4pyuavvxqptsejl0vxcmnhfl60z3rth2xkpjspsgqqqw4rsf34vl5'
|
||||
)
|
||||
expect(type).toEqual('naddr')
|
||||
expect(data.pubkey).toEqual(
|
||||
const pointer = data as nip19.AddressPointer
|
||||
expect(pointer.pubkey).toEqual(
|
||||
'7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194'
|
||||
)
|
||||
expect(data.kind).toEqual(30023)
|
||||
expect(data.identifier).toEqual('references')
|
||||
expect(pointer.kind).toEqual(30023)
|
||||
expect(pointer.identifier).toEqual('references')
|
||||
})
|
||||
|
||||
test('decode naddr from go-nostr with different TLV ordering', () => {
|
||||
|
@ -90,15 +91,16 @@ test('decode naddr from go-nostr with different TLV ordering', () => {
|
|||
)
|
||||
|
||||
expect(type).toEqual('naddr')
|
||||
expect(data.pubkey).toEqual(
|
||||
const pointer = data as nip19.AddressPointer
|
||||
expect(pointer.pubkey).toEqual(
|
||||
'3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'
|
||||
)
|
||||
expect(data.relays).toContain(
|
||||
expect(pointer.relays).toContain(
|
||||
'wss://relay.nostr.example.mydomain.example.com'
|
||||
)
|
||||
expect(data.relays).toContain('wss://nostr.banana.com')
|
||||
expect(data.kind).toEqual(30023)
|
||||
expect(data.identifier).toEqual('banana')
|
||||
expect(pointer.relays).toContain('wss://nostr.banana.com')
|
||||
expect(pointer.kind).toEqual(30023)
|
||||
expect(pointer.identifier).toEqual('banana')
|
||||
})
|
||||
|
||||
test('encode and decode nrelay', () => {
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-env jest */
|
||||
const {nip21} = require('./lib/nostr.cjs')
|
||||
import {nip21} from '.'
|
||||
|
||||
test('test', () => {
|
||||
test('test()', () => {
|
||||
expect(
|
||||
nip21.test(
|
||||
'nostr:npub108pv4cg5ag52nq082kd5leu9ffrn2gdg6g4xdwatn73y36uzplmq9uyev6'
|
|
@ -1,6 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {nip25, finishEvent, getPublicKey, Kind} = require('./lib/nostr.cjs')
|
||||
import {nip25, finishEvent, getPublicKey, Kind} from '.'
|
||||
|
||||
describe('finishReactionEvent + getReactedEventPointer', () => {
|
||||
const privateKey =
|
||||
|
@ -43,8 +41,8 @@ describe('finishReactionEvent + getReactedEventPointer', () => {
|
|||
|
||||
const reactedEventPointer = nip25.getReactedEventPointer(event)
|
||||
|
||||
expect(reactedEventPointer.id).toEqual(reactedEvent.id)
|
||||
expect(reactedEventPointer.author).toEqual(reactedEvent.pubkey)
|
||||
expect(reactedEventPointer!.id).toEqual(reactedEvent.id)
|
||||
expect(reactedEventPointer!.author).toEqual(reactedEvent.pubkey)
|
||||
})
|
||||
|
||||
it('should create a signed event from a filled template', () => {
|
||||
|
@ -72,7 +70,7 @@ describe('finishReactionEvent + getReactedEventPointer', () => {
|
|||
|
||||
const reactedEventPointer = nip25.getReactedEventPointer(event)
|
||||
|
||||
expect(reactedEventPointer.id).toEqual(reactedEvent.id)
|
||||
expect(reactedEventPointer.author).toEqual(reactedEvent.pubkey)
|
||||
expect(reactedEventPointer!.id).toEqual(reactedEvent.id)
|
||||
expect(reactedEventPointer!.author).toEqual(reactedEvent.pubkey)
|
||||
})
|
||||
})
|
|
@ -1,6 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {nip26, getPublicKey, generatePrivateKey} = require('./lib/nostr.cjs')
|
||||
import {nip26, getPublicKey, generatePrivateKey} from '.'
|
||||
|
||||
test('parse good delegation from NIP', async () => {
|
||||
expect(
|
||||
|
@ -99,7 +97,11 @@ test('create and verify delegation', async () => {
|
|||
let event = {
|
||||
kind: 1,
|
||||
tags: [['delegation', delegation.from, delegation.cond, delegation.sig]],
|
||||
pubkey: pk2
|
||||
pubkey: pk2,
|
||||
content: '',
|
||||
created_at: 0,
|
||||
id: '',
|
||||
sig: '',
|
||||
}
|
||||
expect(nip26.getDelegator(event)).toEqual(pk1)
|
||||
})
|
6
nip26.ts
6
nip26.ts
|
@ -8,9 +8,9 @@ import {getPublicKey} from './keys'
|
|||
|
||||
export type Parameters = {
|
||||
pubkey: string // the key to whom the delegation will be given
|
||||
kind: number | undefined
|
||||
until: number | undefined // delegation will only be valid until this date
|
||||
since: number | undefined // delegation will be valid from this date on
|
||||
kind?: number
|
||||
until?: number // delegation will only be valid until this date
|
||||
since?: number // delegation will be valid from this date on
|
||||
}
|
||||
|
||||
export type Delegation = {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* eslint-env jest */
|
||||
const {nip27} = require('./lib/nostr.cjs')
|
||||
import {nip27} from '.'
|
||||
|
||||
test('matchAll', () => {
|
||||
const result = nip27.matchAll(
|
|
@ -1,7 +1,5 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const fetch = require('node-fetch')
|
||||
const {nip39} = require('./lib/nostr.cjs.js')
|
||||
import fetch from 'node-fetch'
|
||||
import {nip39} from '.'
|
||||
|
||||
test('validate github claim', async () => {
|
||||
nip39.useFetchImplementation(fetch)
|
|
@ -1,27 +0,0 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
require('websocket-polyfill')
|
||||
const {
|
||||
relayInit,
|
||||
generatePrivateKey,
|
||||
finishEvent,
|
||||
nip42
|
||||
} = require('./lib/nostr.cjs')
|
||||
|
||||
test('auth flow', done => {
|
||||
const relay = relayInit('wss://nostr.kollider.xyz')
|
||||
relay.connect()
|
||||
const sk = generatePrivateKey()
|
||||
|
||||
relay.on('auth', async challenge => {
|
||||
await expect(
|
||||
nip42.authenticate({
|
||||
challenge,
|
||||
relay,
|
||||
sign: e => finishEvent(e, sk)
|
||||
})
|
||||
).rejects.toBeTruthy()
|
||||
relay.close()
|
||||
done()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,27 @@
|
|||
import 'websocket-polyfill'
|
||||
import {
|
||||
relayInit,
|
||||
generatePrivateKey,
|
||||
finishEvent,
|
||||
nip42
|
||||
} from '.'
|
||||
|
||||
test('auth flow', () => {
|
||||
const relay = relayInit('wss://nostr.kollider.xyz')
|
||||
relay.connect()
|
||||
const sk = generatePrivateKey()
|
||||
|
||||
return new Promise<void>((resolve) => {
|
||||
relay.on('auth', async challenge => {
|
||||
await expect(
|
||||
nip42.authenticate({
|
||||
challenge,
|
||||
relay,
|
||||
sign: (e) => finishEvent(e, sk)
|
||||
})
|
||||
).rejects.toBeTruthy()
|
||||
relay.close()
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
})
|
2
nip42.ts
2
nip42.ts
|
@ -17,7 +17,7 @@ export const authenticate = async ({
|
|||
}: {
|
||||
challenge: string
|
||||
relay: Relay
|
||||
sign: <K extends number = number>(e: EventTemplate<K>) => Promise<Event<K>>
|
||||
sign: <K extends number = number>(e: EventTemplate<K>) => Promise<Event<K>> | Event<K>
|
||||
}): Promise<void> => {
|
||||
const e: EventTemplate = {
|
||||
kind: Kind.ClientAuth,
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
const {bech32} = require('@scure/base')
|
||||
const {
|
||||
import {
|
||||
nip57,
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
finishEvent
|
||||
} = require('./lib/nostr.cjs')
|
||||
} from '.'
|
||||
import { buildEvent } from './test-helpers'
|
||||
|
||||
describe('getZapEndpoint', () => {
|
||||
test('returns null if neither lud06 nor lud16 is present', async () => {
|
||||
const metadata = {content: '{}'}
|
||||
const metadata = buildEvent({kind: 0, content: '{}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBeNull()
|
||||
|
@ -18,7 +18,7 @@ describe('getZapEndpoint', () => {
|
|||
const fetchImplementation = jest.fn(() => Promise.reject(new Error()))
|
||||
nip57.useFetchImplementation(fetchImplementation)
|
||||
|
||||
const metadata = {content: '{"lud16": "name@domain"}'}
|
||||
const metadata = buildEvent({kind: 0, content: '{"lud16": "name@domain"}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBeNull()
|
||||
|
@ -33,7 +33,7 @@ describe('getZapEndpoint', () => {
|
|||
)
|
||||
nip57.useFetchImplementation(fetchImplementation)
|
||||
|
||||
const metadata = {content: '{"lud16": "name@domain"}'}
|
||||
const metadata = buildEvent({kind: 0, content: '{"lud16": "name@domain"}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBeNull()
|
||||
|
@ -54,7 +54,7 @@ describe('getZapEndpoint', () => {
|
|||
)
|
||||
nip57.useFetchImplementation(fetchImplementation)
|
||||
|
||||
const metadata = {content: '{"lud16": "name@domain"}'}
|
||||
const metadata = buildEvent({kind: 0, content: '{"lud16": "name@domain"}'})
|
||||
const result = await nip57.getZapEndpoint(metadata)
|
||||
|
||||
expect(result).toBe('callback')
|
||||
|
@ -67,6 +67,7 @@ describe('getZapEndpoint', () => {
|
|||
describe('makeZapRequest', () => {
|
||||
test('throws an error if amount is not given', () => {
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
nip57.makeZapRequest({
|
||||
profile: 'profile',
|
||||
event: null,
|
||||
|
@ -78,6 +79,7 @@ describe('makeZapRequest', () => {
|
|||
|
||||
test('throws an error if profile is not given', () => {
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
nip57.makeZapRequest({
|
||||
event: null,
|
||||
amount: 100,
|
2
nip57.ts
2
nip57.ts
|
@ -119,7 +119,7 @@ export function makeZapReceipt({
|
|||
paidAt
|
||||
}: {
|
||||
zapRequest: string
|
||||
preimage: string | null
|
||||
preimage?: string
|
||||
bolt11: string
|
||||
paidAt: Date
|
||||
}): EventTemplate<Kind.Zap> {
|
||||
|
|
|
@ -44,8 +44,9 @@
|
|||
"@typescript-eslint/parser": "^5.51.0",
|
||||
"esbuild": "0.16.9",
|
||||
"esbuild-plugin-alias": "^0.2.1",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint": "^8.40.0",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-jest": "^27.2.1",
|
||||
"esm-loader-typescript": "^1.0.3",
|
||||
"events": "^3.3.0",
|
||||
"jest": "^29.5.0",
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
require('websocket-polyfill')
|
||||
const {
|
||||
import 'websocket-polyfill'
|
||||
import {
|
||||
SimplePool,
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
getEventHash,
|
||||
getSignature
|
||||
} = require('./lib/nostr.cjs')
|
||||
finishEvent,
|
||||
type Event,
|
||||
} from '.'
|
||||
|
||||
let pool = new SimplePool()
|
||||
|
||||
|
@ -33,7 +31,7 @@ test('removing duplicates when querying', async () => {
|
|||
let pub = getPublicKey(priv)
|
||||
|
||||
let sub = pool.sub(relays, [{authors: [pub]}])
|
||||
let received = []
|
||||
let received: Event[] = []
|
||||
|
||||
sub.on('event', event => {
|
||||
// this should be called only once even though we're listening
|
||||
|
@ -42,15 +40,12 @@ test('removing duplicates when querying', async () => {
|
|||
received.push(event)
|
||||
})
|
||||
|
||||
let event = {
|
||||
pubkey: pub,
|
||||
let event = finishEvent({
|
||||
created_at: Math.round(Date.now() / 1000),
|
||||
content: 'test',
|
||||
kind: 22345,
|
||||
tags: []
|
||||
}
|
||||
event.id = getEventHash(event)
|
||||
event.sig = getSignature(event, priv)
|
||||
}, priv)
|
||||
|
||||
pool.publish(relays, event)
|
||||
|
||||
|
@ -66,7 +61,7 @@ test('same with double querying', async () => {
|
|||
let sub1 = pool.sub(relays, [{authors: [pub]}])
|
||||
let sub2 = pool.sub(relays, [{authors: [pub]}])
|
||||
|
||||
let received = []
|
||||
let received: Event[] = []
|
||||
|
||||
sub1.on('event', event => {
|
||||
received.push(event)
|
||||
|
@ -76,15 +71,12 @@ test('same with double querying', async () => {
|
|||
received.push(event)
|
||||
})
|
||||
|
||||
let event = {
|
||||
pubkey: pub,
|
||||
let event = finishEvent({
|
||||
created_at: Math.round(Date.now() / 1000),
|
||||
content: 'test2',
|
||||
kind: 22346,
|
||||
tags: []
|
||||
}
|
||||
event.id = getEventHash(event)
|
||||
event.sig = getSignature(event, priv)
|
||||
}, priv)
|
||||
|
||||
pool.publish(relays, event)
|
||||
|
||||
|
@ -122,6 +114,7 @@ test('list()', async () => {
|
|||
expect(events.length).toEqual(
|
||||
events
|
||||
.map(evt => evt.id)
|
||||
// @ts-ignore ???
|
||||
.reduce((acc, n) => (acc.indexOf(n) !== -1 ? acc : [...acc, n]), [])
|
||||
.length
|
||||
)
|
|
@ -1,9 +1,10 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {parseReferences} = require('./lib/nostr.cjs')
|
||||
import {parseReferences} from '.'
|
||||
|
||||
test('parse mentions', () => {
|
||||
let evt = {
|
||||
kind: 1,
|
||||
id: '',
|
||||
pubkey: '',
|
||||
tags: [
|
||||
[
|
||||
'p',
|
||||
|
@ -23,7 +24,9 @@ test('parse mentions', () => {
|
|||
]
|
||||
],
|
||||
content:
|
||||
'hello #[0], have you seen #[2]? it was made by nostr:nprofile1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8yc5usxdg on nostr:nevent1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8ychxp5v4! broken #[3]'
|
||||
'hello #[0], have you seen #[2]? it was made by nostr:nprofile1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8yc5usxdg on nostr:nevent1qqsvc6ulagpn7kwrcwdqgp797xl7usumqa6s3kgcelwq6m75x8fe8ychxp5v4! broken #[3]',
|
||||
created_at: 0,
|
||||
sig: '',
|
||||
}
|
||||
|
||||
expect(parseReferences(evt)).toEqual([
|
|
@ -1,13 +1,10 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
require('websocket-polyfill')
|
||||
const {
|
||||
import 'websocket-polyfill'
|
||||
import {
|
||||
relayInit,
|
||||
generatePrivateKey,
|
||||
getPublicKey,
|
||||
getEventHash,
|
||||
getSignature
|
||||
} = require('./lib/nostr.cjs')
|
||||
finishEvent,
|
||||
} from '.'
|
||||
|
||||
let relay = relayInit('wss://relay.damus.io/')
|
||||
|
||||
|
@ -33,8 +30,8 @@ test('connectivity', () => {
|
|||
})
|
||||
|
||||
test('querying', async () => {
|
||||
var resolve1
|
||||
var resolve2
|
||||
var resolve1: (value: boolean) => void
|
||||
var resolve2: (value: boolean) => void
|
||||
|
||||
let sub = relay.sub([
|
||||
{
|
||||
|
@ -53,10 +50,10 @@ test('querying', async () => {
|
|||
})
|
||||
|
||||
let [t1, t2] = await Promise.all([
|
||||
new Promise(resolve => {
|
||||
new Promise<boolean>(resolve => {
|
||||
resolve1 = resolve
|
||||
}),
|
||||
new Promise(resolve => {
|
||||
new Promise<boolean>(resolve => {
|
||||
resolve2 = resolve
|
||||
})
|
||||
])
|
||||
|
@ -93,8 +90,8 @@ test('list()', async () => {
|
|||
test('listening (twice) and publishing', async () => {
|
||||
let sk = generatePrivateKey()
|
||||
let pk = getPublicKey(sk)
|
||||
var resolve1
|
||||
var resolve2
|
||||
var resolve1: (value: boolean) => void
|
||||
var resolve2: (value: boolean) => void
|
||||
|
||||
let sub = relay.sub([
|
||||
{
|
||||
|
@ -116,15 +113,12 @@ test('listening (twice) and publishing', async () => {
|
|||
resolve2(true)
|
||||
})
|
||||
|
||||
let event = {
|
||||
let event = finishEvent({
|
||||
kind: 27572,
|
||||
pubkey: pk,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
tags: [],
|
||||
content: 'nostr-tools test suite'
|
||||
}
|
||||
event.id = getEventHash(event)
|
||||
event.sig = getSignature(event, sk)
|
||||
}, sk)
|
||||
|
||||
relay.publish(event)
|
||||
return expect(
|
|
@ -0,0 +1,17 @@
|
|||
import {type Event} from '.'
|
||||
|
||||
type EventParams<K extends number> = Partial<Event<K>>
|
||||
|
||||
/** Build an event for testing purposes. */
|
||||
export function buildEvent<K extends number = 1>(params: EventParams<K>): Event<K> {
|
||||
return {
|
||||
id: '',
|
||||
kind: 1 as K,
|
||||
pubkey: '',
|
||||
created_at: 0,
|
||||
content: '',
|
||||
tags: [],
|
||||
sig: '',
|
||||
...params
|
||||
}
|
||||
}
|
183
utils.test.js
183
utils.test.js
|
@ -1,183 +0,0 @@
|
|||
/* eslint-env jest */
|
||||
|
||||
const {utils} = require('./lib/nostr.cjs')
|
||||
|
||||
const {insertEventIntoAscendingList, insertEventIntoDescendingList} = utils
|
||||
|
||||
describe('inserting into a desc sorted list of events', () => {
|
||||
test('insert into an empty list', async () => {
|
||||
const list0 = []
|
||||
expect(
|
||||
insertEventIntoDescendingList(list0, {id: 'abc', created_at: 10})
|
||||
).toHaveLength(1)
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list', async () => {
|
||||
const list0 = [{created_at: 20}, {created_at: 10}]
|
||||
const list1 = insertEventIntoDescendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
})
|
||||
expect(list1).toHaveLength(3)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list with same created_at', async () => {
|
||||
const list0 = [{created_at: 30}, {created_at: 20}, {created_at: 10}]
|
||||
const list1 = insertEventIntoDescendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
})
|
||||
expect(list1).toHaveLength(4)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the middle of a list', async () => {
|
||||
const list0 = [
|
||||
{created_at: 30},
|
||||
{created_at: 20},
|
||||
{created_at: 10},
|
||||
{created_at: 1}
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 15
|
||||
})
|
||||
expect(list1).toHaveLength(5)
|
||||
expect(list1[2].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the end of a list', async () => {
|
||||
const list0 = [
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 10}
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 5
|
||||
})
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-1)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the last-to-end of a list with same created_at', async () => {
|
||||
const list0 = [
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 10}
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 10
|
||||
})
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-2)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('do not insert duplicates', async () => {
|
||||
const list0 = [
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 10, id: 'abc'}
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 10
|
||||
})
|
||||
expect(list1).toHaveLength(3)
|
||||
})
|
||||
})
|
||||
|
||||
describe('inserting into a asc sorted list of events', () => {
|
||||
test('insert into an empty list', async () => {
|
||||
const list0 = []
|
||||
expect(
|
||||
insertEventIntoAscendingList(list0, {id: 'abc', created_at: 10})
|
||||
).toHaveLength(1)
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list', async () => {
|
||||
const list0 = [{created_at: 10}, {created_at: 20}]
|
||||
const list1 = insertEventIntoAscendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 1
|
||||
})
|
||||
expect(list1).toHaveLength(3)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list with same created_at', async () => {
|
||||
const list0 = [{created_at: 10}, {created_at: 20}, {created_at: 30}]
|
||||
const list1 = insertEventIntoAscendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 10
|
||||
})
|
||||
expect(list1).toHaveLength(4)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the middle of a list', async () => {
|
||||
const list0 = [
|
||||
{created_at: 10},
|
||||
{created_at: 20},
|
||||
{created_at: 30},
|
||||
{created_at: 40}
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 25
|
||||
})
|
||||
expect(list1).toHaveLength(5)
|
||||
expect(list1[2].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the end of a list', async () => {
|
||||
const list0 = [
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 40}
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 50
|
||||
})
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-1)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the last-to-end of a list with same created_at', async () => {
|
||||
const list0 = [
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 30}
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
})
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-2)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('do not insert duplicates', async () => {
|
||||
const list0 = [
|
||||
{created_at: 20},
|
||||
{created_at: 20},
|
||||
{created_at: 30, id: 'abc'}
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, {
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
})
|
||||
expect(list1).toHaveLength(3)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,190 @@
|
|||
import {utils, type Event} from '.'
|
||||
import {buildEvent} from './test-helpers'
|
||||
|
||||
const {insertEventIntoAscendingList, insertEventIntoDescendingList} = utils
|
||||
|
||||
describe('inserting into a desc sorted list of events', () => {
|
||||
test('insert into an empty list', async () => {
|
||||
const list0: Event[] = []
|
||||
expect(
|
||||
insertEventIntoDescendingList(list0, buildEvent({id: 'abc', created_at: 10}))
|
||||
).toHaveLength(1)
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list', async () => {
|
||||
const list0 = [buildEvent({created_at: 20}), buildEvent({created_at: 10})]
|
||||
const list1 = insertEventIntoDescendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
}))
|
||||
expect(list1).toHaveLength(3)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list with same created_at', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 30}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 10}),
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
}))
|
||||
expect(list1).toHaveLength(4)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the middle of a list', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 30}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 10}),
|
||||
buildEvent({created_at: 1}),
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 15
|
||||
}))
|
||||
expect(list1).toHaveLength(5)
|
||||
expect(list1[2].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the end of a list', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 10}),
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 5
|
||||
}))
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-1)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the last-to-end of a list with same created_at', async () => {
|
||||
const list0: Event[] = [
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 10}),
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 10
|
||||
}))
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-2)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('do not insert duplicates', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 10, id: 'abc'}),
|
||||
]
|
||||
const list1 = insertEventIntoDescendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 10
|
||||
}))
|
||||
expect(list1).toHaveLength(3)
|
||||
})
|
||||
})
|
||||
|
||||
describe('inserting into a asc sorted list of events', () => {
|
||||
test('insert into an empty list', async () => {
|
||||
const list0: Event[] = []
|
||||
expect(
|
||||
insertEventIntoAscendingList(list0, buildEvent({id: 'abc', created_at: 10}))
|
||||
).toHaveLength(1)
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list', async () => {
|
||||
const list0 = [buildEvent({created_at: 10}), buildEvent({created_at: 20})]
|
||||
const list1 = insertEventIntoAscendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 1
|
||||
}))
|
||||
expect(list1).toHaveLength(3)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the beginning of a list with same created_at', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 10}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 30}),
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 10
|
||||
}))
|
||||
expect(list1).toHaveLength(4)
|
||||
expect(list1[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the middle of a list', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 10}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 30}),
|
||||
buildEvent({created_at: 40}),
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 25
|
||||
}))
|
||||
expect(list1).toHaveLength(5)
|
||||
expect(list1[2].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the end of a list', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 40}),
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 50
|
||||
}))
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-1)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('insert in the last-to-end of a list with same created_at', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 30}),
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
}))
|
||||
expect(list1).toHaveLength(6)
|
||||
expect(list1.slice(-2)[0].id).toBe('abc')
|
||||
})
|
||||
|
||||
test('do not insert duplicates', async () => {
|
||||
const list0 = [
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 20}),
|
||||
buildEvent({created_at: 30, id: 'abc'}),
|
||||
]
|
||||
const list1 = insertEventIntoAscendingList(list0, buildEvent({
|
||||
id: 'abc',
|
||||
created_at: 30
|
||||
}))
|
||||
expect(list1).toHaveLength(3)
|
||||
})
|
||||
})
|
57
yarn.lock
57
yarn.lock
|
@ -958,6 +958,14 @@
|
|||
"@typescript-eslint/types" "5.59.2"
|
||||
"@typescript-eslint/visitor-keys" "5.59.2"
|
||||
|
||||
"@typescript-eslint/scope-manager@5.59.5":
|
||||
version "5.59.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz#33ffc7e8663f42cfaac873de65ebf65d2bce674d"
|
||||
integrity sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.59.5"
|
||||
"@typescript-eslint/visitor-keys" "5.59.5"
|
||||
|
||||
"@typescript-eslint/type-utils@5.59.2":
|
||||
version "5.59.2"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz#0729c237503604cd9a7084b5af04c496c9a4cdcf"
|
||||
|
@ -973,6 +981,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.2.tgz#b511d2b9847fe277c5cb002a2318bd329ef4f655"
|
||||
integrity sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==
|
||||
|
||||
"@typescript-eslint/types@5.59.5":
|
||||
version "5.59.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.5.tgz#e63c5952532306d97c6ea432cee0981f6d2258c7"
|
||||
integrity sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.59.2":
|
||||
version "5.59.2"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz#6e2fabd3ba01db5d69df44e0b654c0b051fe9936"
|
||||
|
@ -986,6 +999,19 @@
|
|||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/typescript-estree@5.59.5":
|
||||
version "5.59.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz#9b252ce55dd765e972a7a2f99233c439c5101e42"
|
||||
integrity sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.59.5"
|
||||
"@typescript-eslint/visitor-keys" "5.59.5"
|
||||
debug "^4.3.4"
|
||||
globby "^11.1.0"
|
||||
is-glob "^4.0.3"
|
||||
semver "^7.3.7"
|
||||
tsutils "^3.21.0"
|
||||
|
||||
"@typescript-eslint/utils@5.59.2":
|
||||
version "5.59.2"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.2.tgz#0c45178124d10cc986115885688db6abc37939f4"
|
||||
|
@ -1000,6 +1026,20 @@
|
|||
eslint-scope "^5.1.1"
|
||||
semver "^7.3.7"
|
||||
|
||||
"@typescript-eslint/utils@^5.10.0":
|
||||
version "5.59.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.5.tgz#15b3eb619bb223302e60413adb0accd29c32bcae"
|
||||
integrity sha512-sCEHOiw+RbyTii9c3/qN74hYDPNORb8yWCoPLmB7BIflhplJ65u2PBpdRla12e3SSTJ2erRkPjz7ngLHhUegxA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@types/json-schema" "^7.0.9"
|
||||
"@types/semver" "^7.3.12"
|
||||
"@typescript-eslint/scope-manager" "5.59.5"
|
||||
"@typescript-eslint/types" "5.59.5"
|
||||
"@typescript-eslint/typescript-estree" "5.59.5"
|
||||
eslint-scope "^5.1.1"
|
||||
semver "^7.3.7"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.59.2":
|
||||
version "5.59.2"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz#37a419dc2723a3eacbf722512b86d6caf7d3b750"
|
||||
|
@ -1008,6 +1048,14 @@
|
|||
"@typescript-eslint/types" "5.59.2"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@5.59.5":
|
||||
version "5.59.5"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz#ba5b8d6791a13cf9fea6716af1e7626434b29b9b"
|
||||
integrity sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "5.59.5"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
acorn-jsx@^5.3.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
|
@ -1651,6 +1699,13 @@ eslint-plugin-babel@^5.3.1:
|
|||
dependencies:
|
||||
eslint-rule-composer "^0.3.0"
|
||||
|
||||
eslint-plugin-jest@^27.2.1:
|
||||
version "27.2.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz#b85b4adf41c682ea29f1f01c8b11ccc39b5c672c"
|
||||
integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==
|
||||
dependencies:
|
||||
"@typescript-eslint/utils" "^5.10.0"
|
||||
|
||||
eslint-rule-composer@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9"
|
||||
|
@ -1682,7 +1737,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
|
|||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994"
|
||||
integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
|
||||
|
||||
eslint@^8.33.0:
|
||||
eslint@^8.40.0:
|
||||
version "8.40.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.40.0.tgz#a564cd0099f38542c4e9a2f630fa45bf33bc42a4"
|
||||
integrity sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==
|
||||
|
|
Loading…
Reference in New Issue