Skip to content

Commit

Permalink
Add support to the map operator
Browse files Browse the repository at this point in the history
Example compiled PlanOut code:
{
  "op": "seq",
  "seq": [
    {
      "op": "set",
      "var": "foo",
      "value": "inside"
    },
    {
      "op": "set",
      "var": "baz",
      "value": {
        "bar": {
          "op": "get",
          "var": "foo"
        },
        "op": "map"
      }
    },
    {
      "op": "set",
      "var": "x",
      "value": {
        "a": 2,
        "b": {
          "op": "get",
          "var": "baz"
        },
        "op": "map"
      }
    }
  ]
}

When the above code is interpreted, the variable 'x' will be assigned a map.
This map contains two (k, v) pairs.
"a" = 2
"b" = map containing the (k, v) "bar" = "inside".

Update test for map operator

... test assignment of an empty dictionary
  • Loading branch information
tsujeeth committed Jun 24, 2015
1 parent 90cd54b commit 666070e
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 0 deletions.
37 changes: 37 additions & 0 deletions core_ops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package planout
import (
"encoding/json"
"fmt"
"reflect"
"testing"
)

Expand Down Expand Up @@ -81,6 +82,42 @@ func TestCoreOps(t *testing.T) {
{"op": "set", "var": "x", "value": {"op": "array", "values": [4, 5, "a"]}}`))
x, _ = expt.Get("x")

// Test Dictionary
expt, _ = runExperiment([]byte(`
{"op": "set", "var": "x", "value": {"op": "map", "a": 2, "b": "foo", "c": [0, 1, 2]}}`))
x, _ = expt.Get("x")
if x == nil {
t.Errorf("Variable x. Expected a map. Actual nil.\n")
} else {
x_map, ok := x.(map[string]interface{})
if !ok {
t.Errorf("Variable x. Expected of type map. Actual %v\n", reflect.TypeOf(x))
}
foo, ok := x_map["b"]
if !ok {
t.Errorf("Variable x['b']. Expected 'foo'. Does not exists.\n")
}
if foo != "foo" {
t.Errorf("Variable x['b']. Expected 'foo'. Actual %v\n", foo)
}
}

// Test empty dictionary
expt, _ = runExperiment([]byte(`
{"op": "set", "var": "x", "value": {"op": "map"}}`))
x, _ = expt.Get("x")
if x == nil {
t.Errorf("Variable x. Expected a map. Actual nil.\n")
} else {
x_map, ok := x.(map[string]interface{})
if !ok {
t.Errorf("Variable x. Expected of type map. Actual %v\n", reflect.TypeOf(x))
}
if len(x_map) != 0 {
t.Errorf("Variable x. Expected empty map. Actual %v\n", x_map)
}
}

// Test Condition
expt, _ = runExperiment([]byte(`
{"op": "cond",
Expand Down
13 changes: 13 additions & 0 deletions operators.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func init() {
"set": &set{},
"get": &get{},
"array": &array{},
"map": &dict{},
"index": &index{},
"length": &length{},
"coalesce": &coalesce{},
Expand Down Expand Up @@ -127,6 +128,18 @@ func (s *array) execute(m map[string]interface{}, interpreter *Interpreter) inte
return ret
}

type dict struct{}

func (s *dict) execute(m map[string]interface{}, interpreter *Interpreter) interface{} {
dictionary := make(map[string]interface{})
for k, v := range m {
if k != "op" {
dictionary[k] = interpreter.evaluate(v)
}
}
return dictionary
}

type index struct{}

func (s *index) execute(m map[string]interface{}, interpreter *Interpreter) interface{} {
Expand Down
47 changes: 47 additions & 0 deletions simple_ops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,50 @@ func TestSimpleOps(t *testing.T) {
t.Errorf("Variable 'z' '%v'. Expected 'test-string'\n", z2)
}
}

func TestMapOp(t *testing.T) {
js := readTest("test/map_operator.json")

data := Struct{Member: 101, String: "test-string"}
params := make(map[string]interface{})
params["struct"] = data

expt := &Interpreter{
Salt: "global_salt",
Evaluated: false,
Inputs: params,
Outputs: map[string]interface{}{},
Overrides: map[string]interface{}{},
Code: js,
}

_, ok := expt.Run()
if !ok {
t.Errorf("Error running experiment 'test/map_operator.json'\n")
return
}

x, exists := expt.Get("x")
if !exists {
t.Errorf("TestMapOp: Expected variable 'x' to be assigned.\n")
}
x_map, ok := x.(map[string]interface{})
if !ok {
t.Errorf("TestMapOp: Expected variable 'x' to be of type map. Actual %v\n", reflect.TypeOf(x))
}
b, exists := x_map["b"]
if !exists {
t.Errorf("TestMapOp: Expected variable 'b' inside the map 'x' to be assigned.\n")
}
b_map, ok := b.(map[string]interface{})
if !ok {
t.Errorf("TestMapOp: Expected variable 'b' to be of type map. Actual %v\n", reflect.TypeOf(b))
}
bar, exists := b_map["bar"]
if !exists {
t.Errorf("TestMapOp: Expected variable 'bar' inside the map 'b' to be assigned.\n")
}
if bar != "inside" {
t.Errorf("TestMapOp: Variable='bar'. Expected value='inside' Actual=%v.\n", bar)
}
}
33 changes: 33 additions & 0 deletions test/map_operator.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"op": "seq",
"seq": [
{
"op": "set",
"var": "foo",
"value": "inside"
},
{
"op": "set",
"var": "baz",
"value": {
"bar": {
"op": "get",
"var": "foo"
},
"op": "map"
}
},
{
"op": "set",
"var": "x",
"value": {
"a": 2,
"b": {
"op": "get",
"var": "baz"
},
"op": "map"
}
}
]
}

0 comments on commit 666070e

Please sign in to comment.