1515// specific language governing permissions and limitations
1616// under the License.
1717
18- package deps_test
18+ package deps
1919
2020import (
2121 "bufio"
2222 "embed"
23+ "io"
2324 "io/fs"
25+ "net/http"
2426 "os"
2527 "path/filepath"
2628 "strings"
2729 "testing"
28-
29- "github.com/apache/skywalking-eyes/pkg/deps"
3030)
3131
3232func writeFileRuby (fileName , content string ) error {
@@ -73,7 +73,7 @@ func copyRuby(assetDir, destination string) error {
7373}
7474
7575func TestRubyGemfileLockResolver (t * testing.T ) {
76- resolver := new (deps. GemfileLockResolver )
76+ resolver := new (GemfileLockResolver )
7777
7878 // App case: include all specs (3)
7979 {
@@ -85,12 +85,12 @@ func TestRubyGemfileLockResolver(t *testing.T) {
8585 if ! resolver .CanResolve (lock ) {
8686 t .Fatalf ("GemfileLockResolver cannot resolve %s" , lock )
8787 }
88- cfg := & deps. ConfigDeps {Files : []string {lock }, Licenses : []* deps. ConfigDepLicense {
88+ cfg := & ConfigDeps {Files : []string {lock }, Licenses : []* ConfigDepLicense {
8989 {Name : "rake" , Version : "13.0.6" , License : "MIT" },
9090 {Name : "rspec" , Version : "3.10.0" , License : "MIT" },
9191 {Name : "rspec-core" , Version : "3.10.1" , License : "MIT" },
9292 }}
93- report := deps. Report {}
93+ report := Report {}
9494 if err := resolver .Resolve (lock , cfg , & report ); err != nil {
9595 t .Fatal (err )
9696 }
@@ -106,10 +106,10 @@ func TestRubyGemfileLockResolver(t *testing.T) {
106106 t .Fatal (err )
107107 }
108108 lock := filepath .Join (tmp , "Gemfile.lock" )
109- cfg := & deps. ConfigDeps {Files : []string {lock }, Licenses : []* deps. ConfigDepLicense {
109+ cfg := & ConfigDeps {Files : []string {lock }, Licenses : []* ConfigDepLicense {
110110 {Name : "rake" , Version : "13.0.6" , License : "MIT" },
111111 }}
112- report := deps. Report {}
112+ report := Report {}
113113 if err := resolver .Resolve (lock , cfg , & report ); err != nil {
114114 t .Fatal (err )
115115 }
@@ -118,3 +118,72 @@ func TestRubyGemfileLockResolver(t *testing.T) {
118118 }
119119 }
120120}
121+
122+ // mock RoundTripper to control HTTP responses
123+ type roundTripFunc func (* http.Request ) (* http.Response , error )
124+
125+ func (f roundTripFunc ) RoundTrip (req * http.Request ) (* http.Response , error ) { return f (req ) }
126+
127+ func TestRubyMissingSpecIsSkippedGracefully (t * testing.T ) {
128+ // Mock HTTP client to avoid real network: always return 404 Not Found
129+ saved := httpClientRuby
130+ httpClientRuby = & http.Client {Transport : roundTripFunc (func (r * http.Request ) (* http.Response , error ) {
131+ return & http.Response {
132+ StatusCode : http .StatusNotFound ,
133+ Status : "404 Not Found" ,
134+ Body : io .NopCloser (strings .NewReader ("{}" )),
135+ Header : make (http.Header ),
136+ }, nil
137+ })}
138+ defer func () { httpClientRuby = saved }()
139+
140+ // Create a Gemfile.lock where a dependency is not present in specs
141+ content := "" +
142+ "GEM\n " +
143+ " remote: https://rubygems.org/\n " +
144+ " specs:\n " +
145+ " rake (13.0.6)\n " +
146+ "\n " +
147+ "PLATFORMS\n " +
148+ " ruby\n " +
149+ "\n " +
150+ "DEPENDENCIES\n " +
151+ " rake\n " +
152+ " missing_gem\n " +
153+ "\n " +
154+ "BUNDLED WITH\n " +
155+ " 2.4.10\n "
156+
157+ dir := t .TempDir ()
158+ lock := filepath .Join (dir , "Gemfile.lock" )
159+ if err := writeFileRuby (lock , content ); err != nil {
160+ t .Fatal (err )
161+ }
162+
163+ resolver := new (GemfileLockResolver )
164+ cfg := & ConfigDeps {Files : []string {lock }, Licenses : []* ConfigDepLicense {
165+ {Name : "rake" , Version : "13.0.6" , License : "MIT" }, // only rake is configured; missing_gem should be skipped
166+ }}
167+ report := Report {}
168+ if err := resolver .Resolve (lock , cfg , & report ); err != nil {
169+ t .Fatal (err )
170+ }
171+
172+ if got := len (report .Resolved ) + len (report .Skipped ); got != 2 {
173+ t .Fatalf ("expected 2 dependencies total, got %d" , got )
174+ }
175+
176+ // Ensure 'missing_gem' is in skipped with empty version
177+ found := false
178+ for _ , s := range report .Skipped {
179+ if s .Dependency == "missing_gem" {
180+ found = true
181+ if s .Version != "" {
182+ t .Fatalf ("expected empty version for missing_gem, got %q" , s .Version )
183+ }
184+ }
185+ }
186+ if ! found {
187+ t .Fatalf ("expected missing_gem to be marked as skipped" )
188+ }
189+ }
0 commit comments