github.com/golang/dep@v0.5.4/gps/rootdata_test.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gps
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/golang/dep/gps/pkgtree"
    12  )
    13  
    14  func TestRootdataExternalImports(t *testing.T) {
    15  	fix := basicFixtures["shared dependency with overlapping constraints"]
    16  
    17  	params := SolveParameters{
    18  		RootDir:         string(fix.ds[0].n),
    19  		RootPackageTree: fix.rootTree(),
    20  		Manifest:        fix.rootmanifest(),
    21  		ProjectAnalyzer: naiveAnalyzer{},
    22  		stdLibFn:        func(string) bool { return false },
    23  		mkBridgeFn:      overrideMkBridge,
    24  	}
    25  
    26  	is, err := Prepare(params, newdepspecSM(fix.ds, nil))
    27  	if err != nil {
    28  		t.Fatalf("Unexpected error while prepping solver: %s", err)
    29  	}
    30  	rd := is.(*solver).rd
    31  
    32  	want := []string{"a", "b"}
    33  	got := rd.externalImportList(params.stdLibFn)
    34  	if !reflect.DeepEqual(want, got) {
    35  		t.Errorf("Unexpected return from rootdata.externalImportList:\n\t(GOT): %s\n\t(WNT): %s", got, want)
    36  	}
    37  
    38  	// Add a require
    39  	rd.req["c"] = true
    40  
    41  	want = []string{"a", "b", "c"}
    42  	got = rd.externalImportList(params.stdLibFn)
    43  	if !reflect.DeepEqual(want, got) {
    44  		t.Errorf("Unexpected return from rootdata.externalImportList:\n\t(GOT): %s\n\t(WNT): %s", got, want)
    45  	}
    46  
    47  	// Add same path as import
    48  	poe := rd.rpt.Packages["root"]
    49  	poe.P.Imports = []string{"a", "b", "c"}
    50  	rd.rpt.Packages["root"] = poe
    51  
    52  	// should still be the same
    53  	got = rd.externalImportList(params.stdLibFn)
    54  	if !reflect.DeepEqual(want, got) {
    55  		t.Errorf("Unexpected return from rootdata.externalImportList:\n\t(GOT): %s\n\t(WNT): %s", got, want)
    56  	}
    57  
    58  	// Add an ignore, but not on the required path (Prepare makes that
    59  	// combination impossible)
    60  
    61  	rd.ir = pkgtree.NewIgnoredRuleset([]string{"b"})
    62  	want = []string{"a", "c"}
    63  	got = rd.externalImportList(params.stdLibFn)
    64  	if !reflect.DeepEqual(want, got) {
    65  		t.Errorf("Unexpected return from rootdata.externalImportList:\n\t(GOT): %s\n\t(WNT): %s", got, want)
    66  	}
    67  }
    68  
    69  func TestGetApplicableConstraints(t *testing.T) {
    70  	fix := basicFixtures["shared dependency with overlapping constraints"]
    71  
    72  	params := SolveParameters{
    73  		RootDir:         string(fix.ds[0].n),
    74  		RootPackageTree: fix.rootTree(),
    75  		Manifest:        fix.rootmanifest(),
    76  		ProjectAnalyzer: naiveAnalyzer{},
    77  		stdLibFn:        func(string) bool { return false },
    78  		mkBridgeFn:      overrideMkBridge,
    79  	}
    80  
    81  	is, err := Prepare(params, newdepspecSM(fix.ds, nil))
    82  	if err != nil {
    83  		t.Fatalf("Unexpected error while prepping solver: %s", err)
    84  	}
    85  	rd := is.(*solver).rd
    86  
    87  	table := []struct {
    88  		name   string
    89  		mut    func()
    90  		result []workingConstraint
    91  	}{
    92  		{
    93  			name: "base case, two constraints",
    94  			mut:  func() {},
    95  			result: []workingConstraint{
    96  				{
    97  					Ident:      mkPI("a"),
    98  					Constraint: mkSVC("1.0.0"),
    99  				},
   100  				{
   101  					Ident:      mkPI("b"),
   102  					Constraint: mkSVC("1.0.0"),
   103  				},
   104  			},
   105  		},
   106  		{
   107  			name: "with unconstrained require",
   108  			mut: func() {
   109  				// No constraint means it doesn't show up
   110  				rd.req["c"] = true
   111  			},
   112  			result: []workingConstraint{
   113  				{
   114  					Ident:      mkPI("a"),
   115  					Constraint: mkSVC("1.0.0"),
   116  				},
   117  				{
   118  					Ident:      mkPI("b"),
   119  					Constraint: mkSVC("1.0.0"),
   120  				},
   121  			},
   122  		},
   123  		{
   124  			name: "with unconstrained import",
   125  			mut: func() {
   126  				// Again, no constraint means it doesn't show up
   127  				poe := rd.rpt.Packages["root"]
   128  				poe.P.Imports = []string{"a", "b", "d"}
   129  				rd.rpt.Packages["root"] = poe
   130  			},
   131  			result: []workingConstraint{
   132  				{
   133  					Ident:      mkPI("a"),
   134  					Constraint: mkSVC("1.0.0"),
   135  				},
   136  				{
   137  					Ident:      mkPI("b"),
   138  					Constraint: mkSVC("1.0.0"),
   139  				},
   140  			},
   141  		},
   142  		{
   143  			name: "constraint on required",
   144  			mut: func() {
   145  				rd.rm.Deps["c"] = ProjectProperties{
   146  					Constraint: NewBranch("foo"),
   147  				}
   148  			},
   149  			result: []workingConstraint{
   150  				{
   151  					Ident:      mkPI("a"),
   152  					Constraint: mkSVC("1.0.0"),
   153  				},
   154  				{
   155  					Ident:      mkPI("b"),
   156  					Constraint: mkSVC("1.0.0"),
   157  				},
   158  				{
   159  					Ident:      mkPI("c"),
   160  					Constraint: NewBranch("foo"),
   161  				},
   162  			},
   163  		},
   164  		{
   165  			name: "override on imported",
   166  			mut: func() {
   167  				rd.ovr["d"] = ProjectProperties{
   168  					Constraint: NewBranch("bar"),
   169  				}
   170  			},
   171  			result: []workingConstraint{
   172  				{
   173  					Ident:      mkPI("a"),
   174  					Constraint: mkSVC("1.0.0"),
   175  				},
   176  				{
   177  					Ident:      mkPI("b"),
   178  					Constraint: mkSVC("1.0.0"),
   179  				},
   180  				{
   181  					Ident:      mkPI("c"),
   182  					Constraint: NewBranch("foo"),
   183  				},
   184  				{
   185  					Ident:           mkPI("d"),
   186  					Constraint:      NewBranch("bar"),
   187  					overrConstraint: true,
   188  				},
   189  			},
   190  		},
   191  		{
   192  			// It is certainly the simplest and most rule-abiding solution to
   193  			// drop the constraint in this case, but is there a chance it would
   194  			// violate the principle of least surprise?
   195  			name: "ignore imported and overridden pkg",
   196  			mut: func() {
   197  				rd.ir = pkgtree.NewIgnoredRuleset([]string{"d"})
   198  			},
   199  			result: []workingConstraint{
   200  				{
   201  					Ident:      mkPI("a"),
   202  					Constraint: mkSVC("1.0.0"),
   203  				},
   204  				{
   205  					Ident:      mkPI("b"),
   206  					Constraint: mkSVC("1.0.0"),
   207  				},
   208  				{
   209  					Ident:      mkPI("c"),
   210  					Constraint: NewBranch("foo"),
   211  				},
   212  			},
   213  		},
   214  	}
   215  
   216  	for _, fix := range table {
   217  		t.Run(fix.name, func(t *testing.T) {
   218  			fix.mut()
   219  
   220  			got := rd.getApplicableConstraints(params.stdLibFn)
   221  			if !reflect.DeepEqual(fix.result, got) {
   222  				t.Errorf("unexpected applicable constraint set:\n\t(GOT): %+v\n\t(WNT): %+v", got, fix.result)
   223  			}
   224  		})
   225  	}
   226  }