]> git.proxmox.com Git - pve-eslint.git/blob - eslint/tests/lib/cli-engine/lint-result-cache.js
a3b6ee3ab2c0ef3626d520676b95bbf4bb283b48
[pve-eslint.git] / eslint / tests / lib / cli-engine / lint-result-cache.js
1 /**
2 * @fileoverview Unit tests for lint result cache.
3 * @author Kevin Partington
4 */
5 "use strict";
6
7 //-----------------------------------------------------------------------------
8 // Requirements
9 //-----------------------------------------------------------------------------
10
11 const assert = require("chai").assert,
12 { CLIEngine } = require("../../../lib/cli-engine"),
13 fs = require("fs"),
14 path = require("path"),
15 proxyquire = require("proxyquire"),
16 sinon = require("sinon");
17
18 //-----------------------------------------------------------------------------
19 // Tests
20 //-----------------------------------------------------------------------------
21
22 describe("LintResultCache", () => {
23 const fixturePath = path.resolve(__dirname, "../../fixtures/lint-result-cache");
24 const cacheFileLocation = path.join(fixturePath, ".eslintcache");
25 const fileEntryCacheStubs = {};
26
27 let LintResultCache,
28 hashStub,
29 fakeConfig,
30 fakeErrorResults,
31 fakeErrorResultsAutofix;
32
33 before(() => {
34 hashStub = sinon.stub();
35
36 let shouldFix = false;
37
38 // Get lint results for test fixtures
39 const cliEngine = new CLIEngine({
40 cache: false,
41 ignore: false,
42 globInputPaths: false,
43 fix: () => shouldFix
44 });
45
46 // Get results without autofixing...
47 fakeErrorResults = cliEngine.executeOnFiles([path.join(fixturePath, "test-with-errors.js")]).results[0];
48
49 // ...and with autofixing
50 shouldFix = true;
51 fakeErrorResultsAutofix = cliEngine.executeOnFiles([path.join(fixturePath, "test-with-errors.js")]).results[0];
52
53 // Set up LintResultCache with fake fileEntryCache module
54 LintResultCache = proxyquire("../../../lib/cli-engine/lint-result-cache.js", {
55 "file-entry-cache": fileEntryCacheStubs,
56 "./hash": hashStub
57 });
58 });
59
60 afterEach(done => {
61 sinon.reset();
62
63 fs.unlink(cacheFileLocation, err => {
64 if (err && err.code !== "ENOENT") {
65 return done(err);
66 }
67
68 return done();
69 });
70 });
71
72 describe("constructor", () => {
73 it("should throw an error if cache file path is not provided", () => {
74 assert.throws(() => new LintResultCache(), /Cache file location is required/u);
75 });
76
77 it("should successfully create an instance if cache file location is provided", () => {
78 const instance = new LintResultCache(cacheFileLocation);
79
80 assert.ok(instance, "Instance should have been created successfully");
81 });
82 });
83
84 describe("getCachedLintResults", () => {
85 const filePath = path.join(fixturePath, "test-with-errors.js");
86 const hashOfConfig = "hashOfConfig";
87
88 let cacheEntry,
89 getFileDescriptorStub,
90 lintResultsCache;
91
92 before(() => {
93 getFileDescriptorStub = sinon.stub();
94
95 fileEntryCacheStubs.create = () => ({
96 getFileDescriptor: getFileDescriptorStub
97 });
98 });
99
100 after(() => {
101 delete fileEntryCacheStubs.create;
102 });
103
104 beforeEach(() => {
105 cacheEntry = {
106 meta: {
107
108 // Serialized results will have null source
109 results: Object.assign({}, fakeErrorResults, { source: null }),
110
111 hashOfConfig
112 }
113 };
114
115 getFileDescriptorStub.withArgs(filePath)
116 .returns(cacheEntry);
117
118 fakeConfig = {};
119
120 lintResultsCache = new LintResultCache(cacheFileLocation);
121 });
122
123 describe("when calculating the hashing", () => {
124 it("contains eslint version during hashing", () => {
125 const version = "eslint-=-version";
126 const NewLintResultCache = proxyquire("../../../lib/cli-engine/lint-result-cache.js", {
127 "../../package.json": { version },
128 "./hash": hashStub
129 });
130 const newLintResultCache = new NewLintResultCache(cacheFileLocation);
131
132 newLintResultCache.getCachedLintResults(filePath, fakeConfig);
133 assert.ok(hashStub.calledOnce);
134 assert.ok(hashStub.calledWithMatch(version));
135 });
136
137 it("contains node version during hashing", () => {
138 const version = "node-=-version";
139
140 sinon.stub(process, "version").value(version);
141 const NewLintResultCache = proxyquire("../../../lib/cli-engine/lint-result-cache.js", {
142 "./hash": hashStub
143 });
144 const newLintResultCache = new NewLintResultCache(cacheFileLocation);
145
146 newLintResultCache.getCachedLintResults(filePath, fakeConfig);
147 assert.ok(hashStub.calledOnce);
148 assert.ok(hashStub.calledWithMatch(version));
149 });
150 });
151
152 describe("When file is changed", () => {
153 beforeEach(() => {
154 hashStub.returns(hashOfConfig);
155 cacheEntry.changed = true;
156 });
157
158 it("should return null", () => {
159 const result = lintResultsCache.getCachedLintResults(filePath, fakeConfig);
160
161 assert.ok(getFileDescriptorStub.calledOnce);
162 assert.isNull(result);
163 });
164 });
165
166 describe("When config hash is changed", () => {
167 beforeEach(() => {
168 hashStub.returns("differentHash");
169 });
170
171 it("should return null", () => {
172 const result = lintResultsCache.getCachedLintResults(filePath, fakeConfig);
173
174 assert.ok(getFileDescriptorStub.calledOnce);
175 assert.isNull(result);
176 });
177 });
178
179 describe("When file is not found on filesystem", () => {
180 beforeEach(() => {
181 cacheEntry.notFound = true;
182 hashStub.returns(hashOfConfig);
183 });
184
185 it("should return null", () => {
186 const result = lintResultsCache.getCachedLintResults(filePath, fakeConfig);
187
188 assert.ok(getFileDescriptorStub.calledOnce);
189 assert.isNull(result);
190 });
191 });
192
193 describe("When file is present and unchanged and config is unchanged", () => {
194 beforeEach(() => {
195 hashStub.returns(hashOfConfig);
196 });
197
198 it("should return expected results", () => {
199 const result = lintResultsCache.getCachedLintResults(filePath, fakeConfig);
200
201 assert.deepStrictEqual(result, fakeErrorResults);
202 assert.ok(result.source, "source property should be hydrated from filesystem");
203 });
204 });
205 });
206
207 describe("setCachedLintResults", () => {
208 const filePath = path.join(fixturePath, "test-with-errors.js");
209 const hashOfConfig = "hashOfConfig";
210
211 let cacheEntry,
212 getFileDescriptorStub,
213 lintResultsCache;
214
215 before(() => {
216 getFileDescriptorStub = sinon.stub();
217
218 fileEntryCacheStubs.create = () => ({
219 getFileDescriptor: getFileDescriptorStub
220 });
221 });
222
223 after(() => {
224 delete fileEntryCacheStubs.create;
225 });
226
227 beforeEach(() => {
228 cacheEntry = {
229 meta: {}
230 };
231
232 getFileDescriptorStub.withArgs(filePath)
233 .returns(cacheEntry);
234
235 fakeConfig = {};
236
237 hashStub.returns(hashOfConfig);
238
239 lintResultsCache = new LintResultCache(cacheFileLocation);
240 });
241
242 describe("When lint result has output property", () => {
243 it("does not modify file entry", () => {
244 lintResultsCache.setCachedLintResults(filePath, fakeConfig, fakeErrorResultsAutofix);
245
246 assert.notProperty(cacheEntry.meta, "results");
247 assert.notProperty(cacheEntry.meta, "hashOfConfig");
248 });
249 });
250
251 describe("When file is not found on filesystem", () => {
252 beforeEach(() => {
253 cacheEntry.notFound = true;
254 });
255
256 it("does not modify file entry", () => {
257 lintResultsCache.setCachedLintResults(filePath, fakeConfig, fakeErrorResults);
258
259 assert.notProperty(cacheEntry.meta, "results");
260 assert.notProperty(cacheEntry.meta, "hashOfConfig");
261 });
262 });
263
264 describe("When file is found on filesystem", () => {
265 beforeEach(() => {
266 lintResultsCache.setCachedLintResults(filePath, fakeConfig, fakeErrorResults);
267 });
268
269 it("stores hash of config in file entry", () => {
270 assert.strictEqual(cacheEntry.meta.hashOfConfig, hashOfConfig);
271 });
272
273 it("stores results (except source) in file entry", () => {
274 const expectedCachedResults = Object.assign(
275 {},
276 fakeErrorResults,
277 { source: null }
278 );
279
280 assert.deepStrictEqual(cacheEntry.meta.results, expectedCachedResults);
281 });
282 });
283
284 describe("When file is found and empty", () => {
285 beforeEach(() => {
286 lintResultsCache.setCachedLintResults(
287 filePath,
288 fakeConfig,
289 Object.assign({}, fakeErrorResults, { source: "" })
290 );
291 });
292
293 it("stores hash of config in file entry", () => {
294 assert.strictEqual(cacheEntry.meta.hashOfConfig, hashOfConfig);
295 });
296
297 it("stores results (except source) in file entry", () => {
298 const expectedCachedResults = Object.assign(
299 {},
300 fakeErrorResults,
301 { source: null }
302 );
303
304 assert.deepStrictEqual(cacheEntry.meta.results, expectedCachedResults);
305 });
306 });
307 });
308
309 describe("reconcile", () => {
310 let reconcileStub,
311 lintResultsCache;
312
313 before(() => {
314 reconcileStub = sinon.stub();
315
316 fileEntryCacheStubs.create = () => ({
317 reconcile: reconcileStub
318 });
319 });
320
321 after(() => {
322 delete fileEntryCacheStubs.create;
323 });
324
325 beforeEach(() => {
326 lintResultsCache = new LintResultCache(cacheFileLocation);
327 });
328
329 it("calls reconcile on the underlying cache", () => {
330 lintResultsCache.reconcile();
331
332 assert.isTrue(reconcileStub.calledOnce);
333 });
334 });
335 });