Repository: goby-lang/goby
Pull request #788 (2019-10-06 06:49:21)

Implement Object#tap

codecov[bot]: # [Codecov](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=h1) Report
> Merging [#788](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=desc) into [master](https://codecov.io/gh/goby-lang/goby/commit/ae5e7c3889047ebf2309d60a088887896966ce20?src=pr&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `60%`.

[![Impacted file tree graph](https://codecov.io/gh/goby-lang/goby/pull/788/graphs/tree.svg?width=650&token=giIKD13jMt&height=150&src=pr)](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #788      +/-   ##
==========================================
- Coverage    80.2%   80.19%   -0.02%     
==========================================
  Files          54       54              
  Lines        7392     7397       +5     
==========================================
+ Hits         5929     5932       +3     
- Misses       1236     1237       +1     
- Partials      227      228       +1
```


| [Impacted Files](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [vm/class.go](https://codecov.io/gh/goby-lang/goby/pull/788/diff?src=pr&el=tree#diff-dm0vY2xhc3MuZ28=) | `85.31% <60%> (-0.2%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=footer). Last update [ae5e7c3...83aa84f](https://codecov.io/gh/goby-lang/goby/pull/788?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/vm/class.go b/vm/class.go
index 7a683b7..6e0067c 100644
--- a/vm/class.go
+++ b/vm/class.go
@@ -1536,6 +1536,18 @@ var builtinClassCommonInstanceMethods = []*BuiltinMethodObject{
 
 		},
 	},
+	{
+		Name: "tap",
+		Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object {
+			if blockFrame == nil {
+				return t.vm.InitErrorObject(errors.InternalError, sourceLine, errors.CantYieldWithoutBlockFormat)
+			}
+
+			t.builtinMethodYield(blockFrame, receiver)
+
+			return receiver
+		},
+	},
 	{
 		Name: "thread",
 		Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object {


Test patch:
diff --git a/vm/object_test.go b/vm/object_test.go
index 0761fb7..fb18205 100644
--- a/vm/object_test.go
+++ b/vm/object_test.go
@@ -19,3 +19,50 @@ func TestObjectClassSuperclass(t *testing.T) {
 		v.checkSP(t, i, 1)
 	}
 }
+
+func TestObjectTapMethod(t *testing.T) {
+	tests := []struct {
+		input    string
+		expected interface{}
+	}{
+		{
+			`
+			a = 1
+			a.tap do |int|
+				int + 1
+			end
+`, 1},
+		{
+			`
+			a = 1
+			b = 2
+			a.tap do |int|
+				b = int + b
+			end
+			b
+`, 3},
+	}
+
+	for i, tt := range tests {
+		v := initTestVM()
+		evaluated := v.testEval(t, tt.input, getFilename())
+		VerifyExpected(t, i, evaluated, tt.expected)
+		v.checkCFP(t, i, 0)
+		v.checkSP(t, i, 1)
+	}
+}
+
+func TestObjectTapMethodFail(t *testing.T) {
+	testsFail := []errorTestCase{
+		{`Object.new.tap`, "InternalError: Can't yield without a block", 1},
+	}
+
+	for i, tt := range testsFail {
+		v := initTestVM()
+		evaluated := v.testEval(t, tt.input, getFilename())
+		checkErrorMsg(t, i, evaluated, tt.expected)
+		v.checkCFP(t, i, tt.expectedCFP)
+		v.checkSP(t, i, 1)
+	}
+}
+