Repository navigation
Expand file tree
/
Copy pathtest_git_diff_cache.cpp
More file actions
165 lines (134 loc) · 4.56 KB
/
Copy pathtest_git_diff_cache.cpp
File metadata and controls
165 lines (134 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* This file is part of Notepad Next.
* Copyright 2026 NotepadAI contributors
*
* Notepad Next is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
#include <QtTest>
#include "GitDiffCache.h"
#include "GitDiffParser.h"
#include <memory>
class TestGitDiffCache : public QObject
{
Q_OBJECT
private slots:
void keyFor_stableAndUnique();
void getMissing_returnsNull();
void putAndGet_roundTrip();
void put_replacesExisting();
void lru_orderingUpdatedOnGet();
void byteBudget_evictsLruFirst();
void clear_dropsEverything();
};
namespace {
GitDiffCache::Entry makeEntry(int rows = 1)
{
auto r = std::make_shared<GitDiffParser::Result>();
r->texts.reserve(rows);
for (int i = 0; i < rows; ++i) r->texts.push_back(QByteArrayLiteral("x"));
r->kinds.fill(GitDiffParser::LineKind::Context, rows);
r->oldLn.fill(-1, rows);
r->newLn.fill(-1, rows);
return GitDiffCache::Entry{ std::move(r), nullptr };
}
} // namespace
void TestGitDiffCache::keyFor_stableAndUnique()
{
const QString repo = QStringLiteral("/tmp/repo");
const QString a = QStringLiteral("src/a.cpp");
const QString b = QStringLiteral("src/b.cpp");
// Same input → same key (stable hashing).
QCOMPARE(GitDiffCache::keyFor(repo, a, false),
GitDiffCache::keyFor(repo, a, false));
// Staged flag changes the key.
QVERIFY(GitDiffCache::keyFor(repo, a, false)
!= GitDiffCache::keyFor(repo, a, true));
// Different paths produce different keys.
QVERIFY(GitDiffCache::keyFor(repo, a, false)
!= GitDiffCache::keyFor(repo, b, false));
// Different repo produces different keys (guards against collisions when
// multiple workspaces share path suffixes).
QVERIFY(GitDiffCache::keyFor(repo, a, false)
!= GitDiffCache::keyFor(QStringLiteral("/tmp/other"), a, false));
}
void TestGitDiffCache::getMissing_returnsNull()
{
GitDiffCache cache(1024);
QVERIFY(!cache.get(0xdeadbeef));
QVERIFY(!cache.get(0));
}
void TestGitDiffCache::putAndGet_roundTrip()
{
GitDiffCache cache(1024 * 1024);
auto entry = makeEntry();
cache.put(42, entry, 100);
auto got = cache.get(42);
QVERIFY(got);
QCOMPARE(got.parsed.get(), entry.parsed.get());
}
void TestGitDiffCache::put_replacesExisting()
{
GitDiffCache cache(1024 * 1024);
auto first = makeEntry(1);
auto second = makeEntry(2);
cache.put(7, first, 50);
const qsizetype afterFirst = cache.sizeBytes();
QVERIFY(afterFirst > 0);
cache.put(7, second, 200);
auto got = cache.get(7);
QCOMPARE(got.parsed.get(), second.parsed.get());
// Replacement must account for the old footprint being removed first —
// otherwise sizeBytes would double-count.
QCOMPARE(cache.sizeBytes(), (qsizetype)((200 * 13) / 10));
}
void TestGitDiffCache::lru_orderingUpdatedOnGet()
{
// capacity exactly fits two entries of footprint = ceil(bytes*1.3); pick 100b
// each → 130b each → capacity 260b. Inserting a third must evict the LRU.
GitDiffCache cache(260);
auto e1 = makeEntry();
auto e2 = makeEntry();
auto e3 = makeEntry();
cache.put(1, e1, 100);
cache.put(2, e2, 100);
// Touch key 1 — moves it to MRU, so key 2 becomes LRU.
QVERIFY(cache.get(1));
cache.put(3, e3, 100);
// Key 2 should have been evicted, key 1 + key 3 still present.
QVERIFY(cache.get(1));
QVERIFY(!cache.get(2));
QVERIFY(cache.get(3));
}
void TestGitDiffCache::byteBudget_evictsLruFirst()
{
GitDiffCache cache(260); // ~2 slots at 100 raw bytes each
auto e1 = makeEntry();
auto e2 = makeEntry();
auto e3 = makeEntry();
cache.put(10, e1, 100);
cache.put(20, e2, 100);
cache.put(30, e3, 100); // pushes total to 390b → must evict key 10 (LRU).
QVERIFY(!cache.get(10));
QVERIFY(cache.get(20));
QVERIFY(cache.get(30));
QVERIFY(cache.sizeBytes() <= cache.capacityBytes());
}
void TestGitDiffCache::clear_dropsEverything()
{
GitDiffCache cache(1024 * 1024);
cache.put(1, makeEntry(), 100);
cache.put(2, makeEntry(), 100);
QVERIFY(cache.sizeBytes() > 0);
cache.clear();
QCOMPARE(cache.sizeBytes(), (qsizetype)0);
QVERIFY(!cache.get(1));
QVERIFY(!cache.get(2));
// Cache is reusable after clear.
cache.put(3, makeEntry(), 50);
QVERIFY(cache.get(3));
}
QTEST_GUILESS_MAIN(TestGitDiffCache)
#include "test_git_diff_cache.moc"