github.com/joey-fossa/fossa-cli@v0.7.34-0.20190708193710-569f1e8679f0/buildtools/stack/stack_test.go (about) 1 package stack_test 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 9 "github.com/fossas/fossa-cli/buildtools/stack" 10 "github.com/fossas/fossa-cli/pkg" 11 ) 12 13 func TestDepFromCanonical(t *testing.T) { 14 t.Run("it should form an isomorphism with DepToCanonical", func(t *testing.T) { 15 dep := stack.Dep{Name: "package-one", Version: "0.0.1.0"} 16 assert.Equal(t, stack.DepFromCanonical(stack.DepToCanonical(dep)), dep) 17 }) 18 } 19 20 func TestDepToCanonical(t *testing.T) { 21 t.Run("it should form an isomorphism with DepFromCanonical", func(t *testing.T) { 22 dep := stack.Canonical{Identifier: "package-one-0.0.1.0"} 23 assert.Equal(t, stack.DepToCanonical(stack.DepFromCanonical(dep)), dep) 24 }) 25 } 26 27 func TestDepToPkgId(t *testing.T) { 28 dep := stack.Dep{Name: "package-one", Version: "0.0.1.0"} 29 result := stack.DepToPkgId(dep) 30 31 assert.Equal(t, result.Name, dep.Name) 32 assert.Equal(t, result.Revision, dep.Version) 33 assert.Equal(t, result.Type, pkg.Haskell) 34 } 35 36 func TestParseStackDependencies(t *testing.T) { 37 packageOne := stack.Dep{Name: "package-one", Version: "0.0.1.0"} 38 packageTwo := stack.Dep{Name: "package-two", Version: "0.0.1.0"} 39 const packageOneRaw = "package-one 0.0.1.0" 40 const packageTwoRaw = "package-two 0.0.1.0" 41 42 joinLines := func(deps ...string) string { 43 return strings.Join(deps, "\n") 44 } 45 46 t.Run("it should parse a single package", func(t *testing.T) { 47 deps := stack.ParseStackDependencies(packageOneRaw) 48 assert.ElementsMatch(t, []stack.Dep{packageOne}, deps) 49 }) 50 t.Run("it should parse many packages", func(t *testing.T) { 51 deps := stack.ParseStackDependencies(joinLines(packageOneRaw, packageTwoRaw)) 52 assert.Equal(t, []stack.Dep{packageOne, packageTwo}, deps) 53 }) 54 t.Run("it should ignore empty or invalid lines", func(t *testing.T) { 55 deps := stack.ParseStackDependencies("notvalid\n\n") 56 assert.Len(t, deps, 0) 57 }) 58 } 59 60 func TestParseGhcPkgDepMap(t *testing.T) { 61 packageOne := stack.Canonical{Identifier: "package-one-0.0.1.0"} 62 packageTwo := stack.Canonical{Identifier: "package-two-0.0.1.0"} 63 packageThree := stack.Canonical{Identifier: "package-three-0.0.1.0"} 64 packageFour := stack.Canonical{Identifier: "package-four-0.0.1.0"} 65 const ( 66 packageOneRaw = "\"package-one-0.0.1.0\"" 67 packageTwoRaw = "\"package-two-0.0.1.0\"" 68 packageThreeRaw = "\"package-three-0.0.1.0\"" 69 packageFourRaw = "\"package-four-0.0.1.0\"" 70 ) 71 72 createDep := func(from string, to string) string { 73 return from + " -> " + to 74 } 75 76 joinLines := func(deps ...string) string { 77 return strings.Join(deps, "\n") 78 } 79 80 t.Run("it should parse a single dependency", func(t *testing.T) { 81 deps := stack.ParseGhcPkgDepMap(createDep(packageOneRaw, packageTwoRaw)) 82 assert.Equal(t, deps, map[stack.Canonical][]stack.Canonical{ 83 packageOne: {packageTwo}, 84 }) 85 }) 86 t.Run("it should parse many dependencies", func(t *testing.T) { 87 deps := stack.ParseGhcPkgDepMap(joinLines(createDep(packageOneRaw, packageTwoRaw), createDep(packageThreeRaw, packageFourRaw))) 88 assert.Equal(t, deps, map[stack.Canonical][]stack.Canonical{ 89 packageOne: {packageTwo}, 90 packageThree: {packageFour}, 91 }) 92 }) 93 t.Run("it should combine dependencies", func(t *testing.T) { 94 deps := stack.ParseGhcPkgDepMap(joinLines(createDep(packageOneRaw, packageTwoRaw), createDep(packageOneRaw, packageThreeRaw))) 95 assert.Equal(t, deps, map[stack.Canonical][]stack.Canonical{ 96 packageOne: {packageTwo, packageThree}, 97 }) 98 }) 99 t.Run("it should ignore empty or invalid lines", func(t *testing.T) { 100 deps := stack.ParseGhcPkgDepMap("notvalid\n\n") 101 assert.Len(t, deps, 0) 102 }) 103 } 104 105 func TestAnalyzeStackPure(t *testing.T) { 106 stackImmediateDeps := []stack.Dep{ 107 { 108 Name: "package-three", 109 Version: "0.0.1.0", 110 }, 111 { 112 Name: "package-four", 113 Version: "0.0.1.0", 114 }, 115 } 116 117 stackAllDeps := append(stackImmediateDeps, 118 stack.Dep{ 119 Name: "package-one", 120 Version: "0.0.1.0", 121 }, 122 stack.Dep{ 123 Name: "package-two", 124 Version: "0.0.1.0", 125 }, 126 ) 127 128 depMap := map[stack.Canonical][]stack.Canonical{ 129 {Identifier: "package-one-0.0.1.0"}: { 130 {Identifier: "package-two-0.0.1.0"}, 131 }, 132 {Identifier: "package-two-0.0.1.0"}: { 133 {Identifier: "package-three-0.0.1.0"}, 134 {Identifier: "package-four-0.0.1.0"}, 135 }, 136 {Identifier: "package-three-0.0.1.0"}: { 137 {Identifier: "package-four-0.0.1.0"}, 138 }, 139 } 140 141 // Shared model example -- when modifying this, also modify in cabal_test.go 142 deps := stack.GetDepsPure(stackAllDeps, stackImmediateDeps, depMap) 143 144 packageOne := pkg.ID{ 145 Type: pkg.Haskell, 146 Name: "package-one", 147 Revision: "0.0.1.0", 148 } 149 packageTwo := pkg.ID{ 150 Type: pkg.Haskell, 151 Name: "package-two", 152 Revision: "0.0.1.0", 153 } 154 packageThree := pkg.ID{ 155 Type: pkg.Haskell, 156 Name: "package-three", 157 Revision: "0.0.1.0", 158 } 159 packageFour := pkg.ID{ 160 Type: pkg.Haskell, 161 Name: "package-four", 162 Revision: "0.0.1.0", 163 } 164 165 assert.Len(t, deps.Direct, 2) 166 assert.Contains(t, deps.Direct, pkg.Import{Resolved: packageThree}) 167 assert.Contains(t, deps.Direct, pkg.Import{Resolved: packageFour}) 168 169 assert.Len(t, deps.Transitive, 4) 170 171 assert.Contains(t, deps.Transitive, packageOne) 172 assert.Len(t, deps.Transitive[packageOne].Imports, 1) 173 assert.Contains(t, deps.Transitive[packageOne].Imports, pkg.Import{Resolved: packageTwo}) 174 175 assert.Contains(t, deps.Transitive, packageTwo) 176 assert.Len(t, deps.Transitive[packageTwo].Imports, 2) 177 assert.Contains(t, deps.Transitive[packageTwo].Imports, pkg.Import{Resolved: packageThree}) 178 assert.Contains(t, deps.Transitive[packageTwo].Imports, pkg.Import{Resolved: packageFour}) 179 180 assert.Contains(t, deps.Transitive, packageThree) 181 assert.Len(t, deps.Transitive[packageThree].Imports, 1) 182 assert.Contains(t, deps.Transitive[packageThree].Imports, pkg.Import{Resolved: packageFour}) 183 184 assert.Contains(t, deps.Transitive, packageFour) 185 assert.Len(t, deps.Transitive[packageFour].Imports, 0) 186 }