github.com/colincross/blueprint@v0.0.0-20150626231830-9c067caf2eb5/unpack_test.go (about)

     1  // Copyright 2014 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  	"bytes"
    19  	"fmt"
    20  	"reflect"
    21  	"testing"
    22  	"text/scanner"
    23  
    24  	"github.com/google/blueprint/parser"
    25  	"github.com/google/blueprint/proptools"
    26  )
    27  
    28  var validUnpackTestCases = []struct {
    29  	input  string
    30  	output interface{}
    31  	errs   []error
    32  }{
    33  	{`
    34  		m {
    35  			name: "abc",
    36  		}
    37  		`,
    38  		struct {
    39  			Name string
    40  		}{
    41  			Name: "abc",
    42  		},
    43  		nil,
    44  	},
    45  
    46  	{`
    47  		m {
    48  			isGood: true,
    49  		}
    50  		`,
    51  		struct {
    52  			IsGood bool
    53  		}{
    54  			IsGood: true,
    55  		},
    56  		nil,
    57  	},
    58  
    59  	{`
    60  		m {
    61  			stuff: ["asdf", "jkl;", "qwert",
    62  				"uiop", "bnm,"]
    63  		}
    64  		`,
    65  		struct {
    66  			Stuff []string
    67  		}{
    68  			Stuff: []string{"asdf", "jkl;", "qwert", "uiop", "bnm,"},
    69  		},
    70  		nil,
    71  	},
    72  
    73  	{`
    74  		m {
    75  			nested: {
    76  				name: "abc",
    77  			}
    78  		}
    79  		`,
    80  		struct {
    81  			Nested struct {
    82  				Name string
    83  			}
    84  		}{
    85  			Nested: struct{ Name string }{
    86  				Name: "abc",
    87  			},
    88  		},
    89  		nil,
    90  	},
    91  
    92  	{`
    93  		m {
    94  			nested: {
    95  				name: "def",
    96  			}
    97  		}
    98  		`,
    99  		struct {
   100  			Nested interface{}
   101  		}{
   102  			Nested: &struct{ Name string }{
   103  				Name: "def",
   104  			},
   105  		},
   106  		nil,
   107  	},
   108  
   109  	{`
   110  		m {
   111  			nested: {
   112  				foo: "abc",
   113  			},
   114  			bar: false,
   115  			baz: ["def", "ghi"],
   116  		}
   117  		`,
   118  		struct {
   119  			Nested struct {
   120  				Foo string
   121  			}
   122  			Bar bool
   123  			Baz []string
   124  		}{
   125  			Nested: struct{ Foo string }{
   126  				Foo: "abc",
   127  			},
   128  			Bar: false,
   129  			Baz: []string{"def", "ghi"},
   130  		},
   131  		nil,
   132  	},
   133  
   134  	{`
   135  		m {
   136  			nested: {
   137  				foo: "abc",
   138  			},
   139  			bar: false,
   140  			baz: ["def", "ghi"],
   141  		}
   142  		`,
   143  		struct {
   144  			Nested struct {
   145  				Foo string `allowNested:"true"`
   146  			} `blueprint:"filter(allowNested:\"true\")"`
   147  			Bar bool
   148  			Baz []string
   149  		}{
   150  			Nested: struct {
   151  				Foo string `allowNested:"true"`
   152  			}{
   153  				Foo: "abc",
   154  			},
   155  			Bar: false,
   156  			Baz: []string{"def", "ghi"},
   157  		},
   158  		nil,
   159  	},
   160  
   161  	{`
   162  		m {
   163  			nested: {
   164  				foo: "abc",
   165  			},
   166  			bar: false,
   167  			baz: ["def", "ghi"],
   168  		}
   169  		`,
   170  		struct {
   171  			Nested struct {
   172  				Foo string
   173  			} `blueprint:"filter(allowNested:\"true\")"`
   174  			Bar bool
   175  			Baz []string
   176  		}{
   177  			Nested: struct{ Foo string }{
   178  				Foo: "",
   179  			},
   180  			Bar: false,
   181  			Baz: []string{"def", "ghi"},
   182  		},
   183  		[]error{
   184  			&Error{
   185  				Err: fmt.Errorf("filtered field nested.foo cannot be set in a Blueprint file"),
   186  				Pos: scanner.Position{"", 27, 4, 8},
   187  			},
   188  		},
   189  	},
   190  }
   191  
   192  func TestUnpackProperties(t *testing.T) {
   193  	for _, testCase := range validUnpackTestCases {
   194  		r := bytes.NewBufferString(testCase.input)
   195  		file, errs := parser.Parse("", r, nil)
   196  		if len(errs) != 0 {
   197  			t.Errorf("test case: %s", testCase.input)
   198  			t.Errorf("unexpected parse errors:")
   199  			for _, err := range errs {
   200  				t.Errorf("  %s", err)
   201  			}
   202  			t.FailNow()
   203  		}
   204  
   205  		module := file.Defs[0].(*parser.Module)
   206  		properties := proptools.CloneProperties(reflect.ValueOf(testCase.output))
   207  		proptools.ZeroProperties(properties.Elem())
   208  		_, errs = unpackProperties(module.Properties, properties.Interface())
   209  		if len(errs) != 0 && len(testCase.errs) == 0 {
   210  			t.Errorf("test case: %s", testCase.input)
   211  			t.Errorf("unexpected unpack errors:")
   212  			for _, err := range errs {
   213  				t.Errorf("  %s", err)
   214  			}
   215  			t.FailNow()
   216  		} else if !reflect.DeepEqual(errs, testCase.errs) {
   217  			t.Errorf("test case: %s", testCase.input)
   218  			t.Errorf("incorrect errors:")
   219  			t.Errorf("  expected: %+v", testCase.errs)
   220  			t.Errorf("       got: %+v", errs)
   221  		}
   222  
   223  		output := properties.Elem().Interface()
   224  		if !reflect.DeepEqual(output, testCase.output) {
   225  			t.Errorf("test case: %s", testCase.input)
   226  			t.Errorf("incorrect output:")
   227  			t.Errorf("  expected: %+v", testCase.output)
   228  			t.Errorf("       got: %+v", output)
   229  		}
   230  	}
   231  }