From b8121ea63ee91e68b67481de749fcd37f99d3b07 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 26 Apr 2016 09:17:26 -0700 Subject: [PATCH] helper/schema: Resource.Data to return a ResourceData for a Resource --- helper/schema/resource.go | 21 +++++++++++++++ helper/schema/resource_test.go | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/helper/schema/resource.go b/helper/schema/resource.go index 1d045e95ec..631c9c2f6c 100644 --- a/helper/schema/resource.go +++ b/helper/schema/resource.go @@ -265,7 +265,28 @@ func (r *Resource) InternalValidate(topSchemaMap schemaMap) error { return schemaMap(r.Schema).InternalValidate(tsm) } +// Data returns a ResourceData struct for this Resource. Each return value +// is a separate copy and can be safely modified differently. +// +// The data returned from this function has no actual affect on the Resource +// itself (including the state given to this function). +// +// This function is useful for unit tests and ResourceImporter functions. +func (r *Resource) Data(s *terraform.InstanceState) *ResourceData { + result, err := schemaMap(r.Schema).Data(s, nil) + if err != nil { + // At the time of writing, this isn't possible (Data never returns + // non-nil errors). We panic to find this in the future if we have to. + // I don't see a reason for Data to ever return an error. + panic(err) + } + + return result +} + // TestResourceData Yields a ResourceData filled with this resource's schema for use in unit testing +// +// TODO: May be able to be removed with the above ResourceData function. func (r *Resource) TestResourceData() *ResourceData { return &ResourceData{ schema: r.Schema, diff --git a/helper/schema/resource_test.go b/helper/schema/resource_test.go index 0b91cd79ab..820c22bd76 100644 --- a/helper/schema/resource_test.go +++ b/helper/schema/resource_test.go @@ -846,3 +846,51 @@ func TestResourceRefresh_migrateStateErr(t *testing.T) { t.Fatal("expected error, but got none!") } } + +func TestResourceData(t *testing.T) { + r := &Resource{ + SchemaVersion: 2, + Schema: map[string]*Schema{ + "foo": &Schema{ + Type: TypeInt, + Optional: true, + }, + }, + } + + state := &terraform.InstanceState{ + ID: "foo", + Attributes: map[string]string{ + "id": "foo", + "foo": "42", + }, + } + + data := r.Data(state) + if data.Id() != "foo" { + t.Fatalf("err: %s", data.Id()) + } + if v := data.Get("foo"); v != 42 { + t.Fatalf("bad: %#v", v) + } +} + +func TestResourceData_blank(t *testing.T) { + r := &Resource{ + SchemaVersion: 2, + Schema: map[string]*Schema{ + "foo": &Schema{ + Type: TypeInt, + Optional: true, + }, + }, + } + + data := r.Data(nil) + if data.Id() != "" { + t.Fatalf("err: %s", data.Id()) + } + if v := data.Get("foo"); v != 0 { + t.Fatalf("bad: %#v", v) + } +}