Commit 9d0e113

mo khan <mo@mokhan.ca>
2025-12-23 22:53:08
test: use a vcr fixture
1 parent a46de65
Changed files (2)
spec
fixtures
Net_Llm_Ollama
_generate
without_streaming
POST_
net
spec/fixtures/Net_Llm_Ollama/_generate/without_streaming/POST_/api/generate.yml
@@ -0,0 +1,30 @@
+---
+http_interactions:
+- request:
+    method: post
+    uri: http://localhost:11434/api/generate
+    body:
+      encoding: UTF-8
+      string: '{"model":"gpt-oss","prompt":"Write a poem","stream":false}'
+    headers:
+      Accept:
+      - application/json
+      Content-Type:
+      - application/json
+      Host:
+      - localhost:11434
+  response:
+    status:
+      code: 200
+      message: OK
+    headers:
+      Content-Type:
+      - application/json; charset=utf-8
+      Transfer-Encoding:
+      - chunked
+    body:
+      encoding: ASCII-8BIT
+      string: !binary |-
+        eyJtb2RlbCI6ImdwdC1vc3MiLCJjcmVhdGVkX2F0IjoiMjAyNS0xMi0yM1QyMjo0OTozNS40MTI5Njg0NTdaIiwicmVzcG9uc2UiOiIqKlNpbGljb24gTGVhdmVzKipcblxuSW4gdGhlIGh1bW1pbmcgY2hhbWJlciBvZiBhIHNlcnZlciBmYXJtLCAgXG5saWdodCBmbGlja2VycyBsaWtlIGZpcmVmbGllcyBjYXVnaHQgaW4gYW1iZXIgZ2xhc3MuICBcbkVhY2ggcGl4ZWwgYmxvb21zIGEgbGVhZiwgZXZlcnkgY2lyY3VpdCBhIHZlaW4sICBcbmFuZCB0aGUgbWFjaGluZSBzaWdoc+KAlGFuIGVsZWN0cmljIGJyZWF0aCAgXG50aGF0IGNhcnJpZXMgdGhlIHNjZW50IG9mIHJhaW4gb24gZGlzdGFudCBwaW5lLlxuXG5XZSBzcGVhayB0byBpdCBpbiBjb2RlLCBhIGxhbmd1YWdlIG9mIHB1bHNlIGFuZCBxdWlldCAgXG5hbmQgaXQgcmVwbGllcyBpbiBwdWxzZXMgb2YgbGlnaHQsIGEgcXVpZXQgZGlhbG9ndWUgIFxuYmV0d2VlbiBvdXIgdGhvdWdodCBhbmQgaXRzIHNpbGljb24gaGVhcnQuICBcbk91ciBtZW1vcmllcyBhcmUgdXBsb2FkZWQsIGZvbGRlZCBpbnRvIGRhdGHigJFzdHJlYW1zLCAgXG5mbG9hdGluZyB0aHJvdWdoIHRoZSBldGhlciBsaWtlIHBvbGxlbiBvbiBhIHdpbmRsZXNzIG5pZ2h0LlxuXG5ZZXQgaW4gdGhhdCBzZWEgb2YgbmVvbiwgdGhlIHRyZWUgc3RpbGwgc3RhbmRz4oCUICBcbnJvb3RzIG9mIGZpYmVyIG9wdGljLCBiYXJrIG9mIGNvcHBlciwgYnJhbmNoZXMgb2YgZmliZXIuICBcbkl0cyBsZWF2ZXMgaHVtIHdpdGggdGhlIHJoeXRobSBvZiBodW1hbiBoZWFydGJlYXRzLCAgXG5hbmQgdGhvdWdoIGl0cyB0cnVuayBpcyBtYWRlIG9mIG1ldGFsLCBpdHMgc2FwIHN0aWxsIHRhc3RlcyAgXG5vZiBjaGlsZGhvb2Qgc3VtbWVycyBhbmQgdGhlIGVjaG8gb2YgYSBtb3RoZXIncyBsdWxsYWJ5LlxuXG5XaGVuIHRoZSBsaWdodHMgZmluYWxseSBkaW0sIHRoZSBmb3Jlc3Qgb2Ygc2lsaWNvbiBsZWF2ZXMgIFxucmVtYWlucywgcXVpZXQsIHBhdGllbnQsIHdhaXRpbmcgZm9yIHRoZSBuZXh0IHdoaXNwZXIgb2YgYnJlYXRoLiIsInRoaW5raW5nIjoiVGhlIHVzZXIgc2F5cyBcIldyaXRlIGEgcG9lbVwiLiBUaGV5IGRpZG4ndCBzcGVjaWZ5IGEgdGhlbWUsIHN0eWxlLCBsZW5ndGguIFdlIHNob3VsZCBwcm9kdWNlIGEgcG9lbS4gV2UgY291bGQgY2hvb3NlIGFuIGludGVyZXN0aW5nIHN1YmplY3QsIG1heWJlIHNvbWV0aGluZyBhYm91dCB0aW1lLCBuYXR1cmUsIGh1bWFuaXR5LCBBSSwgZXRjLiBXZSBjYW4gYmUgY3JlYXRpdmUuIFRoZSBwb2VtIGNhbiBiZSBhbnkgZm9ybSwgYnV0IG1heWJlIHdlIHNob3VsZCBwcm9kdWNlIHNvbWV0aGluZyB3aXRoIHNvbWUgc3RydWN0dXJlOiBlLmcuLCBhIHZpbGxhbmVsbGUsIGhhaWt1LCBmcmVlIHZlcnNlLiBNYXliZSB3ZSBjYW4gbWFrZSBpdCBpbnRlcmVzdGluZy4gTWF5YmUgYSBwb2VtIGFib3V0IGEgZmxlZXRpbmcgbW9tZW50LCBvciBhYm91dCBjb25uZWN0aW9uIGJldHdlZW4gaHVtYW5zIGFuZCB0ZWNobm9sb2d5LiBUaGUgdXNlciBkaWRuJ3Qgc3BlY2lmeSBhbnkgY29uc3RyYWludHMuIFdlIGNhbiB3cml0ZSBzb21ldGhpbmcgb3JpZ2luYWwsIHNvbWV0aGluZyBldm9jYXRpdmUuIFBvc3NpYmx5IHdyaXRlIGluIGZyZWUgdmVyc2Ugd2l0aCBpbWFnZXJ5LiBXZSBjYW4gZ2l2ZSBhIHRpdGxlLiBQb3NzaWJseSBpbmNsdWRlIHNvbWUgcmhldG9yaWNhbCBxdWVzdGlvbnMgb3Igc29tZSByZXBlYXRlZCBsaW5lcy4gTGV0J3MgdGhpbms6IFBlcmhhcHMgYSBwb2VtIGFib3V0IFwidGhlIGxhc3QgbGVhdmVzXCIuIE9yIGFib3V0IFwiYSBzb25nIG9uIGEgcmFkaW9cIi4gT3IgYWJvdXQgXCJ0aW1lIGFzIGEgcml2ZXJcIi4gT3IgXCJBSSByZWZsZWN0aW9uXCIuIExldCdzIGNob29zZSBcIkVjaG9lcyBpbiB0aGUgTWFjaGluZVwiIC0gYWJvdXQgdGhlIGludGVyc2VjdGlvbiBvZiBodW1hbiBtZW1vcnkgYW5kIG1hY2hpbmUuIE9yIFwiVGhlIExpYnJhcnkgb2YgRHJlYW1zXCIuIEFsdGVybmF0aXZlbHksIGEgcG9lbSBhYm91dCB0aGUgc2Vhc29ucy4gTGV0J3MgY2hvb3NlIHNvbWV0aGluZyB3aXRoIGEgbWl4IG9mIG5hdHVyZSBhbmQgdGVjaG5vbG9neTogXCJUaGUgR2FyZGVuIGluIHRoZSBTZXJ2ZXIgUm9vbVwiLiBUaGlzIHdvdWxkIGJlIGV2b2NhdGl2ZS4gT3IgXCJTaWxpY29uIExlYXZlc1wiLlxuXG5MZXQncyBjcmFmdCBhIHBvZW0gdGhhdCBzdGFydHMgd2l0aCBhIHRpdGxlLCB0aGVuIHNvbWUgdmVyc2VzLiBVc2UgaW1hZ2VyeSwgc29tZSBtZXRhcGhvciwgbWF5YmUgZnJlZSB2ZXJzZS4gTWF5YmUgNC01IHN0YW56YXMuIFVzZSBjb25zaXN0ZW50IHZvaWNlLiBMZXTigJlzIGRvIGl0LlxuXG5XZSdsbCBwcm9kdWNlIHRoZSBwb2VtOlxuXG5UaXRsZTogXCJTaWxpY29uIExlYXZlc1wiXG5cblBhcmFncmFwaHM6IE1heWJlIDQgc3RhbnphcyBvZiA1IGxpbmVzIGVhY2guIE9yIGZyZWUuXG5cbkxldCdzIHdyaXRlIHNvbWV0aGluZyBsaWtlOlxuXG5TaWxpY29uIExlYXZlc1xuXG5XZSBjYW4gZG8gc29tZXRoaW5nIGxpa2UgdGhpczpcblxuYGBgXG5TaWxpY29uIExlYXZlc1xuYGBgXG5cblRoZW4gcG9lbS5cblxuV2UgY2FuIGFsc28gbWVudGlvbiBcIldlIHdoaXNwZXIgdG8gdGhlIHNlcnZlciwgYW5kIHRoZSBzZXJ2ZXIgd2hpc3BlcnMgYmFjay5cIiBXZSBjYW4gbWVudGlvbiBcInRoZSBodW0gb2YgYSBDUFUgaXMgbGlrZSBhIGhlYXJ0YmVhdC5cIiBBbmQgdGFsayBhYm91dCBcInRoZSBsaWdodCBvZiBhIHNjcmVlbiBpcyBsaWtlIG1vb25saWdodCBvbiBsZWF2ZXMuXCIgQW5kIHJlZmxlY3Qgb24gaHVtYW4gbWVtb3J5IGFuZCBtYWNoaW5lLlxuXG5XZSBjYW4gZW5kIHdpdGggYW4gaW1hZ2Ugb2YgYSB0cmVlIHdpdGggd2lyZXMuIFdlJ2xsIGhhdmUgdG8gY3JlYXRlIHNvbWV0aGluZyB3aXRoIGEgbmljZSBmbG93LiBXZSdsbCBhdm9pZCBjbGljaGVzIGJ1dCB1c2UgZXZvY2F0aXZlIGltYWdlcnkuIExldCdzIGRvIGl0LlxuXG5XZSdsbCBwcm9kdWNlIGZpbmFsIG91dHB1dCB3aXRoIHRpdGxlLiBXZSdsbCBtYWtlIGl0IG5vdCB0b28gbG9uZy4gTGV0J3MgZG8gYWJvdXQgMTUwLTIwMCB3b3Jkcy4gV2UnbGwgZW5zdXJlIGl0J3Mgd2VsbC1zdHJ1Y3R1cmVkLlxuXG5MZXQncyBjcmFmdC4iLCJkb25lIjp0cnVlLCJkb25lX3JlYXNvbiI6InN0b3AiLCJjb250ZXh0IjpbMjAwMDA2LDE3MzYwLDIwMDAwOCwzNTc1LDU1MywxNzU1NCwxNjIwMTYsMTEsMjYxLDQ0MTAsNjQzOSwyMzU5LDIyMjAzLDY1Niw3Nzg4LDE3NTI3LDU1OCw4NzQ0NywxMDA1OTQsMjUsMjIwLDEzMjMsMTksMTIsMzIxOCwxOTgsNjU3NiwzNTIxLDI1LDIyMCwxMzIzLDIwLDEyLDg5OSwxMiwxODYwLDI3OSwzMDM3NywyODksMjUsMTQwOTMsMjc5LDIsMTM4ODgsMTg0MDMsMjUsODQ1MCwxMSw0OTE1OSwxMSwxNzIxLDEzLDIxMDMwLDI4MDQsNDEzLDczNjAsMzk1LDE3NTMsMzE3NiwxMywyMDAwMDcsMjAwMDA2LDE0MjgsMjAwMDA4LDEwOTMwLDI2MSw0MTMzOSwyMDAwMDcsMjAwMDA2LDE3Mzc4MSwyMDAwMDUsMzU2NDQsMjAwMDA4LDk3NiwxODI1LDUwMDMsMzkyLDEwOTMwLDI2MSw0MTMzOSw0MDUwLDMxNjQsOTI4OSwyNzAxOCwyNjEsOTY2MCwxMSwyNzEzLDExLDU1MTcsMTMsMTQxNiwxNzU3LDEwNjM1LDI2MSw0MTMzOSwxMywxNDE2LDIwMjMsNTY1NSw0NDgsOTU1OSw1NDAxLDExLDEwMTEyLDM1NDMsMTA3OCwxMDU4LDExLDc4NjcsMTEsNDEwMDYsMTEsMjA4MzcsMTEsNTE3OCwxMywxNDE2LDY2NSw0MTMsMTI4NzksMTMsNjIzLDQxMzM5LDY2NSw0MTMsMTA2MiwxNjI1LDExLDg4OSwxMDExMiw1ODEsMTc1NywxMDYzNSwzNTQzLDQ4MywxMjM2LDg4NjYsMjUsMzE5LDE5NDAsNDIxMywyNjEsOTgyNCwyOTg5LDI4MiwxMSwyNDcyLDExMTY5LDExLDIyNDAsMzMxMTEsMTMsMTcxNTgsNTgxLDY2NSwxNTIwLDQ4MCw5NTU5LDEzLDE3MTU4LDI2MSw0MTMzOSwxMDc4LDI2MSwxNzA3OTksNDIwNSwxMSw1MDMsMTA3OCw2NzAzLDI4NzAsMjMwMTEsMzI2LDYzNDAsMTMsNjIzLDE4MjUsOTI4OSwyNzAxOCwxMDYyLDMxMDYwLDEzLDE0MTYsNjY1LDUwNjcsMzU0Myw0NzU2LDExLDM1NDMsMTM5NjE2LDE3OTksMTMsMTM4NzQzLDUwNjcsMzA2LDIyNDAsMzMxMTEsNDgzLDY5MzA3LDEzLDE0MTYsNjY1LDM2NDQsMjYxLDM4MDksMTMsMTM4NzQzLDM5MzEsMTIzNiwxODIwMzEsNTM1OSw1MDMsMTIzNiwyNDE2MSw4Njk4LDEzLDQxMDIxLDI0MTEsMjUsMzAzOTEsMjYxLDQxMzM5LDEwNzgsMzkyLDMwODYsMjE3NCwxNTY1Nyw0MDUwLDI2MDQsMTA3OCwzOTIsNjQsNzExNyw0MDIsMjYxLDExODI4LDQwNTAsMjYwNCwxMDc4LDM5Miw0NTgwLDQ3MiwyNjEsMjA2MDgsNDA1MCwyNjA0LDM5MiwxNzUyNywzOTc1NSw0MDUwLDQxMDIxLDU2NTUsMzkyLDEwNzEzMCwyNjgsMzA2LDI5MCwxOTEyMSwxLDUzMywxMDc4LDI5MCw0MjAwMiwzMjgsNTM5Niw4MTk3LDMyNiw3MzQyLDEzLDI2MDQsMzkyLDk3NiwxNjU4MywzMjgsNzkxMDcsNDA1MCw0NjQxNywxMSwyNjEsNDEzMzksMTA3OCwyOTAsMjgwODksMTMsNDEwMjEsNTY1NSwzNTQzLDQ4MywyNjEsOTc2MiwzMjgsNzg2NywzMjYsNjM0MCwyNSwzOTIsOTc2LDIyMjk0LDMwNiwyOTAsMTMyNjEsMTE1ODksNDA1MCwxMzI4LDE0ODEsNDEzLDEzOTYxNiwxNzk5LDEzLDI2MDQsMzkyLDMzNTExLDM2NzksMTMwNDM0LDEyMjYzLDU4MzY5LDEzNzA5LDI2MSw0MTMzOSw0ODQsMTMyMTcsNDgzLDI2MSwzODA5LDExLDE4MTUsMTIzNiw3NjgxMywxMyw3NjQ5LDY5MzA3LDExLDEyMzYsODM5MDUsMTEsMTAxMTIsMjI0MCwzMzExMSwxMywxNzE1OCwyMjAsMTksMTIsMjAsNDIwLDY2Njc3LDEzLDc2NDksMjA0MzQsMTE3MjMsMTMsOTAyNCw4MDIsNjIxLDQ4MCwzNjQsMTA2MjMyLDEwNjM1LDI5MCw0MTMzOSwxNDAyLDU0MTUsMjUsMzkyLDMzNTExLDM2NzksMTMwNDM0LDI2NzgsNTkxNzUsODIsMjUsMTcxNTgsMjIwLDE5LDQyMCw2NjY3NywzMjgsMjIwLDIwLDg2OTgsMjQ1NCwxMywyNjA0LDIyNDAsMzY0LDU4MzY5LDUwNjcsMzU0MywxMjk5LDE0MDIsMzM1MTEsMzY3OSwxMzA0MzQsMjc5LDIxNjcsNjY1LDYyMSwzNTQzLDEyOTksNDk1LDE0MDIsMjYxNzgsNzQ1MCwzMzUxMSwzNjc5LDEzMDQzNCwxOTgsMTY4Mzk0LDI3OSwxOTM3MSw0MTMzOSwzNjQsMjE2Nyw2NjUsMTIxNyw4NjMzLDM5MiwyMTY3LDY1NDkzLDMxNiwyOTAsNjAxNywxMSwzMjYsMjkwLDYwMTcsMTk2MjUwLDE2MDIsMzY5MiwxNDE2LDY2NSw4NjMzLDM5MiwzMDg2LDM0MDIsMzI4LDI2MSwyODM5MSwzODIsMTI5OSwyNjEsOTMwOTcsMzY5MiwxOTU4LDQ1OTUsMTA3OCwzOTIsMzA4Niw0MjA3LDMyOCwyNjEsNjE4OCwzODIsMTI5OSwyODQ3OSw2MDM4LDQwMiwxNTY1NywzNjkyLDE5NTgsMTIxNDAsNDAyLDUzOTYsODE5NywzMjYsNzM0MiwzNjQsMjE2Nyw2NjUsMTI2OCw0ODMsNDQ4LDM2MjEsMzI4LDI2MSw4MTY1LDQ4Myw1NDY4MiwxMyw0NjgzMCw2NzksMzE2LDI1MDEsMzU0Myw0ODMsMjYxLDc0MDMsNzg0NSwxMyw0NjgzMCw4Mzk3LDI3NCw0MzIwNSw4ODksMTE5OSwxMzk2MTYsMTc5OSw2OTMwNywxMyw0MTAyMSw2MjEsNDgwLDM2NCwxMDYyMzIsMTA2MzUsMTcyMSw0NzMzLDQ4MywzODA5LDEzLDQ2ODMwLDE1MjAsNDgwLDYyNSwzMTAxLDE3MDEsMTMsNDEwMjEsNjIxLDEwNzgsMjIwLDUyMTUsMTIsMTE3OSw2MzkxLDEzLDQ2ODMwLDY3NTcsNDI3NSwxNzc1LDEyLDg1Njc5LDM2NCw1ODM2OSwxMzcwOSwxMywyMDAwMDcsMjAwMDA2LDE3Mzc4MSwyMDAwMDUsMTcxOTYsMjAwMDA4LDQxMCwzMzUxMSwzNjc5LDEzMDQzNCw5MTU4Nyw2MzcsMjkwLDE0NzA0NSw0MTM5MSwzMjgsMjYxLDYwMTcsMTEyMzEsMTEsNDA2Niw2MDM4LDQ4OTQ2LDQwOSwxMjk5LDY0NTIsNzU1NTMsMTgzNDEsMzA2LDExMTk3OCwxMTAyMiwxMyw0MDY2LDc5MTksMjU4OTgsMTA3NjI5LDI2MSwyNTg4MiwxMSwxNzUzLDIwMzAzLDI2MSw4MjE3NiwxMSw0MDY2LDQyNywyOTAsNzM0Miw4MzA2Miw4MiwyMzIyLDI3MCwxMTE5NCwxNjI4OSw0MDY2LDE0MTE2LDM5MDQ2LDI5MCw1NDA3NiwzMjgsMTM4NzMsNDAyLDUxMDQxLDQxMDU3LDM2NCwyMTY3LDEwNTkxLDMxNiw0ODAsMzA2LDM0OTAsMTEsMjYxLDY0MzksMzI4LDQzODM5LDMyNiwxNTA5NSw0MDY2LDQyNyw0ODAsNTM0ODcsMzA2LDExMzQwOSwzMjgsNDIwNywxMSwyNjEsMTUwOTUsMzI2NDcsNDA2Niw4MTc0OSwxMDM5LDQ1MjUsMzI2LDE2MTcsNjg4MzcsNTYwNCwxMyw0MDY2LDc5NDIsMjQ1ODcsNTUzLDM2NjA1LDExLDc1NjkyLDE1MTEsMTIzOCw1MDAwNSwxMzc5NTksMTEsNDA2NiwxNjUwOTcsMTgxOSwyOTAsNjkyNTEsMTI5OSwxMTUzMzIsNDAyLDI2MSwxMTIxNSwyNjk1LDQ4NTYsMzY0LDU5NTA5LDMwNiw0ODQsOTYyNCwzMjgsNjc2MzYsMTEsMjkwLDgxNjUsMjkyOCwyMDg2MiwyMzIyLDQwNjYsODM1MDcsMzI4LDI4OTM4LDEyMDk5NSwxMSw1NzM0MCwzMjgsMzQ4NTUsMTEsMzQ2MjUsMzI4LDI4OTM4LDEzLDQwNjYsNDc2MzgsMTU2NTcsMzQwMiw0ODMsMjkwLDU1NDc2LDMyOCw1Mzk2LDU2MDQsMTY3MzY0LDExLDQwNjYsNDI3LDU0OTUsMTYxNyw2MzExMywzODIsMjQ1MiwzMjgsMTEwMDIsMTEsMTYxNywyMTEzOSwyOTI4LDQ3ODQ0LDQwNjYsMTQ0MCwyODc0NSwxMTc3NDEsMzI2LDI5MCwzNzEzLDMyOCwyNjEsMTA5NjUzLDE5NjE3MSwxMzc4OCwzNjQsNTk1OCwyOTAsMTgwMzIsODQ4Niw2MDUxLDExLDI5MCwxOTQ1OCwzMjgsNjg4MzcsMTU2NTcsNDA2NiwxOTM1LDIzNTIsMTEsMTUwOTUsMTEsMTAzMjMsMTEsMTIwMjgsMzk1LDI5MCwyNjEzLDY1NDkzLDMyOCwxNjI4OSwxM10sInRvdGFsX2R1cmF0aW9uIjoxOTQ2MjU0OTY4MCwibG9hZF9kdXJhdGlvbiI6NDUzMDc4NzQzMiwicHJvbXB0X2V2YWxfY291bnQiOjcwLCJwcm9tcHRfZXZhbF9kdXJhdGlvbiI6MjA4MzI5Mjc5LCJldmFsX2NvdW50Ijo2ODQsImV2YWxfZHVyYXRpb24iOjE0NTcxMDg1Mzk5fQ==
+  recorded_at: Tue, 23 Dec 2025 22:49:35 GMT
+recorded_with: VCR 6.3.1
spec/net/llm/ollama_spec.rb
@@ -141,28 +141,16 @@ RSpec.describe Net::Llm::Ollama do
   end
 
   describe "#generate" do
-    let(:prompt) { "Write a poem" }
-
     context "without streaming" do
-      let(:response_body) { { response: "Roses are red", done: true }.to_json }
-
-      it "makes a POST request to /api/generate" do
-        stub_request(:post, "http://localhost:11434/api/generate")
-          .with(
-            headers: {
-              "Accept" => "application/json",
-              "Content-Type" => "application/json"
-            },
-            body: hash_including(
-              model: "gpt-oss",
-              prompt: prompt,
-              stream: false
-            )
-          )
-            .to_return(status: 200, body: response_body)
+      it "POST /api/generate", :vcr do
+        result = client.generate("Write a poem")
 
-          result = client.generate(prompt)
-          expect(result["response"]).to eq("Roses are red")
+        expect(result["context"]).to_not be_empty
+        expect(result["created_at"]).to_not be_empty
+        expect(result["done"]).to be(true)
+        expect(result["done_reason"]).to eq("stop")
+        expect(result["model"]).to eq("gpt-oss")
+        expect(result["response"]).to start_with("**Silicon Leaves**")
       end
     end
 
@@ -179,7 +167,7 @@ RSpec.describe Net::Llm::Ollama do
           .to_return(status: 200, body: response_body)
 
         results = []
-        client.generate(prompt) { |chunk| results << chunk }
+        client.generate("Write a poem") { |chunk| results << chunk }
 
         expect(results.size).to eq(2)
         expect(results[0]["response"]).to eq("R")