Skip to content

Commit

Permalink
Expand configuration with helper methods
Browse files Browse the repository at this point in the history
Mappings with fallbacks, reverse mappings ...
  • Loading branch information
mhemeryck committed Nov 29, 2018
1 parent a015329 commit e334be0
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 1 deletion.
48 changes: 48 additions & 0 deletions configuration.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,54 @@
package unipitt

import (
"io/ioutil"
"log"

yaml "gopkg.in/yaml.v2"
)

// Configuration represents the topic name for the MQTT message for a given instance name
type Configuration struct {
Topics map[string]string
}

// Topic gets a topic (value) for a given name (key). Return the name itself as fallback
func (c *Configuration) Topic(name string) string {
if value, ok := c.Topics[name]; ok {
return value
}
return name
}

// reverseTopics construct reverse mapping of topics
func (c *Configuration) reverseTopics() map[string]string {
r := make(map[string]string)
for key, value := range c.Topics {
r[value] = key
}
return r
}

// Name reverse mapping of topic for given name. In case nothing is found, just return the topic itself, hoping there's a mapped instance for it
func (c *Configuration) Name(topic string) string {
if name, ok := c.reverseTopics()[topic]; ok {
return name
}
return topic
}

// configFromFile reads a configuration from a yaml file
func configFromFile(configFile string) (c Configuration, err error) {
f, err := ioutil.ReadFile(configFile)
if err != nil {
log.Printf("Error reading config file: %s\n", err)
return
}

err = yaml.Unmarshal(f, &c)
if err != nil {
log.Printf("Error unmarshalling the config: %s\n", err)
return
}
return
}
116 changes: 115 additions & 1 deletion configuration_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package unipitt

import (
"io/ioutil"
"os"
"testing"

yaml "gopkg.in/yaml.v2"
)

func TestConfiguration(t *testing.T) {
func TestConfigurationUnmarshal(t *testing.T) {
input := []byte(`
topics:
di_1_01: kitchen switch
Expand All @@ -33,3 +35,115 @@ topics:
}
}
}

func TestConfigurationTopic(t *testing.T) {
cases := []struct {
Name string
Expected string
}{
{Name: "foo", Expected: "qux"},
{Name: "bar", Expected: "bar"},
}
c := Configuration{
Topics: map[string]string{
"foo": "qux",
},
}
for _, testCase := range cases {
result := c.Topic(testCase.Name)
if result != testCase.Expected {
t.Fatalf("Expected result to be %s, got %s\n", testCase.Expected, result)
}
}
}

func TestConfigurationName(t *testing.T) {
cases := []struct {
Topic string
Expected string
}{
{Topic: "foo", Expected: "qux"},
{Topic: "bar", Expected: "bar"},
}
c := Configuration{
Topics: map[string]string{
"qux": "foo",
},
}
for _, testCase := range cases {
result := c.Name(testCase.Topic)
if result != testCase.Expected {
t.Fatalf("Expected result to be %s, got %s\n", testCase.Expected, result)
}
}
}

func TestConfigFromFileNonExistant(t *testing.T) {
_, err := configFromFile("foo")
if err == nil {
t.Fatalf("Expected an error to occur reading non-existant file, got not none")
}
}

func TestConfigFromFile(t *testing.T) {
configFile, err := ioutil.TempFile("", "config")
if err != nil {
t.Fatal(err)
}
defer os.Remove(configFile.Name())

content := []byte(`
topics:
di_1_01: kitchen switch
do_2_02: living light
`)
if _, err := configFile.Write(content); err != nil {
t.Fatal(err)
}
if err := configFile.Close(); err != nil {
t.Fatal(err)
}

c, err := configFromFile(configFile.Name())
if err != nil {
t.Fatal(err)
}

expected := &Configuration{
Topics: map[string]string{
"di_1_01": "kitchen switch",
"do_2_02": "living light",
},
}

for k, v := range expected.Topics {
if topic, ok := c.Topics[k]; !ok {
t.Errorf("Could not find topic for name %s\n", k)
} else if topic != v {
t.Errorf("Expected topic to be %s, but got %s\n", v, topic)
}
}

}

func TestConfigFromFileUnmarshalIssue(t *testing.T) {
configFile, err := ioutil.TempFile("", "config")
if err != nil {
t.Fatal(err)
}
defer os.Remove(configFile.Name())

content := []byte("foo")

if _, err := configFile.Write(content); err != nil {
t.Fatal(err)
}
if err := configFile.Close(); err != nil {
t.Fatal(err)
}

_, err = configFromFile(configFile.Name())
if err == nil {
t.Fatal("Expected an error on unmarshalling, got none")
}
}

0 comments on commit e334be0

Please sign in to comment.