damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

NdbTests.swift (9734B)


      1 //
      2 //  NDBIterTests.swift
      3 //  damusTests
      4 //
      5 //  Created by William Casarin on 2023-07-21.
      6 //
      7 
      8 import XCTest
      9 @testable import damus
     10 
     11 func test_ndb_dir() -> String? {
     12     do {
     13         let fileManager = FileManager.default
     14         let tempDir = fileManager.temporaryDirectory.appendingPathComponent(UUID().uuidString)
     15         try fileManager.createDirectory(at: tempDir, withIntermediateDirectories: true, attributes: nil)
     16         return remove_file_prefix(tempDir.absoluteString)
     17     } catch {
     18         return nil
     19     }
     20 }
     21 
     22 final class NdbTests: XCTestCase {
     23     var db_dir: String = ""
     24 
     25     override func setUpWithError() throws {
     26         guard let db = test_ndb_dir() else {
     27             XCTFail("Could not create temp directory")
     28             return
     29         }
     30         db_dir = db
     31     }
     32 
     33     override func tearDownWithError() throws {
     34         // Put teardown code here. This method is called after the invocation of each test method in the class.
     35     }
     36 
     37     func test_decode_eose() throws {
     38         let json = "[\"EOSE\",\"DC268DBD-55DA-458A-B967-540925AF3497\"]"
     39         let resp = decode_nostr_event(txt: json)
     40         XCTAssertNotNil(resp)
     41     }
     42 
     43     func test_decode_command_result() throws {
     44         let json = "[\"OK\",\"b1d8f68d39c07ce5c5ea10c235100d529b2ed2250140b36a35d940b712dc6eff\",true,\"\"]"
     45         let resp = decode_nostr_event(txt: json)
     46         XCTAssertNotNil(resp)
     47 
     48     }
     49 
     50     func test_profile_creation() {
     51         let profile = make_test_profile()
     52         XCTAssertEqual(profile.name, "jb55")
     53     }
     54 
     55     func test_ndb_init() {
     56 
     57         do {
     58             let ndb = Ndb(path: db_dir)!
     59             let ok = ndb.process_events(test_wire_events)
     60             XCTAssertTrue(ok)
     61         }
     62 
     63         do {
     64             let ndb = Ndb(path: db_dir)!
     65             let id = NoteId(hex: "d12c17bde3094ad32f4ab862a6cc6f5c289cfe7d5802270bdf34904df585f349")!
     66             guard let txn = NdbTxn(ndb: ndb) else { return XCTAssert(false) }
     67             let note = ndb.lookup_note_with_txn(id: id, txn: txn)
     68             XCTAssertNotNil(note)
     69             guard let note else { return }
     70             let pk = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
     71             XCTAssertEqual(note.pubkey, pk)
     72 
     73             let profile = ndb.lookup_profile_with_txn(pk, txn: txn)
     74             XCTAssertNotNil(profile)
     75             guard let profile else { return }
     76 
     77             XCTAssertEqual(profile.profile?.name, "jb55")
     78             XCTAssertEqual(profile.lnurl, nil)
     79         }
     80 
     81 
     82     }
     83 
     84     func test_ndb_seach() throws {
     85         do {
     86             let ndb = Ndb(path: db_dir)!
     87             let ok = ndb.process_events(test_wire_events)
     88             XCTAssertTrue(ok)
     89         }
     90         
     91         do {
     92             let ndb = Ndb(path: db_dir)!
     93             let note_ids = ndb.text_search(query: "barked")
     94             XCTAssertEqual(note_ids.count, 1)
     95             let expected_note_id = NoteId(hex: "b17a540710fe8495b16bfbaf31c6962c4ba8387f3284a7973ad523988095417e")!
     96             let note_id = ndb.lookup_note_by_key(note_ids[0])?.map({ n in n?.id }).value
     97             XCTAssertEqual(note_id, .some(expected_note_id))
     98         }
     99     }
    100 
    101     func test_ndb_note() throws {
    102         let note = NdbNote.owned_from_json(json: test_contact_list_json)
    103         XCTAssertNotNil(note)
    104         guard let note else { return }
    105 
    106         let id = NoteId(hex: "20d0ff27d6fcb13de8366328c5b1a7af26bcac07f2e558fbebd5e9242e608c09")!
    107         let pubkey = Pubkey(hex: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245")!
    108 
    109         XCTAssertEqual(note.id, id)
    110         XCTAssertEqual(note.pubkey, pubkey)
    111 
    112         XCTAssertEqual(note.count, 34328)
    113         XCTAssertEqual(note.kind, 3)
    114         XCTAssertEqual(note.created_at, 1689904312)
    115 
    116         let expected_count: UInt16 = 786
    117         XCTAssertEqual(note.tags.count, expected_count)
    118         XCTAssertEqual(note.tags.reduce(0, { sum, _ in sum + 1 }), expected_count)
    119 
    120         var tags = 0
    121         var total_count_stored = 0
    122         var total_count_iter = 0
    123         //let tags = note.tags()
    124         for tag in note.tags {
    125             total_count_stored += Int(tag.count)
    126 
    127             if tags == 0 || tags == 1 || tags == 2 {
    128                 XCTAssertEqual(tag.count, 3)
    129             }
    130 
    131             if tags == 6 {
    132                 XCTAssertEqual(tag.count, 2)
    133             }
    134 
    135             if tags == 7 {
    136                 XCTAssertEqual(tag[2].string(), "wss://nostr-pub.wellorder.net")
    137             }
    138 
    139             for elem in tag {
    140                 print("tag[\(tags)][\(elem.index)]")
    141                 total_count_iter += 1
    142             }
    143 
    144             tags += 1
    145         }
    146 
    147         XCTAssertEqual(tags, 786)
    148         XCTAssertEqual(total_count_stored, total_count_iter)
    149     }
    150     
    151     /// Based on https://github.com/damus-io/damus/issues/1468
    152     /// Tests whether a JSON with optional escaped slash characters is correctly unescaped (In accordance to https://datatracker.ietf.org/doc/html/rfc8259#section-7)
    153     func test_decode_json_with_escaped_slashes() {
    154         let testJSONWithEscapedSlashes = "{\"tags\":[],\"pubkey\":\"f8e6c64342f1e052480630e27e1016dce35fc3a614e60434fef4aa2503328ca9\",\"content\":\"https:\\/\\/cdn.nostr.build\\/i\\/5c1d3296f66c2630131bf123106486aeaf051ed8466031c0e0532d70b33cddb2.jpg\",\"created_at\":1691864981,\"kind\":1,\"sig\":\"fc0033aa3d4df50b692a5b346fa816fdded698de2045e36e0642a021391468c44ca69c2471adc7e92088131872d4aaa1e90ea6e1ad97f3cc748f4aed96dfae18\",\"id\":\"e8f6eca3b161abba034dac9a02bb6930ecde9fd2fb5d6c5f22a05526e11382cb\"}"
    155         let testNote = NdbNote.owned_from_json(json: testJSONWithEscapedSlashes)!
    156         XCTAssertEqual(testNote.content, "https://cdn.nostr.build/i/5c1d3296f66c2630131bf123106486aeaf051ed8466031c0e0532d70b33cddb2.jpg")
    157     }
    158     
    159     func test_inherited_transactions() throws {
    160         let ndb = Ndb(path: db_dir)!
    161         do {
    162             guard let txn1 = NdbTxn(ndb: ndb) else { return XCTAssert(false) }
    163 
    164             let ntxn = (Thread.current.threadDictionary.value(forKey: "ndb_txn") as? ndb_txn)!
    165             XCTAssertEqual(txn1.txn.lmdb, ntxn.lmdb)
    166             XCTAssertEqual(txn1.txn.mdb_txn, ntxn.mdb_txn)
    167 
    168             guard let txn2 = NdbTxn(ndb: ndb) else { return XCTAssert(false) }
    169 
    170             XCTAssertEqual(txn1.inherited, false)
    171             XCTAssertEqual(txn2.inherited, true)
    172         }
    173 
    174         let ndb_txn = Thread.current.threadDictionary.value(forKey: "ndb_txn")
    175         XCTAssertNil(ndb_txn)
    176     }
    177 
    178     func test_decode_perf() throws {
    179         // This is an example of a performance test case.
    180         self.measure {
    181             _ = NdbNote.owned_from_json(json: test_contact_list_json)
    182         }
    183     }
    184 
    185     func test_perf_old_decoding() {
    186         self.measure {
    187             let event = decode_nostr_event_json(test_contact_list_json)
    188             XCTAssertNotNil(event)
    189         }
    190     }
    191 
    192     func test_perf_old_iter()  {
    193         self.measure {
    194             let event = decode_nostr_event_json(test_contact_list_json)
    195             XCTAssertNotNil(event)
    196         }
    197     }
    198 
    199     func longer_iter(_ n: Int = 1000) -> XCTMeasureOptions {
    200         let opts = XCTMeasureOptions()
    201         opts.iterationCount = n
    202         return opts
    203     }
    204 
    205     func test_perf_interp_evrefs_old() {
    206         guard let event = decode_nostr_event_json(test_reply_json) else {
    207             return
    208         }
    209         self.measure(options: longer_iter()) {
    210             let blocks = event.blocks(test_keypair).blocks
    211             let xs = interpret_event_refs(blocks: blocks, tags: event.tags)
    212             XCTAssertEqual(xs.count, 1)
    213         }
    214     }
    215 
    216     func test_perf_interp_evrefs_ndb() {
    217         guard let note = NdbNote.owned_from_json(json: test_reply_json) else {
    218             return
    219         }
    220         self.measure(options: longer_iter()) {
    221             let blocks = note.blocks(test_keypair).blocks
    222             let xs = interpret_event_refs_ndb(blocks: blocks, tags: note.tags)
    223             XCTAssertEqual(xs.count, 1)
    224         }
    225     }
    226 
    227     func test_decoded_events_are_equal() {
    228         let event = decode_nostr_event_json(test_reply_json)
    229         let note = NdbNote.owned_from_json(json: test_reply_json)
    230 
    231         XCTAssertNotNil(note)
    232         XCTAssertNotNil(event)
    233         guard let note else { return }
    234         guard let event else { return }
    235 
    236         XCTAssertEqual(note.content_len, UInt32(event.content.utf8.count))
    237         XCTAssertEqual(note.pubkey, event.pubkey)
    238         XCTAssertEqual(note.id, event.id)
    239 
    240         let ev_blocks = event.blocks(test_keypair)
    241         let note_blocks = note.blocks(test_keypair)
    242 
    243         XCTAssertEqual(ev_blocks, note_blocks)
    244 
    245         let event_refs = interpret_event_refs(blocks: ev_blocks.blocks, tags: event.tags)
    246         let note_refs  = interpret_event_refs_ndb(blocks: note_blocks.blocks, tags: note.tags)
    247 
    248         XCTAssertEqual(event_refs, note_refs)
    249     }
    250 
    251     func test_iteration_perf() throws {
    252         guard let note = NdbNote.owned_from_json(json: test_contact_list_json) else {
    253             XCTAssert(false)
    254             return
    255         }
    256 
    257 
    258         self.measure {
    259             var count = 0
    260             var char_count = 0
    261 
    262             for tag in note.tags {
    263                 for elem in tag {
    264                     print("iter_elem \(elem.string())")
    265                     for c in elem {
    266                         if char_count == 0 {
    267                             let ac = AsciiCharacter(c)
    268                             XCTAssertEqual(ac, "p")
    269                         } else if char_count == 0 {
    270                             XCTAssertEqual(c, 0x6c)
    271                         }
    272                         char_count += 1
    273                     }
    274                 }
    275                 count += 1
    276             }
    277 
    278             XCTAssertEqual(count, 786)
    279             XCTAssertEqual(char_count, 24370)
    280         }
    281 
    282     }
    283 
    284 }
    285