Linux_Kerio has quit [Quit: Konversation terminated!]
Linux_Kerio has joined #ruby
gr33n7007h has joined #ruby
nona has quit [Read error: Connection reset by peer]
gr33n7007h has quit [Ping timeout: 252 seconds]
gr33n7007h has joined #ruby
RDMengineer has quit [Remote host closed the connection]
taupiqueur_shiny has joined #ruby
TomyWork has joined #ruby
TomyWork has quit [Ping timeout: 252 seconds]
TomyWork has joined #ruby
grenierm has quit [Ping timeout: 245 seconds]
infinityfye has joined #ruby
konsolebox has quit [Quit: Leaving]
nona has joined #ruby
<nona>
hi all
<gr33n7007h>
o/
<nona>
what's the MiniTest-esque way of doing `allow(String).to receive(:to_mouse).and_return(cheese)`?
Rounin has quit [Remote host closed the connection]
<adam12>
nona: minitest has a stub method that could work, but most people bring in mocha.
<adam12>
nona: I don't personally care for either. I might reach for mocktail in future projects
<nona>
adam12: you don't care for either ... meaning you feel like that sort of thing ought not to be done?
<adam12>
nona: Well, I've been personally trying to use mocks a lot less, but sometimes it's not completely avoidable.
<adam12>
nona: As far as minitest stub works, it's sufficient but fairly simple and has some weird edgecases around Ruby 3 keyword args. It's good in a pinch.
<nona>
ah ok ... i suspect i'm in one of those "sometimeses".
<adam12>
nona: Mocha has been around since mid-2000's and is solid. But it doesn't support Spies so I find it more often then not less than useful. It has a very rspec-like DSL similar to the one above.
* nona
will try and see
<nona>
thank you!
<adam12>
Mocktail is new and from Justin Searls. I tried it in one project but ran into a bug, but it looks like it's fixed, so I might try it again.
<adam12>
Oh, another thing I don't like about Mocha is it breaks the AAA pattern of tests. You don't manually assert on the mocks, so some tests might have no assertions, which is weird.
taupiqueur_shiny has quit [Remote host closed the connection]
<adam12>
I've been trying to model my code more akin to James shore's testing without mocks style (which overlaps a lot with the Eventide project).
taupiqueur_shiny has joined #ruby
<adam12>
In essence, create substitutes/null objects that you can configure their responses, and allow them to publish telemetry that you can listen to.
<nona>
hmm ok, so, "write tests the way you'd expect they should be written"
<adam12>
More like, how you'd expect to understand them
<adam12>
When the test concludes, I want to know that what I expected to happen, happened. Normally if this is at the beginning of the test the flow feels weird.
John_Ivan has quit [Read error: Connection reset by peer]
<adam12>
Wherever I use CommandRunner in a collaborator, I pass it the substitute instead, which allows me to configure the response and see what it's been called with.
<nona>
it looks cool but i'll resist the temptation to read it from start to end, and go down a different rabbit hole than the one i need to be going down right now :)
<adam12>
Haha. Yeah
<adam12>
Isn't software great...
John_Ivan has joined #ruby
<adam12>
I don't use "mocks" or "stubs" anywhere in this project.
<nona>
adam12: what i'm having to do right now is test the methods we have which use Auth0, but without connecting to their servers. i suspect this won't be possible without mocking.
<adam12>
nona: If it's not your Auth0 client, I normally wrap them with my own interface, then build a substitute around that.
<nona>
how do you mean, if it's not my client?
<adam12>
nona: And then I have one test class that compares the real implementation with the substitute, interfacing with the real Auth0 server.
<nona>
oh wow
<adam12>
nona: I mean, if you did `gem install auth0` or `bundle add auth0` in your repo, then just hooked into `Auth0.validate` or something, then I would wrap it.
<adam12>
And control the responses.
<adam12>
It's more upfront work
<nona>
unfortunately i didn't write the code. and the person who wrote it is gone now. and their implementation is very convoluted.
<nona>
but yeah `bundle add auth0` was done.
<adam12>
Yeah. Not wrapping external interfaces is usually what gets you _way_ down the line
<nona>
man, mocktail does look much nicer and easier than any of the others i've seen, including what you'd do with rspec
<adam12>
Because you don't control the boundary, you're prone to whatever churn the library might invoke, and those changes could cause "shotgun surgery" inside your codebase, depending on how prolific the dependency is.
<nona>
adam12: i don't understand "getting down the line"
<adam12>
Yeah. Mocktail (from what little I used it) was pretty good
<adam12>
nona: Well, a lot of projects I work on are 10+ years old.
<adam12>
nona: Not everyone wants to maintain their Ruby gems for that long, or are prone to large rewrites.
<nona>
hmm i think my problem with "getting down the line" are more profound. as in, not being a native speaker of English profound :)
<nona>
problems*
<adam12>
Ooh, I see.
<adam12>
It's not now that these dependencies cause the issues. It's 10 years from now :)
<nona>
aaaaah
<nona>
right
dviola has joined #ruby
<nona>
wait, let me check with management if they're okay with me adding a separation layer in this
<nona>
alright, nope :-P
<adam12>
LOL
<adam12>
Oh well.
<adam12>
If you look at Mocktail docs, I think even they recommend wrapping third party libs
<nona>
I totally see why doing that would make sense.
<nona>
Like, I WANT to do it.
<nona>
Alas, if I did it, I'd die from being shot with a barrage of NerfGun rockets.
<nona>
adam12: in the actual project, i can't use Mocktail (yet). We'll be stuck on Ruby 2.7 until at least next spring or so.
<nona>
Sad :(
<adam12>
:|
taupiqueur_shiny has quit [Remote host closed the connection]
TomyWork has quit [Remote host closed the connection]
nona has quit [Ping timeout: 255 seconds]
_ht has joined #ruby
<adam12>
One interesting side-effect of running gemdocs.org is I look at it periodically throughout the week to see how it's going with gems, and sometimes come across some interesting ones.
<ox1eef_>
I use a notion doc for that. GitHub issues are too formal.
nona has quit [Ping timeout: 245 seconds]
nona has joined #ruby
nona has quit [Ping timeout: 255 seconds]
gr33n7007h has quit [Ping timeout: 252 seconds]
nona has joined #ruby
gr33n7007h has joined #ruby
taupiqueur_shiny has quit [Remote host closed the connection]
<nona>
adam12: so now i did this thing where i wrote some tests, happily hacking away without checking in between, using a mix of the Minitest::Spec style and Mocha-based mocking. and it looks neat. and then I run it (explicitly saying `ruby -Ilib:test test/models/user_test.rb`) and it goes all "0 runs, 0 assertions, 0 failures, 0 errors, 0 skips" on me. did you ever have something like that?
<adam12>
nona: Nope.
<adam12>
nona: You're using spec-style `describe` and `it` inside user_test.rb?
<nona>
yes
<nona>
is that not what i'm supposed to be doing? because it's a model?
<adam12>
nona: Seems fine.
<adam12>
nona: What happens if you put a flunking test somewhere.
<ox1eef_>
Are you sure that works ? Try it { flunk }.
<nona>
same
<ox1eef_>
Or, subclass Minitest::Test if you want to use 'def test_foo; end'.
<ox1eef_>
It works for me.
<ox1eef_>
require 'minitest'
<ox1eef_>
require 'minitest/autorun'
<nona>
ox1eef_: i added a few puts. only the first two output anything.
<ox1eef_>
describe 'foo' do
<ox1eef_>
def test_flunks; flunk; end
<ox1eef_>
end
<nona>
perhaps because i'm stuck on ruby 2.7.8?
<ox1eef_>
Might be. I tried with 3.2.
<nona>
hmm
<nona>
not ruby's fault
<nona>
if i run JUST your code then it's fine
<nona>
once Rails's config/environment.rb is required, that's when it stops working. interesting.
<nona>
this app has pretty bad history and is full of code smell
<adam12>
Remove autorun line
<adam12>
I'm assuming it's handled automatically by ActiveSupport.
<nona>
doesn't make it worse. doesn't make it work, either :)
<nona>
huh ... `WEBMASTER_EMAIL = 'webmaster@domain.tld'.freeze` ... do people have any good reason for freezing a string being assigned to a constant in a configuration file loaded once on startup?
<ox1eef_>
Frozen string literals are a common default. Usually you'd achieve it with a magic comment though (# frozen_string_literal: true).
<ox1eef_>
It is done for performance, and for your own sanity. Something like a webmaster's email should not be modified at runtime. If it is, it's probably a mistake.
<nona>
ox1eef_: i know about the performance topic. but all uppercase letters means it's a constant anyways. what am i missing?
<leftylink>
strings are mutable.
<leftylink>
WEBMASTER_EMAIL.clear
<leftylink>
oops, you no longer have a webmaster email aymore
<leftylink>
that's you freeze
<leftylink>
that's why you freeze.
<nona>
woah!! didn't know about #clear on constants! not even a warning?!
<ox1eef_>
A constant is something that should not be reassigned, mutating the reference is something else.
* nona
feels cheated by Ruby
<nona>
how is FOO="bar" ; FOO.clear different from FOO="" and therefore _not_ a reassignment?
<ox1eef_>
FOO.clear doesn't create a new object.
<nona>
hmm. i still feel like a constant shouldn't allow itself to be cleared without causing a warning. it's called a _constant_ because it's not variable.
<ox1eef_>
The warning is there as long as you freeze the string.
<nona>
that's it. i'm putting that magic comment _every_where.
<nona>
also, riddle with minitest solved: it works fine until you wish to use the spec syntax. then it stops working. at least with this app.
<leftylink>
in the same vein, you should of course also freeze any arrays or hashes that you do not need to modify. there is no comment for that, so you have to call #freeze.
<nona>
why no comment for that?
<leftylink>
who knows
<nona>
and what about more advanced data types?
<nona>
oh great Matz, I call upon thee ... why hathst though forsaken thy principle of predictability?
<leftylink>
sure, freeze anything mutable that shouldn't be modified. I actually only restricted my initial statement because I thought that user-defined classes won't have a #freeze by default and/or it won't actually freeze, but upon quick inspection... they might actually, which is interesting
<ox1eef_>
For your own objects, you'd implement #freeze and #frozen?, then check @frozen anywhere you might mutate the object. Object#freeze is probably not enough.
helge has quit [Server closed connection]
helge has joined #ruby
<johnjaye>
ox1eef_: is the syntax for the attr_accessor just foo.frozen
<ox1eef_>
You'd probably want to implement #initialize_dup as well, where you set @frozen back to false.
<ox1eef_>
johnjaye: frozen? is a predicate, and freeze is the setter, that sets @frozen to true. You wouldn't need attr_accessor.
<nona>
what's a predicate?
<johnjaye>
ah ok. i was thinking the syntax to access an instance variable is just foo.bar
<johnjaye>
which is the same as a method
<johnjaye>
nona: it's from First order logic. basically a function returning true or false.
* nona
googles first order logic
<johnjaye>
ruby is very lisp in that it puts a ? on such functions often
<johnjaye>
and a ! on mutators as well. very elegant
<nona>
i know both
<nona>
and i like it
<nona>
it immediately lets you see things
<nona>
but lisp scares me
<nona>
"First-order logic uses quantified variables over non-logical objects, and allows the use of sentences that contain variables, so that rather than propositions such as "Socrates is a man", one can have expressions in the form "there exists x such that x is Socrates and x is a man", where "there exists" is a quantifier, while x is a variable." <--- this, too, scares me
<ox1eef_>
In Ruby a predicate method can be described as a method that ends in ?, and returns either a truthy or falsey value. Some would argue it should return strictly true or false but there's not complete agreement on that.
<leftylink>
what was a well-known example where a ? method doesn't return a boolean... I don't quite remember. I know defined? doesn't, but it's not a method so it doesn't fit the letter of the question (but I guess it fits the spirit which matters much much more?)