FreeCAD

Форк
0
/
StringHasher.cpp 
1585 строк · 38.1 Кб
1
// SPDX-License-Identifier: LGPL-2.1-or-later
2

3
#include "App/MappedName.h"
4
#include "gtest/gtest.h"
5

6
#include <App/StringHasher.h>
7
#include <App/StringHasherPy.h>
8
#include <App/StringIDPy.h>
9

10
#include <QCryptographicHash>
11
#include <array>
12

13
class StringIDTest: public ::testing::Test
14
{
15
protected:
16
    // void SetUp() override {}
17
    // void TearDown() override {}
18

19
    static App::StringID givenFlaggedStringID(App::StringID::Flag flag)
20
    {
21
        const long value {42};
22
        const QByteArray data {"data", 4};
23
        return App::StringID {value, data, flag};
24
    }
25
};
26

27
TEST_F(StringIDTest, stringIDManualConstructionNoFlags)  // NOLINT
28
{
29
    // Arrange
30
    const long expectedValue {42};
31
    const QByteArray expectedData {"data", 4};
32

33
    // Act
34
    auto id = App::StringID(expectedValue, expectedData);
35

36
    // Assert
37
    EXPECT_EQ(expectedValue, id.value());
38
    EXPECT_EQ(expectedData, id.data());
39
    EXPECT_FALSE(id.isBinary());
40
}
41

42
TEST_F(StringIDTest, stringIDManualConstructionWithFlag)  // NOLINT
43
{
44
    // Arrange
45
    const long expectedValue {42};
46
    const QByteArray expectedData {"data", 4};
47
    const App::StringID::Flags expectedFlags {App::StringID::Flag::Binary};
48

49
    // Act
50
    auto id = App::StringID(expectedValue, expectedData, expectedFlags);
51

52
    // Assert
53
    EXPECT_EQ(expectedValue, id.value());
54
    EXPECT_EQ(expectedData, id.data());
55
    EXPECT_TRUE(id.isBinary());
56
}
57

58
TEST_F(StringIDTest, stringIDDefaultConstruction)  // NOLINT
59
{
60
    // Arrange & Act
61
    auto id = App::StringID();
62

63
    // Assert
64
    EXPECT_EQ(0, id.value());
65
}
66

67
TEST_F(StringIDTest, value)  // NOLINT
68
{
69
    // Arrange
70
    const long expectedValueA {0};
71
    auto idA = App::StringID(expectedValueA, nullptr);
72
    const long expectedValueB {42};
73
    auto idB = App::StringID(expectedValueB, nullptr);
74
    const long expectedValueC {314159};
75
    auto idC = App::StringID(expectedValueC, nullptr);
76

77
    // Act
78
    auto valueA = idA.value();
79
    auto valueB = idB.value();
80
    auto valueC = idC.value();
81

82
    // Assert
83
    EXPECT_EQ(expectedValueA, valueA);
84
    EXPECT_EQ(expectedValueB, valueB);
85
    EXPECT_EQ(expectedValueC, valueC);
86
}
87

88
TEST_F(StringIDTest, relatedIDs)  // NOLINT
89
{
90
    // Nothing to test -- relatedIDs are storage-only in this class
91
}
92

93
TEST_F(StringIDTest, isBinary)  // NOLINT
94
{
95
    // Arrange
96
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::Binary);
97
    auto controlID = App::StringID {};
98

99
    // Act & Assert
100
    EXPECT_TRUE(flaggedID.isBinary());
101
    EXPECT_FALSE(controlID.isBinary());
102
}
103

104
TEST_F(StringIDTest, isHashed)  // NOLINT
105
{
106
    // Arrange
107
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::Hashed);
108
    auto controlID = App::StringID {};
109

110
    // Act & Assert
111
    EXPECT_TRUE(flaggedID.isHashed());
112
    EXPECT_FALSE(controlID.isHashed());
113
}
114

115
TEST_F(StringIDTest, isPostfixed)  // NOLINT
116
{
117
    // Arrange
118
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::Postfixed);
119
    auto controlID = App::StringID {};
120

121
    // Act & Assert
122
    EXPECT_TRUE(flaggedID.isPostfixed());
123
    EXPECT_FALSE(controlID.isPostfixed());
124
}
125

126
TEST_F(StringIDTest, isPostfixEncoded)  // NOLINT
127
{
128
    // Arrange
129
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::PostfixEncoded);
130
    auto controlID = App::StringID {};
131

132
    // Act & Assert
133
    EXPECT_TRUE(flaggedID.isPostfixEncoded());
134
    EXPECT_FALSE(controlID.isPostfixEncoded());
135
}
136

137
TEST_F(StringIDTest, isIndexed)  // NOLINT
138
{
139
    // Arrange
140
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::Indexed);
141
    auto controlID = App::StringID {};
142

143
    // Act & Assert
144
    EXPECT_TRUE(flaggedID.isIndexed());
145
    EXPECT_FALSE(controlID.isIndexed());
146
}
147

148
TEST_F(StringIDTest, isPrefixID)  // NOLINT
149
{
150
    // Arrange
151
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::PrefixID);
152
    auto controlID = App::StringID {};
153

154
    // Act & Assert
155
    EXPECT_TRUE(flaggedID.isPrefixID());
156
    EXPECT_FALSE(controlID.isPrefixID());
157
}
158

159
TEST_F(StringIDTest, isPrefixIDIndex)  // NOLINT
160
{
161
    // Arrange
162
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::PrefixIDIndex);
163
    auto controlID = App::StringID {};
164

165
    // Act & Assert
166
    EXPECT_TRUE(flaggedID.isPrefixIDIndex());
167
    EXPECT_FALSE(controlID.isPrefixIDIndex());
168
}
169

170
TEST_F(StringIDTest, isMarked)  // NOLINT
171
{
172
    // Arrange
173
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::Marked);
174
    auto controlID = App::StringID {};
175

176
    // Act & Assert
177
    EXPECT_TRUE(flaggedID.isMarked());
178
    EXPECT_FALSE(controlID.isMarked());
179
}
180

181
TEST_F(StringIDTest, isPersistent)  // NOLINT
182
{
183
    // Arrange
184
    auto flaggedID = givenFlaggedStringID(App::StringID::Flag::Persistent);
185
    auto controlID = App::StringID {};
186

187
    // Act & Assert
188
    EXPECT_TRUE(flaggedID.isPersistent());
189
    EXPECT_FALSE(controlID.isPersistent());
190
}
191

192
TEST_F(StringIDTest, isFromSameHasher)  // NOLINT
193
{
194
    // Nothing to test except when used by StringHasher
195
}
196

197
TEST_F(StringIDTest, getHasher)  // NOLINT
198
{
199
    // Nothing to test except when used by StringHasher
200
}
201

202
TEST_F(StringIDTest, data)  // NOLINT
203
{
204
    // Arrange
205
    QByteArray expectedData {"data", 4};
206
    auto id = App::StringID(1, expectedData);
207

208
    // Act
209
    auto data = id.data();
210

211
    // Assert
212
    EXPECT_EQ(expectedData, data);
213
}
214

215
TEST_F(StringIDTest, postfix)  // NOLINT
216
{
217
    // Nothing to test except when used by StringHasher
218
}
219

220
TEST_F(StringIDTest, getPyObject)  // NOLINT
221
{
222
    // Arrange
223
    Py_Initialize();
224
    auto id = new App::StringID(1, nullptr);
225
    id->ref();
226

227
    // Act
228
    Py::Object py(id->getPyObject(), true);
229
    id->unref();
230

231
    // Assert
232
    EXPECT_TRUE(PyObject_TypeCheck(py.ptr(), &App::StringIDPy::Type));
233
}
234

235
TEST_F(StringIDTest, getPyObjectWithIndex)  // NOLINT
236
{
237
    // Arrange
238
    Py_Initialize();
239
    auto id = new App::StringID(1, nullptr);
240
    id->ref();
241

242
    // Act
243
    Py::Object py(id->getPyObjectWithIndex(2), true);
244
    id->unref();
245

246
    // Assert
247
    ASSERT_TRUE(PyObject_TypeCheck(py.ptr(), &App::StringIDPy::Type));
248
}
249

250
TEST_F(StringIDTest, toStringWithoutIndex)  // NOLINT
251
{
252
    // Arrange
253
    const long bigHex = 0xfcad10;
254
    auto idA = App::StringID(1, QByteArray {"data", 4});
255
    auto idB = App::StringID(bigHex, QByteArray {"data", 4});
256

257
    // Act
258
    auto resultA = idA.toString();
259
    auto resultB = idB.toString();
260

261
    // Assert
262
    EXPECT_EQ(std::string("#1"), resultA);
263
    EXPECT_EQ(std::string("#fcad10"), resultB);  // Make sure result is in hex
264
}
265

266
TEST_F(StringIDTest, toStringWithIndex)  // NOLINT
267
{
268
    // Arrange
269
    const long bigHex = 0xfcad10;
270
    auto id = App::StringID(1, QByteArray {"data", 4});
271

272
    // Act
273
    auto resultA = id.toString(bigHex);
274
    auto resultB = id.toString(0);
275

276
    // Assert
277
    EXPECT_EQ(std::string("#1:fcad10"), resultA);
278
    EXPECT_EQ(std::string("#1"), resultB);
279
}
280

281
TEST_F(StringIDTest, fromStringWithEOFAndLengthGood)  // NOLINT
282
{
283
    // Arrange
284
    const std::string testString {"#1:fcad"};
285

286
    // Act
287
    auto result =
288
        App::StringID::fromString(testString.c_str(), true, static_cast<int>(testString.length()));
289

290
    // Assert
291
    EXPECT_EQ(result.id, 1);
292
    EXPECT_EQ(result.index, 0xfcad);
293
}
294

295
TEST_F(StringIDTest, fromStringExtraData)  // NOLINT
296
{
297
    // Arrange
298
    const std::string testString {"#1:fcad#2:bad"};
299

300
    // Act
301
    auto trueResult =
302
        App::StringID::fromString(testString.c_str(), true, static_cast<int>(testString.length()));
303
    auto falseResult =
304
        App::StringID::fromString(testString.c_str(), false, static_cast<int>(testString.length()));
305

306
    // Assert
307
    EXPECT_EQ(trueResult.id, -1);
308
    EXPECT_EQ(falseResult.id, 1);
309
}
310

311
TEST_F(StringIDTest, fromStringLengthUnspecified)  // NOLINT
312
{
313
    // Arrange
314
    const std::string testString {"#1:fcad#2:bad"};
315

316
    // Act
317
    auto trueResult = App::StringID::fromString(testString.c_str(), true);
318
    auto falseResult = App::StringID::fromString(testString.c_str(), false);
319

320
    // Assert
321
    EXPECT_EQ(trueResult.id, -1);
322
    EXPECT_EQ(falseResult.id, 1);
323
}
324

325
TEST_F(StringIDTest, fromStringShorterLength)  // NOLINT
326
{
327
    // Arrange
328
    const int dataLength {7};
329
    const std::string testString {"#1:fcad#2:bad"};
330

331
    // Act
332
    auto trueResult = App::StringID::fromString(testString.c_str(), true, dataLength);
333
    auto falseResult = App::StringID::fromString(testString.c_str(), false, dataLength);
334

335
    // Assert
336
    EXPECT_EQ(trueResult.id, 1);
337
    EXPECT_EQ(falseResult.id, 1);
338
}
339

340
TEST_F(StringIDTest, fromStringNoHashtag)  // NOLINT
341
{
342
    // Arrange
343
    const std::string testString {"1:fcad"};
344

345
    // Act
346
    auto result = App::StringID::fromString(testString.c_str(), true);
347

348
    // Assert
349
    EXPECT_EQ(result.id, -1);
350
}
351

352
TEST_F(StringIDTest, fromStringNotHex)  // NOLINT
353
{
354
    // Arrange
355
    const std::string testStringA {"1:freecad"};
356
    const std::string testStringB {"zoink:2"};
357

358
    // Act
359
    auto resultA = App::StringID::fromString(testStringA.c_str(), false);
360
    auto resultB = App::StringID::fromString(testStringB.c_str(), false);
361

362
    // Assert
363
    EXPECT_EQ(resultA.id, -1);
364
    EXPECT_EQ(resultB.id, -1);
365
}
366

367
TEST_F(StringIDTest, fromStringQByteArray)  // NOLINT
368
{
369
    // Arrange
370
    const QByteArray testString {"#1:fcad", 7};
371

372
    // Act
373
    auto result = App::StringID::fromString(testString, true);
374

375
    // Assert
376
    EXPECT_EQ(result.id, 1);
377
    EXPECT_EQ(result.index, 0xfcad);
378
}
379

380
TEST_F(StringIDTest, dataToTextHashed)  // NOLINT
381
{
382
    // Arrange
383
    QByteArray buffer {"120ca87015d849dbea060eaf2295fcc4ee981427", 40};  // NOLINT
384
    auto id = App::StringID(1, buffer, App::StringID::Flag::Hashed);
385

386
    // Act
387
    auto result = id.dataToText(0);
388

389
    // Assert
390
    EXPECT_EQ(result, buffer.toBase64().constData());
391
}
392

393
TEST_F(StringIDTest, dataToTextBinary)  // NOLINT
394
{
395
    // Arrange
396
    QByteArray buffer {"120ca87015d849dbea060eaf2295fcc4ee981427", 40};  // NOLINT
397
    auto id = App::StringID(1, buffer, App::StringID::Flag::Binary);
398

399
    // Act
400
    auto result = id.dataToText(0);
401

402
    // Assert
403
    EXPECT_EQ(result, buffer.toBase64().constData());
404
}
405

406
TEST_F(StringIDTest, dataToTextNoIndex)  // NOLINT
407
{
408
    // Arrange
409
    QByteArray data {"data", 4};
410
    auto id = App::StringID(1, data);
411

412
    // Act
413
    auto result = id.dataToText(0);
414

415
    // Assert
416
    EXPECT_EQ(result, "data");
417
}
418

419
TEST_F(StringIDTest, dataToTextWithIndex)  // NOLINT
420
{
421
    // Arrange
422
    QByteArray data {"data", 4};
423
    auto id = App::StringID(1, data);
424

425
    // Act
426
    auto resultA = id.dataToText(1);
427
    auto resultB = id.dataToText(1024);  // NOLINT
428

429
    // Assert
430
    EXPECT_EQ(resultA, "data1");
431
    EXPECT_EQ(resultB, "data1024");  // Not hex!
432
}
433

434
TEST_F(StringIDTest, dataToTextWithPostfix)  // NOLINT
435
{
436
    // Arrange
437
    QByteArray data {"data", 4};
438
    QByteArray postfix {"postfix", 7};  // NOLINT
439
    auto id = App::StringID(1, data);
440
    id.setPostfix(postfix);
441

442
    // Act
443
    auto result = id.dataToText(1);
444

445
    // Assert
446
    EXPECT_EQ(result, "data1postfix");
447
}
448

449
TEST_F(StringIDTest, dataToBytesNoIndex)  // NOLINT
450
{
451
    // Arrange
452
    QByteArray data {"data", 4};
453
    auto id = App::StringID(1, data);
454

455
    // Act
456
    auto result = id.dataToBytes();
457

458
    // Assert
459
    EXPECT_EQ(data, result);
460
}
461

462
TEST_F(StringIDTest, dataToBytesWithIndex)  // NOLINT
463
{
464
    // Arrange
465
    QByteArray data {"data", 4};
466
    const int index {1234};
467
    auto id = App::StringID(1, data);
468

469
    // Act
470
    auto result = id.dataToBytes(index);
471

472
    // Assert
473
    EXPECT_EQ(data + QByteArray::number(index), result);
474
}
475

476
TEST_F(StringIDTest, dataToBytesWithPostfix)  // NOLINT
477
{
478
    // Arrange
479
    QByteArray data {"data", 4};
480
    QByteArray postfix {"postfix", 7};  // NOLINT
481
    auto id = App::StringID(1, data);
482
    id.setPostfix(postfix);
483

484
    // Act
485
    auto result = id.dataToBytes();
486

487
    // Assert
488
    EXPECT_EQ(data + postfix, result);
489
}
490

491
TEST_F(StringIDTest, dataToBytesWithIndexAndPostfix)  // NOLINT
492
{
493
    // Arrange
494
    QByteArray data {"data", 4};
495
    QByteArray postfix {"postfix", 7};  // NOLINT
496
    const int index {1234};
497
    auto id = App::StringID(1, data);
498
    id.setPostfix(postfix);
499

500
    // Act
501
    auto result = id.dataToBytes(index);
502

503
    // Assert
504
    EXPECT_EQ(data + QByteArray::number(index) + postfix, result);
505
}
506

507
TEST_F(StringIDTest, mark)  // NOLINT
508
{
509
    // Arrange
510
    QByteArray data {"data", 4};
511
    auto id = App::StringID(1, data);
512
    ASSERT_FALSE(id.isMarked());
513

514
    // Act
515
    id.mark();
516

517
    // Assert
518
    EXPECT_TRUE(id.isMarked());
519
}
520

521
TEST_F(StringIDTest, setPersistent)  // NOLINT
522
{
523
    // Arrange
524
    QByteArray data {"data", 4};
525
    auto id = App::StringID(1, data);
526
    ASSERT_FALSE(id.isPersistent());
527

528
    // Act
529
    id.setPersistent(true);
530

531
    // Assert
532
    EXPECT_TRUE(id.isPersistent());
533
}
534

535
TEST_F(StringIDTest, operatorLessThan)  // NOLINT
536
{
537
    // Can't test without a _hasher
538
}
539

540
TEST_F(StringIDTest, compare)  // NOLINT
541
{
542
    // Can't test without a _hasher
543
}
544

545
TEST_F(StringIDTest, IndexIDBooleanConversion)  // NOLINT
546
{
547
    // Arrange
548
    const long id {42};
549
    const int index {123};
550
    App::StringID::IndexID indexIdTrue {id, index};
551
    App::StringID::IndexID indexIdFalse {0, index};
552

553
    // Act & Assert
554
    EXPECT_TRUE(indexIdTrue);
555
    EXPECT_FALSE(indexIdFalse);
556
}
557

558
TEST_F(StringIDTest, IndexIDStreamInsertionOperator)  // NOLINT
559
{
560
    // Arrange
561
    const long id {42};
562
    const int index {123};
563
    App::StringID::IndexID indexIdNonZero {id, index};
564
    App::StringID::IndexID indexIdZero {id, 0};
565
    std::ostringstream stream;
566

567
    // Act
568
    stream << indexIdNonZero << " " << indexIdZero;
569

570
    // Assert
571
    EXPECT_EQ("42:123 42", stream.str());
572
}
573

574

575
class StringIDRefTest: public ::testing::Test
576
{
577
protected:
578
    // void SetUp() override {}
579
    // void TearDown() override {}
580

581
    App::StringID* createStringID() const
582
    {
583
        return new App::StringID {_id, _data};
584
    }
585

586
private:
587
    QByteArray _data {"data", 4};
588
    int _id {1};
589
};
590

591

592
TEST_F(StringIDRefTest, defaultConstructor)  // NOLINT
593
{
594
    // Arrange & Act
595
    auto idRef = App::StringIDRef();
596

597
    // Assert
598
    EXPECT_FALSE(idRef);
599
}
600

601
TEST_F(StringIDRefTest, constructFromNewStringID)  // NOLINT
602
{
603
    // Arrange & Act
604
    auto idRef = App::StringIDRef(createStringID());
605

606
    // Assert
607
    EXPECT_TRUE(idRef);
608
    EXPECT_EQ(1, idRef.getRefCount());
609

610
    // NOTE: the dynamically-allocated StringID is automatically deallocated by the StringIDRef
611
    // when its destructor is called (upon exit from this test function).
612
}
613

614
TEST_F(StringIDRefTest, constructFromStringIDAndIndex)  // NOLINT
615
{
616
    // Arrange
617
    const int index {42};
618

619
    // Act
620
    auto idRef = App::StringIDRef(createStringID(), index);
621

622
    // Assert
623
    EXPECT_TRUE(idRef);
624
    EXPECT_EQ(1, idRef.getRefCount());
625
    EXPECT_EQ(index, idRef.getIndex());
626

627
    // NOTE: the dynamically-allocated StringID is automatically deallocated by the StringIDRef
628
    // when its destructor is called (upon exit from this test function).
629
}
630

631
TEST_F(StringIDRefTest, copyConstructor)  // NOLINT
632
{
633
    // Arrange
634
    const int index {42};
635
    auto idRef = App::StringIDRef(createStringID(), index);
636

637
    // Act
638
    auto newIdRef = App::StringIDRef(idRef);
639

640
    // Assert
641
    EXPECT_TRUE(newIdRef);
642
    EXPECT_EQ(2, newIdRef.getRefCount());
643
    EXPECT_EQ(index, idRef.getIndex());
644
    EXPECT_EQ(index, newIdRef.getIndex());
645
}
646

647
TEST_F(StringIDRefTest, copyConstructorWithIndex)  // NOLINT
648
{
649
    // Arrange
650
    const int index {42};
651
    const int otherIndex {12345};
652
    auto idRef = App::StringIDRef(createStringID(), index);
653

654
    // Act
655
    auto newIdRef = App::StringIDRef(idRef, otherIndex);
656

657
    // Assert
658
    EXPECT_TRUE(newIdRef);
659
    EXPECT_EQ(2, newIdRef.getRefCount());
660
    EXPECT_EQ(index, idRef.getIndex());
661
    EXPECT_EQ(otherIndex, newIdRef.getIndex());
662
}
663

664
TEST_F(StringIDRefTest, moveConstructor)  // NOLINT
665
{
666
    // Arrange
667
    auto idRef = App::StringIDRef(createStringID());
668

669
    // Act
670
    auto newIdRef = App::StringIDRef(std::move(idRef));
671

672
    // Assert
673
    EXPECT_EQ(1, newIdRef.getRefCount());
674
}
675

676
TEST_F(StringIDRefTest, destructor)  // NOLINT
677
{
678
    // Arrange
679
    auto idRef = App::StringIDRef(createStringID());
680

681
    {
682
        auto newIdRef = App::StringIDRef(idRef);
683
        ASSERT_EQ(2, idRef.getRefCount());  // Verify the test setup
684

685
        // Act
686
        // The scope ends, causing newIdRef destructor execution
687
    }
688

689
    // Assert
690
    EXPECT_EQ(1, idRef.getRefCount());
691
}
692

693
TEST_F(StringIDRefTest, reset)  // NOLINT
694
{
695
    // Arrange
696
    auto idRef = App::StringIDRef(createStringID());
697

698
    // Act
699
    idRef.reset();
700

701
    // Assert
702
    EXPECT_FALSE(idRef);
703
}
704

705
TEST_F(StringIDRefTest, resetWithStringID)  // NOLINT
706
{
707
    // Arrange
708
    const int index {42};
709
    auto idRef = App::StringIDRef(createStringID(), index);
710

711
    // Act
712
    idRef.reset(createStringID());
713

714
    // Assert
715
    EXPECT_TRUE(idRef);
716
    EXPECT_NE(index, idRef.getIndex());
717
}
718

719
TEST_F(StringIDRefTest, resetWithStringIDAndIndex)  // NOLINT
720
{
721
    // Arrange
722
    const int indexA {42};
723
    const int indexB {12345};
724
    auto idRef = App::StringIDRef(createStringID(), indexA);
725

726
    // Act
727
    idRef.reset(createStringID(), indexB);
728

729
    // Assert
730
    EXPECT_TRUE(idRef);
731
    EXPECT_EQ(indexB, idRef.getIndex());
732
}
733

734
TEST_F(StringIDRefTest, swap)  // NOLINT
735
{
736
    // Arrange
737
    const int indexA {42};
738
    const int indexB {12345};
739
    auto idRefA = App::StringIDRef(createStringID(), indexA);
740
    auto idRefB = App::StringIDRef(createStringID(), indexB);
741

742
    // Act
743
    idRefA.swap(idRefB);
744

745
    // Assert
746
    EXPECT_EQ(indexB, idRefA.getIndex());
747
    EXPECT_EQ(indexA, idRefB.getIndex());
748
}
749

750
#if defined(__clang__)
751
#pragma clang diagnostic push
752
#pragma clang diagnostic ignored "-Wself-assign-overloaded"
753
#endif
754

755
TEST_F(StringIDRefTest, assignmentFromSelf)  // NOLINT
756
{
757
    // Arrange
758
    auto idRef = App::StringIDRef(createStringID());
759

760
    // Act
761
    idRef = idRef;
762

763
    // Assert
764
    EXPECT_EQ(1, idRef.getRefCount());
765
}
766

767
#if defined(__clang__)
768
#pragma clang diagnostic pop
769
#endif
770

771
TEST_F(StringIDRefTest, assignmentToEmptyFromStringID)  // NOLINT
772
{
773
    // Arrange
774
    Py_Initialize();
775
    auto idRef = App::StringIDRef();
776
    ASSERT_FALSE(idRef);  // Verify setup
777

778
    // Act
779
    idRef = createStringID();
780

781
    // Assert
782
    EXPECT_TRUE(idRef);
783
}
784

785
TEST_F(StringIDRefTest, assignmentFromStringIDRef)  // NOLINT
786
{
787
    // Arrange
788
    auto firstIdRef = App::StringIDRef(createStringID());
789
    auto firstIdRefExtra = firstIdRef;
790
    auto secondIdRef = App::StringIDRef(createStringID());
791

792
    // Act
793
    firstIdRef = secondIdRef;
794

795
    // Assert
796
    EXPECT_EQ(2, secondIdRef.getRefCount());
797
    EXPECT_EQ(2, firstIdRef.getRefCount());
798
    EXPECT_EQ(1, firstIdRefExtra.getRefCount());
799
}
800

801
TEST_F(StringIDRefTest, moveAssignmentFromStringIDRef)  // NOLINT
802
{
803
    auto emptyIdRef = App::StringIDRef();
804
    auto goodIdRef = App::StringIDRef(createStringID());
805
    ASSERT_FALSE(emptyIdRef);  // Verify setup
806

807
    // Act
808
    emptyIdRef = std::move(goodIdRef);
809

810
    // Assert
811
    EXPECT_TRUE(emptyIdRef);
812
    EXPECT_EQ(1, emptyIdRef.getRefCount());
813
}
814

815
TEST_F(StringIDRefTest, operatorLess)  // NOLINT
816
{
817
    // Arrange
818
    auto emptySIDA = App::StringIDRef();
819
    auto emptySIDB = App::StringIDRef();
820
    auto lowID = App::StringIDRef(new App::StringID {1, nullptr});
821
    auto highID = App::StringIDRef(new App::StringID {2, nullptr});
822

823
    // Act & Assert
824
    EXPECT_FALSE(emptySIDA < emptySIDB);
825
    EXPECT_FALSE(emptySIDB < emptySIDA);
826
    EXPECT_TRUE(emptySIDA < lowID);
827
    EXPECT_TRUE(emptySIDA < highID);
828
    EXPECT_TRUE(lowID < highID);
829
    EXPECT_FALSE(highID < lowID);
830

831
    // NOTE: Cannot test the impact of hasher without a StringHasher
832
}
833

834
TEST_F(StringIDRefTest, operatorEquality)  // NOLINT
835
{
836
    // Arrange
837
    auto emptySIDA = App::StringIDRef();
838
    auto emptySIDB = App::StringIDRef();
839
    auto nonEmptyA = App::StringIDRef(new App::StringID {1, nullptr});
840
    auto nonEmptyB = App::StringIDRef(new App::StringID {1, nullptr});
841
    auto nonEmptyOther = App::StringIDRef(new App::StringID {2, nullptr});
842

843
    // Act & Assert
844
    EXPECT_TRUE(emptySIDA == emptySIDB);
845
    EXPECT_TRUE(nonEmptyA == nonEmptyB);
846
    EXPECT_FALSE(emptySIDA == nonEmptyA);
847
    EXPECT_FALSE(nonEmptyA == nonEmptyOther);
848
}
849

850
TEST_F(StringIDRefTest, operatorInequality)  // NOLINT
851
{
852
    // Arrange
853
    auto emptySIDA = App::StringIDRef();
854
    auto emptySIDB = App::StringIDRef();
855
    auto nonEmptyA = App::StringIDRef(new App::StringID {1, nullptr});
856
    auto nonEmptyB = App::StringIDRef(new App::StringID {1, nullptr});
857
    auto nonEmptyOther = App::StringIDRef(new App::StringID {2, nullptr});
858

859
    // Act & Assert
860
    EXPECT_FALSE(emptySIDA != emptySIDB);
861
    EXPECT_FALSE(nonEmptyA != nonEmptyB);
862
    EXPECT_TRUE(emptySIDA != nonEmptyA);
863
    EXPECT_TRUE(nonEmptyA != nonEmptyOther);
864
}
865

866
TEST_F(StringIDRefTest, booleanConversion)  // NOLINT
867
{
868
    // Arrange
869
    auto emptySID = App::StringIDRef();
870
    auto nonEmpty = App::StringIDRef(new App::StringID {1, nullptr});
871

872
    // Act & Assert
873
    EXPECT_FALSE(emptySID);
874
    EXPECT_TRUE(nonEmpty);
875
}
876

877
TEST_F(StringIDRefTest, getRefCount)  // NOLINT
878
{
879
    // Arrange
880
    auto stringID = createStringID();
881
    auto stringIDRef = App::StringIDRef(stringID);
882

883
    // Act
884
    auto firstCount = stringIDRef.getRefCount();
885
    auto stringIDRef2 = App::StringIDRef(stringID);
886
    auto secondCount = stringIDRef.getRefCount();
887

888
    // Assert
889
    EXPECT_EQ(1, firstCount);
890
    EXPECT_EQ(2, secondCount);
891
}
892

893
TEST_F(StringIDRefTest, toString)  // NOLINT
894
{
895
    // Arrange
896
    auto emptySID = App::StringIDRef();
897
    auto nonEmpty = App::StringIDRef(createStringID());
898

899
    // Act
900
    auto empty = emptySID.toString();
901
    auto nonempty = nonEmpty.toString();
902

903
    // Assert
904
    // Only confirm that the function call is passed along: the real test is in the StringID class
905
    EXPECT_TRUE(empty.empty());
906
    EXPECT_FALSE(nonempty.empty());
907
}
908

909
TEST_F(StringIDRefTest, dataToText)  // NOLINT
910
{
911
    // Arrange
912
    auto emptySID = App::StringIDRef();
913
    auto nonEmpty = App::StringIDRef(createStringID());
914

915
    // Act
916
    auto empty = emptySID.dataToText();
917
    auto nonempty = nonEmpty.dataToText();
918

919
    // Assert
920
    // Only confirm that the function call is passed along: the real test is in the StringID class
921
    EXPECT_TRUE(empty.empty());
922
    EXPECT_FALSE(nonempty.empty());
923
}
924

925
TEST_F(StringIDRefTest, constData)  // NOLINT
926
{
927
    // Arrange
928
    auto sid = App::StringIDRef(createStringID());
929

930
    // Act
931
    auto constData = sid.constData();
932

933
    // Assert
934
    ASSERT_NE(constData, nullptr);
935
    EXPECT_STREQ(constData, "data");
936
}
937

938
TEST_F(StringIDRefTest, deref)  // NOLINT
939
{
940
    // Arrange
941
    auto sid = createStringID();
942
    auto ref = App::StringIDRef(sid);
943

944
    // Act & Assert
945
    EXPECT_EQ(sid, &(ref.deref()));
946
}
947

948
TEST_F(StringIDRefTest, value)  // NOLINT
949
{
950
    // Arrange
951
    auto empty = App::StringIDRef();
952
    auto nonEmpty = App::StringIDRef(createStringID());
953

954
    // Act
955
    auto emptyValue = empty.value();
956
    auto nonEmptyValue = nonEmpty.value();
957

958
    // Assert
959
    EXPECT_EQ(0, emptyValue);
960
    EXPECT_NE(0, nonEmptyValue);
961
}
962

963
TEST_F(StringIDRefTest, relatedIDs)  // NOLINT
964
{
965
    // Nothing to test without a StringHasher
966
}
967

968
TEST_F(StringIDRefTest, isBinary)  // NOLINT
969
{
970
    // Arrange
971
    auto nothing = App::StringIDRef();
972
    auto binary = App::StringIDRef(new App::StringID {1, nullptr, App::StringID::Flag::Binary});
973
    auto nonBinary = App::StringIDRef(new App::StringID {1, nullptr, App::StringID::Flag::None});
974

975
    // Act & Assert
976
    EXPECT_FALSE(nothing.isBinary());
977
    EXPECT_TRUE(binary.isBinary());
978
    EXPECT_FALSE(nonBinary.isBinary());
979
}
980

981
TEST_F(StringIDRefTest, isHashed)  // NOLINT
982
{
983
    // Arrange
984
    auto nothing = App::StringIDRef();
985
    auto hashed = App::StringIDRef(new App::StringID {1, nullptr, App::StringID::Flag::Hashed});
986
    auto nonHashed = App::StringIDRef(new App::StringID {1, nullptr, App::StringID::Flag::None});
987

988
    // Act & Assert
989
    EXPECT_FALSE(nothing.isHashed());
990
    EXPECT_TRUE(hashed.isHashed());
991
    EXPECT_FALSE(nonHashed.isHashed());
992
}
993

994
TEST_F(StringIDRefTest, toBytes)  // NOLINT
995
{
996
    // Arrange
997
    QByteArray byteStorage;
998
    auto ref = App::StringIDRef(createStringID());
999

1000
    // Act
1001
    ref.toBytes(byteStorage);
1002

1003
    // Assert
1004
    EXPECT_FALSE(byteStorage.isNull());
1005
}
1006

1007
TEST_F(StringIDRefTest, getPyObject)  // NOLINT
1008
{
1009
    Py_Initialize();
1010
    // Arrange
1011
    auto ref = App::StringIDRef(createStringID());
1012
    auto empty = App::StringIDRef();
1013

1014
    // Act
1015
    Py::Object pyObject(ref.getPyObject(), true);
1016
    Py::Object none(empty.getPyObject(), true);
1017

1018
    // Assert
1019
    EXPECT_TRUE(PyObject_TypeCheck(pyObject.ptr(), &App::StringIDPy::Type));
1020
    EXPECT_EQ(none.ptr(), Py_None);
1021
}
1022

1023
TEST_F(StringIDRefTest, mark)  // NOLINT
1024
{
1025
    // Arrange
1026
    auto ref = App::StringIDRef(createStringID());
1027
    ASSERT_FALSE(ref.isMarked());
1028

1029
    // Act
1030
    ref.mark();
1031

1032
    // Assert
1033
    EXPECT_TRUE(ref.isMarked());
1034
}
1035

1036
TEST_F(StringIDRefTest, isMarked)  // NOLINT
1037
{
1038
    // Arrange
1039
    auto marked = App::StringIDRef(new App::StringID(1, nullptr, App::StringID::Flag::Marked));
1040
    auto notMarked = App::StringIDRef(createStringID());
1041

1042
    // Act & Assert
1043
    EXPECT_TRUE(marked.isMarked());
1044
    EXPECT_FALSE(notMarked.isMarked());
1045
}
1046

1047
TEST_F(StringIDRefTest, isFromSameHasher)  // NOLINT
1048
{
1049
    // Nothing to test, requires a StringHasher
1050
}
1051

1052
TEST_F(StringIDRefTest, getHasher)  // NOLINT
1053
{
1054
    // Nothing to test, requires a StringHasher
1055
}
1056

1057
TEST_F(StringIDRefTest, setPersistent)  // NOLINT
1058
{
1059
    // Arrange
1060
    auto persistent = App::StringIDRef(createStringID());
1061
    ASSERT_FALSE(persistent.deref().isPersistent());
1062

1063
    // Act
1064
    persistent.setPersistent(true);
1065

1066
    // Assert
1067
    ASSERT_TRUE(persistent.deref().isPersistent());
1068
}
1069

1070

1071
class StringHasherTest: public ::testing::Test
1072
{
1073
protected:
1074
    void SetUp() override
1075
    {
1076
        Py_Initialize();
1077
        _hasher = Base::Reference<App::StringHasher>(new App::StringHasher);
1078
    }
1079

1080
    void TearDown() override
1081
    {
1082
        _hasher->clear();
1083
    }
1084

1085
    Base::Reference<App::StringHasher> Hasher()
1086
    {
1087
        return _hasher;
1088
    }
1089

1090
    static Data::MappedName givenMappedName(const char* name, const char* postfix = nullptr)
1091
    {
1092
        QByteArray expectedPrefix {name, static_cast<int>(std::strlen(name))};
1093
        Data::MappedName mappedName(expectedPrefix);
1094
        if (postfix) {
1095
            QByteArray expectedPostfix {postfix, static_cast<int>(std::strlen(postfix))};
1096
            Data::MappedName mappedNameA(mappedName, expectedPostfix.data());
1097
            return mappedNameA;
1098
        }
1099
        return mappedName;
1100
    }
1101

1102
    /// Put a couple of things into the hash table: at the end of this call the size of the table
1103
    /// is 2, one postfix string and one prefix+postfix combination.
1104
    App::StringIDRef givenSomeHashedValues()
1105
    {
1106
        const std::string prefix {"Test1"};
1107
        const std::string postfix {";:M;FUS;:Hb:7,F"};
1108
        auto mappedName = givenMappedName(prefix.c_str(), postfix.c_str());
1109
        QVector<App::StringIDRef> sids;
1110
        return Hasher()->getID(mappedName, sids);
1111
    }
1112

1113
private:
1114
    Base::Reference<App::StringHasher> _hasher;
1115
};
1116

1117
TEST_F(StringHasherTest, defaultConstructor)  // NOLINT
1118
{
1119
    // Arrange
1120
    // Done in Setup()
1121

1122
    // Act
1123
    // Done in Setup()
1124

1125
    // Assert
1126
    EXPECT_EQ(0, Hasher()->size());
1127
}
1128

1129
TEST_F(StringHasherTest, getMemSize)  // NOLINT
1130
{
1131
    // Arrange
1132
    givenSomeHashedValues();
1133

1134
    // Act
1135
    auto result = Hasher()->getMemSize();
1136

1137
    // Assert
1138
    // getMemSize is advisory only, so the only thing we can confidently assert is that it is larger
1139
    // than the number of values in the hash table.
1140
    EXPECT_LT(Hasher()->size(), result);
1141
}
1142

1143
TEST_F(StringHasherTest, Save)  // NOLINT
1144
{
1145
    // Arrange
1146
    // Act
1147
    // Assert
1148
}
1149

1150
TEST_F(StringHasherTest, Restore)  // NOLINT
1151
{
1152
    // Arrange
1153
    // Act
1154
    // Assert
1155
}
1156

1157
TEST_F(StringHasherTest, SaveDocFile)  // NOLINT
1158
{
1159
    // Arrange
1160
    // Act
1161
    // Assert
1162
}
1163

1164
TEST_F(StringHasherTest, RestoreDocFile)  // NOLINT
1165
{
1166
    // Arrange
1167
    // Act
1168
    // Assert
1169
}
1170

1171
TEST_F(StringHasherTest, setPersistenceFileName)  // NOLINT
1172
{
1173
    // Arrange
1174
    // Act
1175
    // Assert
1176
}
1177

1178
TEST_F(StringHasherTest, getPersistenceFileName)  // NOLINT
1179
{
1180
    // Arrange
1181
    // Act
1182
    // Assert
1183
}
1184

1185
TEST_F(StringHasherTest, getIDFromQByteArrayShort)  // NOLINT
1186
{
1187
    // Arrange
1188
    const std::array<char, 5> string {"data"};
1189
    QByteArray qba(string.data(), string.size());
1190
    Hasher()->setThreshold(string.size() + 1);
1191

1192
    // Act
1193
    auto id = Hasher()->getID(qba, App::StringHasher::Option::Hashable);
1194

1195
    // Assert
1196
    EXPECT_STREQ(string.data(), id.constData());
1197
    EXPECT_FALSE(id.isHashed());
1198
    EXPECT_NE(qba.constData(), id.constData());  // A copy was made, the pointers differ
1199
    EXPECT_EQ(2, id.getRefCount());
1200
}
1201

1202
TEST_F(StringHasherTest, getIDFromQByteArrayLongHashable)  // NOLINT
1203
{
1204
    // Arrange
1205
    const std::array<char, 47> string {"data that is longer than our hasher threshold"};
1206
    QByteArray qba(string.data(), string.size());
1207
    Hasher()->setThreshold(string.size() - 1);
1208

1209
    // Act
1210
    auto id = Hasher()->getID(qba, App::StringHasher::Option::Hashable);
1211

1212
    // Assert
1213
    EXPECT_STRNE(string.data(), id.constData());
1214
    EXPECT_TRUE(id.isHashed());
1215
    EXPECT_NE(qba.constData(), id.constData());  // A copy was made, the pointers differ
1216
}
1217

1218
TEST_F(StringHasherTest, getIDFromQByteArrayLongUnhashable)  // NOLINT
1219
{
1220
    // Arrange
1221
    const std::array<char, 47> string {"data that is longer than our hasher threshold"};
1222
    QByteArray qba(string.data(), string.size());
1223
    Hasher()->setThreshold(string.size() - 1);
1224

1225
    // Act
1226
    auto id = Hasher()->getID(qba, App::StringHasher::Option::None);
1227

1228
    // Assert
1229
    EXPECT_STREQ(string.data(), id.constData());
1230
    EXPECT_FALSE(id.isHashed());
1231
    EXPECT_NE(qba.constData(), id.constData());  // A copy was made, the pointers differ
1232
}
1233

1234
TEST_F(StringHasherTest, getIDFromQByteArrayNoCopy)  // NOLINT
1235
{
1236
    // Arrange
1237
    const std::array<char, 5> string {"data"};
1238
    QByteArray qba(string.data(), string.size());
1239
    Hasher()->setThreshold(string.size() + 1);
1240

1241
    // Act
1242
    auto id = Hasher()->getID(qba, App::StringHasher::Option::NoCopy);
1243

1244
    // Assert
1245
    EXPECT_STREQ(string.data(), id.constData());
1246
    EXPECT_EQ(qba.constData(), id.constData());  // No copy was made, the pointers are the same
1247
}
1248

1249
TEST_F(StringHasherTest, getIDFromQByteArrayTwoDifferentStrings)  // NOLINT
1250
{
1251
    // Arrange
1252
    const std::array<char, 6> stringA {"dataA"};
1253
    QByteArray qbaA(stringA.data(), stringA.size());
1254
    const std::array<char, 6> stringB {"dataB"};
1255
    QByteArray qbaB(stringB.data(), stringB.size());
1256

1257
    // Act
1258
    auto idA = Hasher()->getID(qbaA);
1259
    auto idB = Hasher()->getID(qbaB);
1260

1261
    // Assert
1262
    EXPECT_NE(idA.dataToText(), idB.dataToText());
1263
}
1264

1265
TEST_F(StringHasherTest, getIDFromQByteArrayTwoIdenticalStrings)  // NOLINT
1266
{
1267
    // Arrange
1268
    const std::array<char, 5> stringA {"data"};
1269
    QByteArray qbaA(stringA.data(), stringA.size());
1270
    const std::array<char, 5> stringB {"data"};
1271
    QByteArray qbaB(stringB.data(), stringB.size());
1272

1273
    // Act
1274
    auto idA = Hasher()->getID(qbaA);
1275
    auto idB = Hasher()->getID(qbaB);
1276

1277
    // Assert
1278
    EXPECT_EQ(idA.dataToText(), idB.dataToText());
1279
}
1280

1281
TEST_F(StringHasherTest, getIDFromQByteArrayBinaryFlag)  // NOLINT
1282
{
1283
    // Arrange
1284
    const std::array<char, 5> string {"data"};
1285
    QByteArray qba(string.data(), string.size());
1286

1287
    // Act
1288
    auto id = Hasher()->getID(qba, App::StringHasher::Option::Binary);
1289

1290
    // Assert
1291
    EXPECT_TRUE(id.isBinary());
1292
}
1293

1294
TEST_F(StringHasherTest, getIDFromCString)  // NOLINT
1295
{
1296
    // Arrange
1297
    // Act
1298
    // Assert
1299
}
1300

1301
/*
1302
 * Things that have to be tested for getIDFromMappedName:
1303
 *   1. With and without postfix (every other path must test both)
1304
 *   2. Existing entry: short circuits
1305
 *   3. Raw data and non-raw
1306
 *   4. Postfix contains # and not
1307
 *   5. Indexed name and not
1308
 *   6. sids empty and sids with content
1309
 *   7. sids whose hasher==this and whose hasher is something else
1310
 *   8. If sids.size() > 10, duplicates get removed
1311
 */
1312

1313
TEST_F(StringHasherTest, getIDFromMappedNameWithoutPostfixWithoutIndex)  // NOLINT
1314
{
1315
    // Arrange
1316
    const char* name {"Face"};
1317
    QByteArray expectedPrefix {name, static_cast<int>(std::strlen(name))};
1318
    Data::MappedName mappedName1(expectedPrefix);
1319
    QVector<App::StringIDRef> sids;
1320

1321
    // Act
1322
    auto id = Hasher()->getID(mappedName1, sids);
1323

1324
    // Assert
1325
    EXPECT_EQ(id.dataToText(), mappedName1.toString());
1326
}
1327

1328
TEST_F(StringHasherTest, getIDFromMappedNameWithoutPostfixWithIndex)  // NOLINT
1329
{
1330
    // Arrange
1331
    const char* expectedName {"Face"};
1332
    QByteArray expectedPrefix {expectedName, static_cast<int>(std::strlen(expectedName))};
1333
    const char* name {"Face3"};
1334
    QByteArray prefix {name, static_cast<int>(std::strlen(name))};
1335
    Data::MappedName mappedName1(prefix);
1336
    QVector<App::StringIDRef> sids;
1337

1338
    // Act
1339
    auto id = Hasher()->getID(mappedName1, sids);
1340

1341
    // Assert
1342
    EXPECT_EQ(id.dataToText(), mappedName1.toString());
1343
}
1344

1345
TEST_F(StringHasherTest, getIDFromMappedNameWithoutIndexWithPostfix)  // NOLINT
1346
{
1347
    // Arrange
1348
    const char* name {"Face"};
1349
    QByteArray expectedPrefix {name, static_cast<int>(std::strlen(name))};
1350
    const char* postfix {";:M;FUS;:Hb:7,F"};
1351
    QByteArray expectedPostfix {postfix, static_cast<int>(std::strlen(postfix))};
1352
    Data::MappedName mappedName1(expectedPrefix);
1353
    Data::MappedName mappedName2(mappedName1, expectedPostfix.data());
1354
    QVector<App::StringIDRef> sids;
1355

1356
    // Act
1357
    auto id = Hasher()->getID(mappedName2, sids);
1358

1359
    // Assert
1360
    EXPECT_EQ(expectedPrefix, id.deref().data());
1361
    EXPECT_EQ(expectedPostfix, id.deref().postfix());
1362
}
1363

1364
TEST_F(StringHasherTest, getIDFromMappedNameWithIndexWithPostfix)  // NOLINT
1365
{
1366
    // Arrange
1367
    const char* name {"Face3"};
1368
    QByteArray expectedPrefix {name, static_cast<int>(std::strlen(name))};
1369
    const char* postfix {";:M;FUS;:Hb:7,F"};
1370
    QByteArray expectedPostfix {postfix, static_cast<int>(std::strlen(postfix))};
1371
    Data::MappedName mappedName1(expectedPrefix);
1372
    Data::MappedName mappedName2(mappedName1, expectedPostfix.data());
1373
    QVector<App::StringIDRef> sids;
1374

1375
    // Act
1376
    auto id = Hasher()->getID(mappedName2, sids);
1377

1378
    // Assert
1379
    EXPECT_EQ(id.dataToText(), mappedName2.toString());
1380
}
1381

1382
TEST_F(StringHasherTest, getIDFromMappedNameExistingNameNoIndex)  // NOLINT
1383
{
1384
    // Arrange
1385
    Data::MappedName mappedName1 = givenMappedName("SomeTestName");
1386
    QVector<App::StringIDRef> sids;
1387
    auto firstIDInserted = Hasher()->getID(mappedName1, sids);
1388
    ASSERT_EQ(1, Hasher()->size());
1389

1390
    // Act
1391
    auto secondIDInserted = Hasher()->getID(mappedName1, sids);
1392

1393
    // Assert
1394
    EXPECT_EQ(secondIDInserted.dataToText(), mappedName1.toString());
1395
}
1396

1397
TEST_F(StringHasherTest, getIDFromMappedNameExistingNameWithIndex)  // NOLINT
1398
{
1399
    // Arrange
1400
    auto mappedNameA = givenMappedName("Test1");
1401
    auto mappedNameB = givenMappedName("Test2");
1402
    QVector<App::StringIDRef> sids;
1403
    auto firstIDInserted = Hasher()->getID(mappedNameA, sids);
1404

1405
    // Act
1406
    auto secondIDInserted = Hasher()->getID(mappedNameB, sids);
1407

1408
    // Assert
1409
    EXPECT_EQ(firstIDInserted.dataToText(), mappedNameA.toString());
1410
    EXPECT_EQ(secondIDInserted.dataToText(), mappedNameB.toString());
1411
}
1412

1413
TEST_F(StringHasherTest, getIDFromMappedNameExistingNameWithIndexAndPostfix)  // NOLINT
1414
{
1415
    // Arrange
1416
    auto mappedNameA = givenMappedName("Test1", ";:M;FUS;:Hb:7,F");
1417
    auto mappedNameB = givenMappedName("Test2", ";:M;FUS;:Hb:7,F");
1418
    QVector<App::StringIDRef> sids;
1419
    auto firstIDInserted = Hasher()->getID(mappedNameA, sids);
1420

1421
    // Act
1422
    auto secondIDInserted = Hasher()->getID(mappedNameB, sids);
1423

1424
    // Assert
1425
    EXPECT_EQ(firstIDInserted.dataToText(), mappedNameA.toString());
1426
    EXPECT_EQ(secondIDInserted.dataToText(), mappedNameB.toString());
1427
}
1428

1429
TEST_F(StringHasherTest, getIDFromMappedNameDuplicateWithEncodedPostfix)  // NOLINT
1430
{
1431
    // Arrange
1432
    auto mappedNameA = givenMappedName("Test1", ";:M;FUS;:Hb:7,F");
1433
    auto mappedNameB = givenMappedName("Test1", "#1");
1434
    QVector<App::StringIDRef> sids;
1435
    auto firstIDInserted = Hasher()->getID(mappedNameA, sids);
1436

1437
    // Act
1438
    auto secondIDInserted = Hasher()->getID(mappedNameB, sids);
1439

1440
    // Assert
1441
    EXPECT_EQ(firstIDInserted.dataToText(), mappedNameA.toString());
1442
    EXPECT_EQ(secondIDInserted.dataToText(), mappedNameB.toString());
1443
}
1444

1445
TEST_F(StringHasherTest, getIDFromIntegerIDNoSuchID)  // NOLINT
1446
{
1447
    // Arrange
1448
    // Do nothing, so the hash table is empty
1449

1450
    // Act
1451
    auto result = Hasher()->getID(1);
1452

1453
    // Assert
1454
    EXPECT_FALSE(result);
1455
}
1456

1457
TEST_F(StringHasherTest, getIDFromIntegerIDBadID)  // NOLINT
1458
{
1459
    // Arrange
1460
    const std::string prefix {"Test1"};
1461
    auto mappedName = givenMappedName(prefix.c_str());
1462
    QVector<App::StringIDRef> sids;
1463
    auto inserted = Hasher()->getID(mappedName, sids);
1464
    ASSERT_EQ(1, Hasher()->size());
1465

1466
    // Act
1467
    auto result = Hasher()->getID(-1);
1468

1469
    // Assert
1470
    EXPECT_FALSE(result);
1471
}
1472

1473

1474
TEST_F(StringHasherTest, getIDMap)  // NOLINT
1475
{
1476
    // Arrange
1477
    givenSomeHashedValues();
1478

1479
    // Act
1480
    auto map = Hasher()->getIDMap();
1481

1482
    // Assert
1483
    EXPECT_GT(map.size(), 0);
1484
}
1485

1486
TEST_F(StringHasherTest, clear)  // NOLINT
1487
{
1488
    // Arrange
1489
    givenSomeHashedValues();
1490

1491
    // Act
1492
    Hasher()->clear();
1493

1494
    // Assert
1495
    EXPECT_EQ(0, Hasher()->size());
1496
}
1497

1498
TEST_F(StringHasherTest, size)  // NOLINT
1499
{
1500
    // Arrange
1501
    givenSomeHashedValues();
1502

1503
    // Act
1504
    auto result = Hasher()->size();
1505

1506
    // Assert
1507
    EXPECT_GT(result, 0);
1508
}
1509

1510
TEST_F(StringHasherTest, count)  // NOLINT
1511
{
1512
    // Arrange
1513
    givenSomeHashedValues();
1514

1515
    // Act
1516
    auto result = Hasher()->count();
1517

1518
    // Assert
1519
    EXPECT_GT(result, 0);
1520
}
1521

1522
TEST_F(StringHasherTest, getPyObject)  // NOLINT
1523
{
1524
    // Arrange - done in setUp()
1525

1526
    // Act
1527
    Py::Object py(Hasher()->getPyObject(), true);
1528

1529
    // Assert
1530
    EXPECT_TRUE(PyObject_TypeCheck(py.ptr(), &App::StringHasherPy::Type));
1531
}
1532

1533
TEST_F(StringHasherTest, setGetSaveAll)  // NOLINT
1534
{
1535
    // Arrange - done by setUp()
1536

1537
    // Act
1538
    Hasher()->setSaveAll(true);
1539
    bool expectedTrue = Hasher()->getSaveAll();
1540
    Hasher()->setSaveAll(false);
1541
    bool expectedFalse = Hasher()->getSaveAll();
1542

1543
    // Assert
1544
    EXPECT_TRUE(expectedTrue);
1545
    EXPECT_FALSE(expectedFalse);
1546
}
1547

1548
TEST_F(StringHasherTest, setGetThreshold)  // NOLINT
1549
{
1550
    // Arrange
1551
    const int expectedThreshold {42};
1552

1553
    // Act
1554
    Hasher()->setThreshold(expectedThreshold);
1555
    auto foundThreshold = Hasher()->getThreshold();
1556

1557
    // Assert
1558
    EXPECT_EQ(expectedThreshold, foundThreshold);
1559
}
1560

1561
TEST_F(StringHasherTest, clearMarks)  // NOLINT
1562
{
1563
    // Arrange
1564
    auto ref = givenSomeHashedValues();
1565
    ref.mark();
1566
    ASSERT_TRUE(ref.isMarked());
1567

1568
    // Act
1569
    Hasher()->clearMarks();
1570

1571
    // Assert
1572
    ASSERT_FALSE(ref.isMarked());
1573
}
1574

1575
TEST_F(StringHasherTest, compact)  // NOLINT
1576
{
1577
    // Arrange
1578
    givenSomeHashedValues();
1579

1580
    // Act
1581
    Hasher()->compact();
1582

1583
    // Assert
1584
    EXPECT_EQ(0, Hasher()->count());
1585
}
1586

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.