helper/schema: Set operations

This commit is contained in:
Mitchell Hashimoto 2014-08-20 18:30:28 -07:00
parent ca18e971d1
commit 475528adc3
4 changed files with 137 additions and 5 deletions

View File

@ -223,6 +223,8 @@ func (m schemaMap) diff(
err = m.diffList(k, schema, diff, d)
case TypeMap:
err = m.diffMap(k, schema, diff, d)
case TypeSet:
err = m.diffSet(k, schema, diff, d)
default:
err = fmt.Errorf("%s: unknown type %s", k, schema.Type)
}
@ -348,6 +350,14 @@ func (m schemaMap) diffMap(
return nil
}
func (m schemaMap) diffSet(
k string,
schema *Schema,
diff *terraform.ResourceDiff,
d *ResourceData) error {
return nil
}
func (m schemaMap) diffString(
k string,
schema *Schema,

View File

@ -320,6 +320,9 @@ func TestSchemaMap_Diff(t *testing.T) {
},
/*
* Set
*/
{
Schema: map[string]*Schema{
"ports": &Schema{
@ -361,7 +364,6 @@ func TestSchemaMap_Diff(t *testing.T) {
Err: false,
},
*/
/*
* List of structure decode

View File

@ -8,9 +8,9 @@ import (
// Set is a set data structure that is returned for elements of type
// TypeSet.
type Set struct {
F SchemaSetFunc
F SchemaSetFunc
m map[int]interface{}
m map[int]interface{}
once sync.Once
}
@ -23,7 +23,7 @@ func (s *Set) Add(item interface{}) {
//
// The order of the returned elements is deterministic. Given the same
// set, the order of this will always be the same.
func (s *Set) List() []interface{}{
func (s *Set) List() []interface{} {
result := make([]interface{}, len(s.m))
for i, k := range s.listCode() {
result[i] = s.m[k]
@ -32,6 +32,52 @@ func (s *Set) List() []interface{}{
return result
}
// Differences performs a set difference of the two sets, returning
// a new third set that has only the elements unique to this set.
func (s *Set) Difference(other *Set) *Set {
result := &Set{F: s.F}
result.init()
for k, v := range s.m {
if _, ok := other.m[k]; !ok {
result.m[k] = v
}
}
return result
}
// Intersection performs the set intersection of the two sets
// and returns a new third set.
func (s *Set) Intersection(other *Set) *Set {
result := &Set{F: s.F}
result.init()
for k, v := range s.m {
if _, ok := other.m[k]; ok {
result.m[k] = v
}
}
return result
}
// Union performs the set union of the two sets and returns a new third
// set.
func (s *Set) Union(other *Set) *Set {
result := &Set{F: s.F}
result.init()
for k, v := range s.m {
result.m[k] = v
}
for k, v := range other.m {
result.m[k] = v
}
return result
}
func (s *Set) init() {
s.m = make(map[int]interface{})
}
@ -47,7 +93,7 @@ func (s *Set) add(item interface{}) int {
return code
}
func (s *Set) listCode() []int{
func (s *Set) listCode() []int {
// Sort the hash codes so the order of the list is deterministic
keys := make([]int, 0, len(s.m))
for k, _ := range s.m {

74
helper/schema/set_test.go Normal file
View File

@ -0,0 +1,74 @@
package schema
import (
"reflect"
"testing"
)
func TestSetAdd(t *testing.T) {
s := &Set{F: testSetInt}
s.Add(1)
s.Add(5)
s.Add(25)
expected := []interface{}{1, 5, 25}
actual := s.List()
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestSetDifference(t *testing.T) {
s1 := &Set{F: testSetInt}
s2:= &Set{F: testSetInt}
s1.Add(1)
s1.Add(5)
s2.Add(5)
s2.Add(25)
expected := []interface{}{1}
actual := s1.Difference(s2).List()
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestSetIntersection(t *testing.T) {
s1 := &Set{F: testSetInt}
s2:= &Set{F: testSetInt}
s1.Add(1)
s1.Add(5)
s2.Add(5)
s2.Add(25)
expected := []interface{}{5}
actual := s1.Intersection(s2).List()
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestSetUnion(t *testing.T) {
s1 := &Set{F: testSetInt}
s2:= &Set{F: testSetInt}
s1.Add(1)
s1.Add(5)
s2.Add(5)
s2.Add(25)
expected := []interface{}{1, 5, 25}
actual := s1.Union(s2).List()
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func testSetInt(v interface{}) int {
return v.(int)
}