11import { execSync } from "child_process" ;
22import { getDeps , getVersionType } from "../src/deps" ;
3- import { describe , expect , it , vi , MockedObject } from "vitest" ;
3+ import { describe , expect , it , vi , MockedObject , beforeEach } from "vitest" ;
44import * as glob from "@actions/glob" ;
55
66// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -23,13 +23,24 @@ vi.mock("@actions/core", async (importOriginal: any) => ({
2323 } ,
2424} ) ) ;
2525
26+ vi . mock ( "node:child_process" , ( ) => ( { execSync : vi . fn ( ) } ) ) ;
27+ vi . mock ( "@actions/glob" , ( ) => ( { create : vi . fn ( ) } ) ) ;
28+
2629const mockedExecSync = vi . mocked ( execSync ) ;
27- vi . mock ( "child_process" ) ;
28- const mockedGlob = vi . mocked ( glob ) ;
29- vi . mock ( "@actions/glob" ) ;
30+ const mockedCreate = vi . mocked ( glob . create ) ;
31+
32+ let getDeps : typeof import ( "../src/deps" ) . getDeps ;
3033type MockedGlob = MockedObject < Awaited < ReturnType < typeof glob . create > > > ;
3134
3235describe ( "getDependenciesMap" , ( ) => {
36+ beforeEach ( async ( ) => {
37+ vi . resetModules ( ) ; // <- key: clears module-level caching
38+ vi . clearAllMocks ( ) ;
39+
40+ // re-import AFTER resetModules so module-level singletons re-run
41+ ( { getDeps } = await import ( "../src/deps" ) ) ;
42+ } ) ;
43+
3344 it ( "should return a map of <go.mod files: dependencies in json>" , async ( ) => {
3445 const paths = [ "/path/to/first/go.mod" , "/path/to/second/go.mod" ] ;
3546 const goList1 =
@@ -39,14 +50,17 @@ describe("getDependenciesMap", () => {
3950 const goList3 =
4051 '{"Path": "github.com/smartcontractkit/chainlink-protos/cre/go", "Version": "v1.0.0-beta"}' ;
4152
42- mockedGlob . create . mockResolvedValueOnce ( {
53+ mockedCreate . mockResolvedValueOnce ( {
4354 glob : vi . fn ( ) . mockResolvedValue ( paths ) ,
4455 } as MockedGlob ) ;
4556
4657 mockedExecSync . mockImplementationOnce ( ( ) => goList1 ) ;
4758 mockedExecSync . mockImplementationOnce ( ( ) => goList2 + "\n" + goList3 ) ;
4859
4960 const result = await getDeps ( "" , "github.com/smartcontractkit" ) ;
61+
62+ expect ( mockedExecSync ) . toHaveBeenCalledTimes ( 2 ) ;
63+
5064 expect ( result ) . toMatchInlineSnapshot ( `
5165 [
5266 {
@@ -80,18 +94,56 @@ describe("getDependenciesMap", () => {
8094 ` ) ;
8195 } ) ;
8296
97+ it ( "should skip dependencies with errors" , async ( ) => {
98+ const paths = [ "/path/to/first/go.mod" ] ;
99+ const goList1 =
100+ '{"Path": "github.com/smartcontractkit/go-plugin", "Version": "v0.0.0-20240208201424-b3b91517de16"}' ;
101+ const goList2 = `
102+ {
103+ "Path": "github.com/smartcontractkit/private-dep",
104+ "Version": "v0.0.0-20260224170222-a43bd3ff9dd5",
105+ "Error": {
106+ "Err": "github.com/smartcontractkit/private-dep@v0.0.0-20260224170222-a43bd3ff9dd5: invalid version: git ls-remote -q --end-of-options https://github.com/smartcontractkit/private-dep in /go/pkg/mod/cache/vcs/94d9727765b1ab36ed05d10c5d35ca726794e132cb25bee11cb34a7d6107b004: exit status 128:\\n\\tfatal: could not read Username for 'https://github.com': terminal prompts disabled\\nConfirm the import path was entered correctly.\\nIf this is a private repository, see https://golang.org/doc/faq#git_https for additional information."
107+ }
108+ }` ;
109+
110+ mockedCreate . mockResolvedValueOnce ( {
111+ glob : vi . fn ( ) . mockResolvedValue ( paths ) ,
112+ } as MockedGlob ) ;
113+
114+ mockedExecSync . mockImplementationOnce ( ( ) => goList1 + "\n" + goList2 ) ;
115+
116+ const result = await getDeps ( "" , "github.com/smartcontractkit" ) ;
117+
118+ expect ( mockedExecSync ) . toHaveBeenCalledTimes ( 1 ) ;
119+
120+ expect ( result ) . toMatchInlineSnapshot ( `
121+ [
122+ {
123+ "commitSha": "b3b91517de16",
124+ "goModFilePath": "/path/to/first/go.mod",
125+ "name": "github.com/smartcontractkit/go-plugin@v0.0.0-20240208201424-b3b91517de16",
126+ "owner": "smartcontractkit",
127+ "path": "github.com/smartcontractkit/go-plugin",
128+ "repo": "go-plugin",
129+ "version": "v0.0.0-20240208201424-b3b91517de16",
130+ },
131+ ]
132+ ` ) ;
133+ } ) ;
134+
83135 it ( "should handle no go.mod files found" , async ( ) => {
84136 const paths : string [ ] = [ ] ;
85137
86- mockedGlob . create . mockResolvedValue ( {
138+ mockedCreate . mockResolvedValue ( {
87139 glob : vi . fn ( ) . mockResolvedValue ( paths ) ,
88140 } as MockedGlob ) ;
89141
90142 await expect ( getDeps ( "" , "" ) ) . rejects . toThrow ( "no go.mod files found" ) ;
91143 } ) ;
92144
93145 it ( "should handle glob search failure" , async ( ) => {
94- mockedGlob . create . mockRejectedValue ( new Error ( "Glob error" ) ) ;
146+ mockedCreate . mockRejectedValue ( new Error ( "Glob error" ) ) ;
95147 await expect ( getDeps ( "" , "" ) ) . rejects . toThrow ( "Glob error" ) ;
96148 } ) ;
97149} ) ;
0 commit comments