diff --git a/class.go b/class.go index 328dfb2..8941538 100644 --- a/class.go +++ b/class.go @@ -78,6 +78,10 @@ func (mrb *State) DefineClassId(name Symbol, super RClass) (RClass, error) { return mrb.defineClass(name, super, mrb.ObjectClass) } +func (mrb *State) ObjectClassName(obj Value) string { + return mrb.ClassName(mrb.Class(obj)) +} + func (mrb *State) ClassName(class RClass) string { if class == nil { return "" diff --git a/features/object.feature b/features/object.feature index 4c7eca8..0ffce54 100644 --- a/features/object.feature +++ b/features/object.feature @@ -28,4 +28,4 @@ Feature: Object end Hello.new.inspect """ - Then there should return string "Hello" + Then there should return string like "#" diff --git a/godogs_test.go b/godogs_test.go index 645ddc0..883fedc 100644 --- a/godogs_test.go +++ b/godogs_test.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "os" + "regexp" "testing" "github.com/cucumber/godog" @@ -99,6 +100,24 @@ func (feat *RubyFeature) thereShouldReturnString(expected string) error { return nil } +func (feat *RubyFeature) thereShouldReturnStringLike(expected string) error { + actual, ok := feat.ret.(string) + if !ok { + return fmt.Errorf("expected string, got %T (%+v)", feat.ret, feat.ret) + } + + expr, err := regexp.Compile(expected) + if err != nil { + return err + } + + if !expr.MatchString(actual) { + return fmt.Errorf("string not matched %s", cmp.Diff(actual, expected)) + } + + return nil +} + func (feat *RubyFeature) thereShouldReturnSymbol(expected string) error { ret, ok := feat.ret.(mruby.Symbol) if !ok { @@ -213,6 +232,7 @@ func InitializeScenario(s *godog.ScenarioContext) { s.Step(`^there should return false$`, feat.thereShouldReturnFalse) s.Step(`^there should return nil$`, feat.thereShouldReturnNil) s.Step(`^there should return string "([^"]*)"$`, feat.thereShouldReturnString) + s.Step(`^there should return string like "([^"]*)"$`, feat.thereShouldReturnStringLike) s.Step(`^there should return symbol "([^"]*)"$`, feat.thereShouldReturnSymbol) s.Step(`^there should return object$`, feat.thereShouldReturnObject) s.Step(`^there should return class "([^"]*)"$`, feat.thereShouldReturnClass) diff --git a/kernel.go b/kernel.go index c73ed06..207e5e0 100644 --- a/kernel.go +++ b/kernel.go @@ -13,9 +13,6 @@ func (mrb *State) Inspect(obj Value) string { func objectInspect(mrb *State, self Value) Value { switch v := self.(type) { - case *Object: - name := mrb.ObjectInstanceVariableGet(v.Class(), _classname(mrb)) - return name case RClass: name := mrb.ObjectInstanceVariableGet(v, _classname(mrb)) return name @@ -24,7 +21,7 @@ func objectInspect(mrb *State, self Value) Value { case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: return fmt.Sprintf("%d", v) default: - return nil + return anyToString(mrb, self) } } diff --git a/object.go b/object.go index cd71b5d..8a7c8c7 100644 --- a/object.go +++ b/object.go @@ -1,5 +1,7 @@ package mruby +import "fmt" + type RBasic interface { Class() RClass Flags() uint32 @@ -44,6 +46,11 @@ func (obj *Object) ivGet(sym Symbol) Value { return obj.iv.Get(sym) } +func anyToString(mrb *State, obj Value) Value { + className := mrb.ObjectClassName(obj) + return fmt.Sprintf("#<%s:%p>", className, obj) +} + func initObject(mrb *State) (err error) { mrb.FalseClass, err = mrb.DefineClassId(_FalseClass(mrb), mrb.ObjectClass) if err != nil { diff --git a/value.go b/value.go index 937b99d..f88847e 100644 --- a/value.go +++ b/value.go @@ -19,6 +19,15 @@ func Test(v Value) bool { return Bool(v) } +func ObjectP(v Value) bool { + switch v.(type) { + case *Object: + return true + default: + return false + } +} + func ClassP(v Value) bool { switch v.(type) { case *Class: