mirror of
https://github.com/robertkrimen/otto
synced 2025-10-12 20:27:30 +08:00
Fix that we were using a non-runtime toValue method with go_array, go_map, and go_struct
This will fix #13
This commit is contained in:
parent
b477d8eaed
commit
149f94f9fb
59
bug_test.go
59
bug_test.go
|
@ -21,3 +21,62 @@ func Test_issue5(t *testing.T) {
|
|||
test(`'abc' === 'def'`, "false")
|
||||
test(`'\t' === '\r'`, "false")
|
||||
}
|
||||
|
||||
func Test_issue13(t *testing.T) {
|
||||
Terst(t)
|
||||
|
||||
otto, test := runTestWithOtto()
|
||||
value, err := otto.ToValue(map[string]interface{}{
|
||||
"string": "Xyzzy",
|
||||
"number": 42,
|
||||
"array": []string{"def", "ghi"},
|
||||
})
|
||||
if err != nil {
|
||||
FailNow(err)
|
||||
}
|
||||
fn, err := otto.Object(`
|
||||
(function(value){
|
||||
return ""+[value.string, value.number, value.array]
|
||||
})
|
||||
`)
|
||||
if err != nil {
|
||||
FailNow(err)
|
||||
}
|
||||
result, err := fn.Value().Call(fn.Value(), value)
|
||||
if err != nil {
|
||||
FailNow(err)
|
||||
}
|
||||
Is(result.toString(), "Xyzzy,42,def,ghi")
|
||||
|
||||
anything := struct {
|
||||
Abc interface{}
|
||||
}{
|
||||
Abc: map[string]interface{}{
|
||||
"def": []interface{}{
|
||||
[]interface{}{
|
||||
"a", "b", "c", "", "d", "e",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"jkl": "Nothing happens.",
|
||||
},
|
||||
},
|
||||
"ghi": -1,
|
||||
},
|
||||
}
|
||||
otto.Set("anything", anything)
|
||||
test(`
|
||||
[
|
||||
anything,
|
||||
"~",
|
||||
anything.Abc,
|
||||
"~",
|
||||
anything.Abc.def,
|
||||
"~",
|
||||
anything.Abc.def[1].jkl,
|
||||
"~",
|
||||
anything.Abc.ghi,
|
||||
];
|
||||
`, "[object Object],~,[object Object],~,a,b,c,,d,e,[object Object],~,Nothing happens.,~,-1",
|
||||
)
|
||||
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
func (runtime *_runtime) newGoArrayObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Array" // TODO Should this be something else?
|
||||
self.stash = newGoArrayStash(value, self.stash)
|
||||
self.stash = newGoArrayStash(value, self.stash, runtime)
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,12 @@ type _goArrayStash struct {
|
|||
writable bool
|
||||
propertyMode _propertyMode
|
||||
_stash
|
||||
// We pass the runtime to the stash to it can do deep
|
||||
// value promotion
|
||||
runtime *_runtime
|
||||
}
|
||||
|
||||
func newGoArrayStash(value reflect.Value, stash _stash) *_goArrayStash {
|
||||
func newGoArrayStash(value reflect.Value, stash _stash, runtime *_runtime) *_goArrayStash {
|
||||
propertyMode := _propertyMode(0111)
|
||||
writable := true
|
||||
switch value.Kind() {
|
||||
|
@ -37,6 +40,7 @@ func newGoArrayStash(value reflect.Value, stash _stash) *_goArrayStash {
|
|||
writable: writable,
|
||||
propertyMode: propertyMode,
|
||||
_stash: stash,
|
||||
runtime: runtime,
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
@ -91,7 +95,7 @@ func (self *_goArrayStash) get(name string) Value {
|
|||
if !exists {
|
||||
return UndefinedValue()
|
||||
}
|
||||
return toValue(value)
|
||||
return self.runtime.toValue(value.Interface())
|
||||
}
|
||||
|
||||
return self._stash.get(name)
|
||||
|
@ -113,7 +117,7 @@ func (self *_goArrayStash) property(name string) *_property {
|
|||
value := UndefinedValue()
|
||||
reflectValue, exists := self.getValue(int(index))
|
||||
if exists {
|
||||
value = toValue(reflectValue)
|
||||
value = self.runtime.toValue(reflectValue.Interface())
|
||||
}
|
||||
return &_property{
|
||||
value: value,
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
func (runtime *_runtime) newGoMapObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Object" // TODO Should this be something else?
|
||||
self.stash = newGoMapStash(value, self.stash)
|
||||
self.stash = newGoMapStash(value, self.stash, runtime)
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,12 @@ type _goMapStash struct {
|
|||
keyKind reflect.Kind
|
||||
valueKind reflect.Kind
|
||||
_stash
|
||||
// We pass the runtime to the stash to it can do deep
|
||||
// value promotion
|
||||
runtime *_runtime
|
||||
}
|
||||
|
||||
func newGoMapStash(value reflect.Value, stash _stash) *_goMapStash {
|
||||
func newGoMapStash(value reflect.Value, stash _stash, runtime *_runtime) *_goMapStash {
|
||||
if value.Kind() != reflect.Map {
|
||||
dbgf("%/panic//%@: %v != reflect.Map", value.Kind())
|
||||
}
|
||||
|
@ -27,6 +30,7 @@ func newGoMapStash(value reflect.Value, stash _stash) *_goMapStash {
|
|||
keyKind: value.Type().Key().Kind(),
|
||||
valueKind: value.Type().Elem().Kind(),
|
||||
_stash: stash,
|
||||
runtime: runtime,
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
@ -60,7 +64,7 @@ func (self *_goMapStash) test(name string) bool {
|
|||
func (self *_goMapStash) get(name string) Value {
|
||||
value := self.value.MapIndex(self.toKey(name))
|
||||
if value.IsValid() {
|
||||
return toValue(value)
|
||||
return self.runtime.toValue(value.Interface())
|
||||
}
|
||||
|
||||
return UndefinedValue()
|
||||
|
@ -70,7 +74,7 @@ func (self *_goMapStash) property(name string) *_property {
|
|||
value := self.value.MapIndex(self.toKey(name))
|
||||
if value.IsValid() {
|
||||
return &_property{
|
||||
toValue(value),
|
||||
self.runtime.toValue(value.Interface()),
|
||||
0111, // +Write +Enumerate +Configure
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,22 +7,26 @@ import (
|
|||
func (runtime *_runtime) newGoStructObject(value reflect.Value) *_object {
|
||||
self := runtime.newObject()
|
||||
self.class = "Object" // TODO Should this be something else?
|
||||
self.stash = newGoStructStash(value, self.stash)
|
||||
self.stash = newGoStructStash(value, self.stash, runtime)
|
||||
return self
|
||||
}
|
||||
|
||||
type _goStructStash struct {
|
||||
value reflect.Value
|
||||
_stash
|
||||
// We pass the runtime to the stash to it can do deep
|
||||
// value promotion
|
||||
runtime *_runtime
|
||||
}
|
||||
|
||||
func newGoStructStash(value reflect.Value, stash _stash) *_goStructStash {
|
||||
func newGoStructStash(value reflect.Value, stash _stash, runtime *_runtime) *_goStructStash {
|
||||
if value.Kind() != reflect.Struct {
|
||||
dbgf("%/panic//%@: %v != reflect.Struct", value.Kind())
|
||||
}
|
||||
self := &_goStructStash{
|
||||
value: value,
|
||||
_stash: stash,
|
||||
value: value,
|
||||
_stash: stash,
|
||||
runtime: runtime,
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
@ -62,7 +66,7 @@ func (self *_goStructStash) test(name string) bool {
|
|||
func (self *_goStructStash) get(name string) Value {
|
||||
value := self.getValue(name)
|
||||
if value.IsValid() {
|
||||
return toValue(value)
|
||||
return self.runtime.toValue(value.Interface())
|
||||
}
|
||||
|
||||
return self._stash.get(name)
|
||||
|
@ -72,7 +76,7 @@ func (self *_goStructStash) property(name string) *_property {
|
|||
value := self.getValue(name)
|
||||
if value.IsValid() {
|
||||
return &_property{
|
||||
toValue(value),
|
||||
self.runtime.toValue(value.Interface()),
|
||||
0111, // +Write +Enumerate +Configure
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user