// Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package sdk import ( "testing" "android/soong/android" "github.com/google/blueprint/proptools" ) func propertySetFixture() interface{} { set := newPropertySet() set.AddProperty("x", "taxi") set.AddPropertyWithTag("y", 1729, "tag_y") subset := set.AddPropertySet("sub") subset.AddPropertyWithTag("x", "taxi", "tag_x") subset.AddProperty("y", 1729) return set } func intPtr(i int) *int { return &i } type propertyStruct struct { X *string Y *int Unset *bool Sub struct { X *string Y *int Unset *bool } } func propertyStructFixture() interface{} { str := &propertyStruct{} str.X = proptools.StringPtr("taxi") str.Y = intPtr(1729) str.Sub.X = proptools.StringPtr("taxi") str.Sub.Y = intPtr(1729) return str } func checkPropertySetFixture(t *testing.T, val interface{}, hasTags bool) { set := val.(*bpPropertySet) android.AssertDeepEquals(t, "wrong x value", "taxi", set.getValue("x")) android.AssertDeepEquals(t, "wrong y value", 1729, set.getValue("y")) subset := set.getValue("sub").(*bpPropertySet) android.AssertDeepEquals(t, "wrong sub.x value", "taxi", subset.getValue("x")) android.AssertDeepEquals(t, "wrong sub.y value", 1729, subset.getValue("y")) if hasTags { android.AssertDeepEquals(t, "wrong y tag", "tag_y", set.getTag("y")) android.AssertDeepEquals(t, "wrong sub.x tag", "tag_x", subset.getTag("x")) } else { android.AssertDeepEquals(t, "wrong y tag", nil, set.getTag("y")) android.AssertDeepEquals(t, "wrong sub.x tag", nil, subset.getTag("x")) } } func TestAddPropertySimple(t *testing.T) { set := newPropertySet() for name, val := range map[string]interface{}{ "x": "taxi", "y": 1729, "t": true, "f": false, "arr": []string{"a", "b", "c"}, } { set.AddProperty(name, val) android.AssertDeepEquals(t, "wrong value", val, set.getValue(name)) } android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`, func() { set.AddProperty("x", "taxi") }) android.AssertPanicMessageContains(t, "adding arr again should panic", `Property "arr" already exists in property set`, func() { set.AddProperty("arr", []string{"d"}) }) } func TestAddPropertySubset(t *testing.T) { getFixtureMap := map[string]func() interface{}{ "property set": propertySetFixture, "property struct": propertyStructFixture, } t.Run("add new subset", func(t *testing.T) { for name, getFixture := range getFixtureMap { t.Run(name, func(t *testing.T) { set := propertySetFixture().(*bpPropertySet) set.AddProperty("new", getFixture()) checkPropertySetFixture(t, set, true) checkPropertySetFixture(t, set.getValue("new"), name == "property set") }) } }) t.Run("merge existing subset", func(t *testing.T) { for name, getFixture := range getFixtureMap { t.Run(name, func(t *testing.T) { set := newPropertySet() subset := set.AddPropertySet("sub") subset.AddProperty("flag", false) subset.AddPropertySet("sub") set.AddProperty("sub", getFixture()) merged := set.getValue("sub").(*bpPropertySet) android.AssertDeepEquals(t, "wrong flag value", false, merged.getValue("flag")) checkPropertySetFixture(t, merged, name == "property set") }) } }) t.Run("add conflicting subset", func(t *testing.T) { set := propertySetFixture().(*bpPropertySet) android.AssertPanicMessageContains(t, "adding x again should panic", `Property "x" already exists in property set`, func() { set.AddProperty("x", propertySetFixture()) }) }) t.Run("add non-pointer struct", func(t *testing.T) { set := propertySetFixture().(*bpPropertySet) str := propertyStructFixture().(*propertyStruct) android.AssertPanicMessageContains(t, "adding a non-pointer struct should panic", "Value is a struct, not a pointer to one:", func() { set.AddProperty("new", *str) }) }) } func TestAddPropertySetNew(t *testing.T) { set := newPropertySet() subset := set.AddPropertySet("sub") subset.AddProperty("new", "d^^b") android.AssertDeepEquals(t, "wrong sub.new value", "d^^b", set.getValue("sub").(*bpPropertySet).getValue("new")) } func TestAddPropertySetExisting(t *testing.T) { set := propertySetFixture().(*bpPropertySet) subset := set.AddPropertySet("sub") subset.AddProperty("new", "d^^b") android.AssertDeepEquals(t, "wrong sub.new value", "d^^b", set.getValue("sub").(*bpPropertySet).getValue("new")) } type removeFredTransformation struct { identityTransformation } func (t removeFredTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { if name == "fred" { return nil, nil } return value, tag } func (t removeFredTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { if name == "fred" { return nil, nil } return propertySet, tag } func (t removeFredTransformation) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) { if len(propertySet.properties) == 0 { return nil, nil } return propertySet, tag } func TestTransformRemoveProperty(t *testing.T) { set := newPropertySet() set.AddProperty("name", "name") set.AddProperty("fred", "12") set.transformContents(removeFredTransformation{}) contents := &generatedContents{} outputPropertySet(contents, set) android.AssertTrimmedStringEquals(t, "removing property failed", "name: \"name\",\n", contents.content.String()) } func TestTransformRemovePropertySet(t *testing.T) { set := newPropertySet() set.AddProperty("name", "name") set.AddPropertySet("fred") set.transformContents(removeFredTransformation{}) contents := &generatedContents{} outputPropertySet(contents, set) android.AssertTrimmedStringEquals(t, "removing property set failed", "name: \"name\",\n", contents.content.String()) }