Home | History | Annotate | Download | only in blueprint
      1 // Copyright 2015 Google Inc. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 package blueprint
     16 
     17 import (
     18 	"reflect"
     19 	"testing"
     20 )
     21 
     22 var (
     23 	testModuleA = &moduleInfo{variantName: "testModuleA"}
     24 	testModuleB = &moduleInfo{variantName: "testModuleB"}
     25 	testModuleC = &moduleInfo{variantName: "testModuleC"}
     26 	testModuleD = &moduleInfo{variantName: "testModuleD"}
     27 	testModuleE = &moduleInfo{variantName: "testModuleE"}
     28 	testModuleF = &moduleInfo{variantName: "testModuleF"}
     29 )
     30 
     31 var spliceModulesTestCases = []struct {
     32 	in         []*moduleInfo
     33 	at         int
     34 	with       []*moduleInfo
     35 	out        []*moduleInfo
     36 	outAt      int
     37 	reallocate bool
     38 }{
     39 	{
     40 		// Insert at the beginning
     41 		in:         []*moduleInfo{testModuleA, testModuleB, testModuleC},
     42 		at:         0,
     43 		with:       []*moduleInfo{testModuleD, testModuleE},
     44 		out:        []*moduleInfo{testModuleD, testModuleE, testModuleB, testModuleC},
     45 		outAt:      1,
     46 		reallocate: true,
     47 	},
     48 	{
     49 		// Insert in the middle
     50 		in:         []*moduleInfo{testModuleA, testModuleB, testModuleC},
     51 		at:         1,
     52 		with:       []*moduleInfo{testModuleD, testModuleE},
     53 		out:        []*moduleInfo{testModuleA, testModuleD, testModuleE, testModuleC},
     54 		outAt:      2,
     55 		reallocate: true,
     56 	},
     57 	{
     58 		// Insert at the end
     59 		in:         []*moduleInfo{testModuleA, testModuleB, testModuleC},
     60 		at:         2,
     61 		with:       []*moduleInfo{testModuleD, testModuleE},
     62 		out:        []*moduleInfo{testModuleA, testModuleB, testModuleD, testModuleE},
     63 		outAt:      3,
     64 		reallocate: true,
     65 	},
     66 	{
     67 		// Insert over a single element
     68 		in:         []*moduleInfo{testModuleA},
     69 		at:         0,
     70 		with:       []*moduleInfo{testModuleD, testModuleE},
     71 		out:        []*moduleInfo{testModuleD, testModuleE},
     72 		outAt:      1,
     73 		reallocate: true,
     74 	},
     75 	{
     76 		// Insert at the beginning without reallocating
     77 		in:         []*moduleInfo{testModuleA, testModuleB, testModuleC, nil}[0:3],
     78 		at:         0,
     79 		with:       []*moduleInfo{testModuleD, testModuleE},
     80 		out:        []*moduleInfo{testModuleD, testModuleE, testModuleB, testModuleC},
     81 		outAt:      1,
     82 		reallocate: false,
     83 	},
     84 	{
     85 		// Insert in the middle without reallocating
     86 		in:         []*moduleInfo{testModuleA, testModuleB, testModuleC, nil}[0:3],
     87 		at:         1,
     88 		with:       []*moduleInfo{testModuleD, testModuleE},
     89 		out:        []*moduleInfo{testModuleA, testModuleD, testModuleE, testModuleC},
     90 		outAt:      2,
     91 		reallocate: false,
     92 	},
     93 	{
     94 		// Insert at the end without reallocating
     95 		in:         []*moduleInfo{testModuleA, testModuleB, testModuleC, nil}[0:3],
     96 		at:         2,
     97 		with:       []*moduleInfo{testModuleD, testModuleE},
     98 		out:        []*moduleInfo{testModuleA, testModuleB, testModuleD, testModuleE},
     99 		outAt:      3,
    100 		reallocate: false,
    101 	},
    102 	{
    103 		// Insert over a single element without reallocating
    104 		in:         []*moduleInfo{testModuleA, nil}[0:1],
    105 		at:         0,
    106 		with:       []*moduleInfo{testModuleD, testModuleE},
    107 		out:        []*moduleInfo{testModuleD, testModuleE},
    108 		outAt:      1,
    109 		reallocate: false,
    110 	},
    111 }
    112 
    113 func TestSpliceModules(t *testing.T) {
    114 	for _, testCase := range spliceModulesTestCases {
    115 		in := make([]*moduleInfo, len(testCase.in), cap(testCase.in))
    116 		copy(in, testCase.in)
    117 		origIn := in
    118 		got, gotAt := spliceModules(in, testCase.at, testCase.with)
    119 		if !reflect.DeepEqual(got, testCase.out) {
    120 			t.Errorf("test case: %v, %v -> %v", testCase.in, testCase.at, testCase.with)
    121 			t.Errorf("incorrect output:")
    122 			t.Errorf("  expected: %v", testCase.out)
    123 			t.Errorf("       got: %v", got)
    124 		}
    125 		if gotAt != testCase.outAt {
    126 			t.Errorf("test case: %v, %v -> %v", testCase.in, testCase.at, testCase.with)
    127 			t.Errorf("incorrect index:")
    128 			t.Errorf("  expected: %d", testCase.outAt)
    129 			t.Errorf("       got: %d", gotAt)
    130 		}
    131 		if sameArray(origIn, got) != !testCase.reallocate {
    132 			t.Errorf("test case: %v, %v -> %v", testCase.in, testCase.at, testCase.with)
    133 			not := ""
    134 			if !testCase.reallocate {
    135 				not = " not"
    136 			}
    137 			t.Errorf("  expected to%s reallocate", not)
    138 		}
    139 	}
    140 }
    141 
    142 func sameArray(a, b []*moduleInfo) bool {
    143 	return &a[0:cap(a)][cap(a)-1] == &b[0:cap(b)][cap(b)-1]
    144 }
    145