Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/android/soongconfig/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 13 kB image not shown  

Quelle  modules_test.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2020 Google Inc. All rights reserved.
//
// 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 soongconfig

import (
 "reflect"
 "testing"

 "github.com/google/blueprint/proptools"
)

func Test_CanonicalizeToProperty(t *testing.T) {
 tests := []struct {
  name string
  arg  string
  want string
 }{
  {
   name: "lowercase",
   arg:  "board",
   want: "board",
  },
  {
   name: "uppercase",
   arg:  "BOARD",
   want: "BOARD",
  },
  {
   name: "numbers",
   arg:  "BOARD123",
   want: "BOARD123",
  },
  {
   name: "underscore",
   arg:  "TARGET_BOARD",
   want: "TARGET_BOARD",
  },
  {
   name: "dash",
   arg:  "TARGET-BOARD",
   want: "TARGET_BOARD",
  },
  {
   name: "unicode",
   arg:  "boardλ",
   want: "board_",
  },
 }
 for _, tt := range tests {
  t.Run(tt.name, func(t *testing.T) {
   if got := CanonicalizeToProperty(tt.arg); got != tt.want {
    t.Errorf("canonicalizeToProperty() = %v, want %v", got, tt.want)
   }
  })
 }
}

func Test_typeForPropertyFromPropertyStruct(t *testing.T) {
 tests := []struct {
  name     string
  ps       interface{}
  property string
  want     string
 }{
  {
   name: "string",
   ps: struct {
    A string
   }{},
   property: "a",
   want:     "string",
  },
  {
   name: "list",
   ps: struct {
    A []string
   }{},
   property: "a",
   want:     "[]string",
  },
  {
   name: "missing",
   ps: struct {
    A []string
   }{},
   property: "b",
   want:     "",
  },
  {
   name: "nested",
   ps: struct {
    A struct {
     B string
    }
   }{},
   property: "a.b",
   want:     "string",
  },
  {
   name: "missing nested",
   ps: struct {
    A struct {
     B string
    }
   }{},
   property: "a.c",
   want:     "",
  },
  {
   name: "not a struct",
   ps: struct {
    A string
   }{},
   property: "a.b",
   want:     "",
  },
  {
   name: "nested pointer",
   ps: struct {
    A *struct {
     B string
    }
   }{},
   property: "a.b",
   want:     "string",
  },
  {
   name: "nested interface",
   ps: struct {
    A interface{}
   }{
    A: struct {
     B string
    }{},
   },
   property: "a.b",
   want:     "string",
  },
  {
   name: "nested interface pointer",
   ps: struct {
    A interface{}
   }{
    A: &struct {
     B string
    }{},
   },
   property: "a.b",
   want:     "string",
  },
  {
   name: "nested interface nil pointer",
   ps: struct {
    A interface{}
   }{
    A: (*struct {
     B string
    })(nil),
   },
   property: "a.b",
   want:     "string",
  },
 }
 for _, tt := range tests {
  t.Run(tt.name, func(t *testing.T) {
   typ := typeForPropertyFromPropertyStruct(tt.ps, tt.property)
   got := ""
   if typ != nil {
    got = typ.String()
   }
   if got != tt.want {
    t.Errorf("typeForPropertyFromPropertyStruct() = %v, want %v", got, tt.want)
   }
  })
 }
}

func Test_createAffectablePropertiesType(t *testing.T) {
 tests := []struct {
  name                 string
  affectableProperties []string
  factoryProps         interface{}
  want                 string
 }{
  {
   name:                 "string",
   affectableProperties: []string{"cflags"},
   factoryProps: struct {
    Cflags string
   }{},
   want: "*struct { Cflags string }",
  },
  {
   name:                 "list",
   affectableProperties: []string{"cflags"},
   factoryProps: struct {
    Cflags []string
   }{},
   want: "*struct { Cflags []string }",
  },
  {
   name:                 "string pointer",
   affectableProperties: []string{"cflags"},
   factoryProps: struct {
    Cflags *string
   }{},
   want: "*struct { Cflags *string }",
  },
  {
   name:                 "subset",
   affectableProperties: []string{"cflags"},
   factoryProps: struct {
    Cflags  string
    Ldflags string
   }{},
   want: "*struct { Cflags string }",
  },
  {
   name:                 "none",
   affectableProperties: []string{"cflags"},
   factoryProps: struct {
    Ldflags string
   }{},
   want: "",
  },
  {
   name:                 "nested",
   affectableProperties: []string{"multilib.lib32.cflags"},
   factoryProps: struct {
    Multilib struct {
     Lib32 struct {
      Cflags string
     }
    }
   }{},
   want: "*struct { Multilib struct { Lib32 struct { Cflags string } } }",
  },
  {
   name: "complex",
   affectableProperties: []string{
    "cflags",
    "multilib.lib32.cflags",
    "multilib.lib32.ldflags",
    "multilib.lib64.cflags",
    "multilib.lib64.ldflags",
    "zflags",
   },
   factoryProps: struct {
    Cflags   string
    Multilib struct {
     Lib32 struct {
      Cflags  string
      Ldflags string
     }
     Lib64 struct {
      Cflags  string
      Ldflags string
     }
    }
    Zflags string
   }{},
   want: "*struct { Cflags string; Multilib struct { Lib32 struct { Cflags string; Ldflags string }; Lib64 struct { Cflags string; Ldflags string } }; Zflags string }",
  },
 }
 for _, tt := range tests {
  t.Run(tt.name, func(t *testing.T) {
   typ := createAffectablePropertiesType(tt.affectableProperties, []interface{}{tt.factoryProps})
   got := ""
   if typ != nil {
    got = typ.String()
   }
   if !reflect.DeepEqual(got, tt.want) {
    t.Errorf("createAffectablePropertiesType() = %v, want %v", got, tt.want)
   }
  })
 }
}

type properties struct {
 A *string
 B bool
 C []string
}

type varProps struct {
 A                  *string
 B                  bool
 C                  []string
 Conditions_default *properties
}

type boolSoongConfigVars struct {
 Bool_var interface{}
}

type stringSoongConfigVars struct {
 String_var interface{}
}

type valueSoongConfigVars struct {
 My_value_var interface{}
}

type listProperties struct {
 C []string
}

type listVarProps struct {
 C                  []string
 Conditions_default *listProperties
}

type listSoongConfigVars struct {
 List_var interface{}
}

func Test_PropertiesToApply_Bool(t *testing.T) {
 mt, _ := newModuleType(&ModuleTypeProperties{
  Module_type:      "foo",
  Config_namespace: "bar",
  Bool_variables:   []string{"bool_var"},
  Properties:       []string{"a", "b"},
 })
 boolVarPositive := &properties{
  A: proptools.StringPtr("A"),
  B: true,
 }
 conditionsDefault := &properties{
  A: proptools.StringPtr("default"),
  B: false,
 }
 actualProps := &struct {
  Soong_config_variables boolSoongConfigVars
 }{
  Soong_config_variables: boolSoongConfigVars{
   Bool_var: &varProps{
    A:                  boolVarPositive.A,
    B:                  boolVarPositive.B,
    Conditions_default: conditionsDefault,
   },
  },
 }
 props := reflect.ValueOf(actualProps)

 testCases := []struct {
  name      string
  config    SoongConfig
  wantProps []interface{}
 }{
  {
   name:      "no_vendor_config",
   config:    Config(map[string]string{}),
   wantProps: []interface{}{conditionsDefault},
  },
  {
   name:      "vendor_config_false",
   config:    Config(map[string]string{"bool_var": "n"}),
   wantProps: []interface{}{conditionsDefault},
  },
  {
   name:      "bool_var_true",
   config:    Config(map[string]string{"bool_var": "y"}),
   wantProps: []interface{}{boolVarPositive},
  },
 }

 for _, tc := range testCases {
  gotProps, err := PropertiesToApply(mt, props, tc.config)
  if err != nil {
   t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
  }

  if !reflect.DeepEqual(gotProps, tc.wantProps) {
   t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
  }
 }
}

func Test_PropertiesToApply_List(t *testing.T) {
 mt, _ := newModuleType(&ModuleTypeProperties{
  Module_type:      "foo",
  Config_namespace: "bar",
  List_variables:   []string{"my_list_var"},
  Properties:       []string{"c"},
 })
 conditionsDefault := &listProperties{
  C: []string{"default"},
 }
 actualProps := &struct {
  Soong_config_variables listSoongConfigVars
 }{
  Soong_config_variables: listSoongConfigVars{
   List_var: &listVarProps{
    C:                  []string{"A=%s", "B=%s"},
    Conditions_default: conditionsDefault,
   },
  },
 }
 props := reflect.ValueOf(actualProps)

 testCases := []struct {
  name      string
  config    SoongConfig
  wantProps []interface{}
 }{
  {
   name:      "no_vendor_config",
   config:    Config(map[string]string{}),
   wantProps: []interface{}{conditionsDefault},
  },
  {
   name:   "value_var_set",
   config: Config(map[string]string{"my_list_var": "hello there"}),
   wantProps: []interface{}{&listProperties{
    C: []string{"A=hello", "A=there", "B=hello", "B=there"},
   }},
  },
 }

 for _, tc := range testCases {
  gotProps, err := PropertiesToApply(mt, props, tc.config)
  if err != nil {
   t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
  }

  if !reflect.DeepEqual(gotProps, tc.wantProps) {
   t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
  }
 }
}

func Test_PropertiesToApply_Value(t *testing.T) {
 mt, _ := newModuleType(&ModuleTypeProperties{
  Module_type:      "foo",
  Config_namespace: "bar",
  Value_variables:  []string{"my_value_var"},
  Properties:       []string{"a", "b"},
 })
 conditionsDefault := &properties{
  A: proptools.StringPtr("default"),
  B: false,
 }
 actualProps := &struct {
  Soong_config_variables valueSoongConfigVars
 }{
  Soong_config_variables: valueSoongConfigVars{
   My_value_var: &varProps{
    A:                  proptools.StringPtr("A=%s"),
    B:                  true,
    Conditions_default: conditionsDefault,
   },
  },
 }
 props := reflect.ValueOf(actualProps)

 testCases := []struct {
  name      string
  config    SoongConfig
  wantProps []interface{}
 }{
  {
   name:      "no_vendor_config",
   config:    Config(map[string]string{}),
   wantProps: []interface{}{conditionsDefault},
  },
  {
   name:   "value_var_set",
   config: Config(map[string]string{"my_value_var": "Hello"}),
   wantProps: []interface{}{&properties{
    A: proptools.StringPtr("A=Hello"),
    B: true,
   }},
  },
 }

 for _, tc := range testCases {
  gotProps, err := PropertiesToApply(mt, props, tc.config)
  if err != nil {
   t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
  }

  if !reflect.DeepEqual(gotProps, tc.wantProps) {
   t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
  }
 }
}

func Test_PropertiesToApply_Value_Nested(t *testing.T) {
 mt, _ := newModuleType(&ModuleTypeProperties{
  Module_type:      "foo",
  Config_namespace: "bar",
  Value_variables:  []string{"my_value_var"},
  Properties:       []string{"a.b"},
 })
 type properties struct {
  A struct {
   B string
  }
 }
 conditionsDefault := &properties{
  A: struct{ B string }{
   B: "default",
  },
 }
 type valueVarProps struct {
  A struct {
   B string
  }
  Conditions_default *properties
 }
 actualProps := &struct {
  Soong_config_variables valueSoongConfigVars
 }{
  Soong_config_variables: valueSoongConfigVars{
   My_value_var: &valueVarProps{
    A: struct{ B string }{
     B: "A.B=%s",
    },
    Conditions_default: conditionsDefault,
   },
  },
 }
 props := reflect.ValueOf(actualProps)

 testCases := []struct {
  name      string
  config    SoongConfig
  wantProps []interface{}
 }{
  {
   name:      "no_vendor_config",
   config:    Config(map[string]string{}),
   wantProps: []interface{}{conditionsDefault},
  },
  {
   name:   "value_var_set",
   config: Config(map[string]string{"my_value_var": "Hello"}),
   wantProps: []interface{}{&properties{
    A: struct{ B string }{
     B: "A.B=Hello",
    },
   }},
  },
 }

 for _, tc := range testCases {
  gotProps, err := PropertiesToApply(mt, props, tc.config)
  if err != nil {
   t.Errorf("%s: Unexpected error in PropertiesToApply: %s", tc.name, err)
  }

  if !reflect.DeepEqual(gotProps, tc.wantProps) {
   t.Errorf("%s: Expected %s, got %s", tc.name, tc.wantProps, gotProps)
  }
 }
}

func Test_PropertiesToApply_String_Error(t *testing.T) {
 mt, _ := newModuleType(&ModuleTypeProperties{
  Module_type:      "foo",
  Config_namespace: "bar",
  Variables:        []string{"string_var"},
  Properties:       []string{"a", "b"},
 })
 mt.Variables = append(mt.Variables, &stringVariable{
  baseVariable: baseVariable{
   variable: "string_var",
  },
  values: []string{"a", "b", "c"},
 })
 stringVarPositive := &properties{
  A: proptools.StringPtr("A"),
  B: true,
 }
 conditionsDefault := &properties{
  A: proptools.StringPtr("default"),
  B: false,
 }
 actualProps := &struct {
  Soong_config_variables stringSoongConfigVars
 }{
  Soong_config_variables: stringSoongConfigVars{
   String_var: &varProps{
    A:                  stringVarPositive.A,
    B:                  stringVarPositive.B,
    Conditions_default: conditionsDefault,
   },
  },
 }
 props := reflect.ValueOf(actualProps)

 _, err := PropertiesToApply(mt, props, Config(map[string]string{
  "string_var": "x",
 }))
 expected := `Soong config property "string_var" must be one of [a b c], found "x"`
 if err == nil {
  t.Fatalf("Expected an error, got nil")
 } else if err.Error() != expected {
  t.Fatalf("Error message was not correct, expected %q, got %q", expected, err.Error())
 }
}

[Dauer der Verarbeitung: 0.21 Sekunden, vorverarbeitet 2026-06-28]