1
1
import { logger } from "@coder/logger"
2
- import { readFile , writeFile , stat } from "fs/promises"
2
+ import { readFile , writeFile , stat , utimes } from "fs/promises"
3
3
import { Heart , heartbeatTimer } from "../../../src/node/heart"
4
4
import { clean , mockLogger , tmpdir } from "../../utils/helpers"
5
5
@@ -33,17 +33,26 @@ describe("Heart", () => {
33
33
const pathToFile = `${ testDir } /file.txt`
34
34
await writeFile ( pathToFile , text )
35
35
const fileContents = await readFile ( pathToFile , { encoding : "utf8" } )
36
- const fileStatusBeforeEdit = await stat ( pathToFile )
36
+ // Explicitly set the modified time to 0 so that we can check
37
+ // that the file was indeed modified after calling heart.beat().
38
+ // This works around any potential race conditions.
39
+ // Docs: https://nodejs.org/api/fs.html#fspromisesutimespath-atime-mtime
40
+ await utimes ( pathToFile , 0 , 0 )
41
+
37
42
expect ( fileContents ) . toBe ( text )
38
43
39
44
heart = new Heart ( pathToFile , mockIsActive ( true ) )
40
45
heart . beat ( )
46
+ // HACK@jsjoeio - beat has some async logic but is not an async method
47
+ // Therefore, we have to create an artificial wait in order to make sure
48
+ // all async code has completed before asserting
49
+ await new Promise ( ( r ) => setTimeout ( r , 100 ) )
41
50
// Check that the heart wrote to the heartbeatFilePath and overwrote our text
42
51
const fileContentsAfterBeat = await readFile ( pathToFile , { encoding : "utf8" } )
43
52
expect ( fileContentsAfterBeat ) . not . toBe ( text )
44
53
// Make sure the modified timestamp was updated.
45
54
const fileStatusAfterEdit = await stat ( pathToFile )
46
- expect ( fileStatusAfterEdit . mtimeMs ) . toBeGreaterThan ( fileStatusBeforeEdit . mtimeMs )
55
+ expect ( fileStatusAfterEdit . mtimeMs ) . toBeGreaterThan ( 0 )
47
56
} )
48
57
it ( "should log a warning when given an invalid file path" , async ( ) => {
49
58
heart = new Heart ( `fakeDir/fake.txt` , mockIsActive ( false ) )
@@ -52,7 +61,6 @@ describe("Heart", () => {
52
61
// Therefore, we have to create an artificial wait in order to make sure
53
62
// all async code has completed before asserting
54
63
await new Promise ( ( r ) => setTimeout ( r , 100 ) )
55
- // expect(logger.trace).toHaveBeenCalled()
56
64
expect ( logger . warn ) . toHaveBeenCalled ( )
57
65
} )
58
66
it ( "should be active after calling beat" , ( ) => {
0 commit comments