how to stub a method that takes and argument - minitest

I'm kind of stuck (Maybe because this is my first time using Minitest) wherein I want to stub a method that takes an argument.
def self.bonsai_site_configuration(since=nil)
data = []
Site.all.reduce(data) do |data, site|
begin
data << JSON.parse(site.bonsai_desc)
rescue StandardError => exception
notify_exception(exception)
end
data
end
return {data: data`}
end
All I'm looking over here is that if test cases wherein if the site.bonsai_desc fails(i.e throw an exception). It should invoke notify_exception with given exception
Here how my minitest looks like
test "should return bonsai_site_configuration even on exception" do
site = Site.first
raises_exception = -> { raise 'boom' }
Site.stub(:all, [site]) do
site.stub(:bonsai_desc, raises_exception) do
Site.stub(:notify_exception) do
bonsai_information = Site.bonsai_site_configuration
assert_equal(0, bonsai_information[:data].count)
end
end
end
end
Upon running the minitest the test passes but I want to ensure that argument check is also included.
What am I suppose to do?

Related

Understanding cats effect `Cancelable `

I am trying to understand how cats effect Cancelable works. I have the following minimal app, based on the documentation
import java.util.concurrent.{Executors, ScheduledExecutorService}
import cats.effect._
import cats.implicits._
import scala.concurrent.duration._
object Main extends IOApp {
def delayedTick(d: FiniteDuration)
(implicit sc: ScheduledExecutorService): IO[Unit] = {
IO.cancelable { cb =>
val r = new Runnable {
def run() =
cb(Right(()))
}
val f = sc.schedule(r, d.length, d.unit)
// Returning the cancellation token needed to cancel
// the scheduling and release resources early
val mayInterruptIfRunning = false
IO(f.cancel(mayInterruptIfRunning)).void
}
}
override def run(args: List[String]): IO[ExitCode] = {
val scheduledExecutorService =
Executors.newSingleThreadScheduledExecutor()
for {
x <- delayedTick(1.second)(scheduledExecutorService)
_ <- IO(println(s"$x"))
} yield ExitCode.Success
}
}
When I run this:
❯ sbt run
[info] Loading global plugins from /Users/ethan/.sbt/1.0/plugins
[info] Loading settings for project stackoverflow-build from plugins.sbt ...
[info] Loading project definition from /Users/ethan/IdeaProjects/stackoverflow/project
[info] Loading settings for project stackoverflow from build.sbt ...
[info] Set current project to cats-effect-tutorial (in build file:/Users/ethan/IdeaProjects/stackoverflow/)
[info] Compiling 1 Scala source to /Users/ethan/IdeaProjects/stackoverflow/target/scala-2.12/classes ...
[info] running (fork) Main
[info] ()
The program just hangs at this point. I have many questions:
Why does the program hang instead of terminating after 1 second?
Why do we set mayInterruptIfRunning = false? Isn't the whole point of cancellation to interrupt a running task?
Is this the recommended way to define the ScheduledExecutorService? I did not see examples in the docs.
This program waits 1 second, and then returns () (then unexpectedly hangs). What if I wanted to return something else? For example, let's say I wanted to return a string, the result of some long-running computation. How would I extract that value from IO.cancelable? The difficulty, it seems, is that IO.cancelable returns the cancelation operation, not the return value of the process to be cancelled.
Pardon the long post but this is my build.sbt:
name := "cats-effect-tutorial"
version := "1.0"
fork := true
scalaVersion := "2.12.8"
libraryDependencies += "org.typelevel" %% "cats-effect" % "1.3.0" withSources() withJavadoc()
scalacOptions ++= Seq(
"-feature",
"-deprecation",
"-unchecked",
"-language:postfixOps",
"-language:higherKinds",
"-Ypartial-unification")
you need shutdown the ScheduledExecutorService, Try this
Resource.make(IO(Executors.newSingleThreadScheduledExecutor))(se => IO(se.shutdown())).use {
se =>
for {
x <- delayedTick(5.second)(se)
_ <- IO(println(s"$x"))
} yield ExitCode.Success
}
I was able to find an answer to these questions although there are still some things that I don't understand.
Why does the program hang instead of terminating after 1 second?
For some reason, Executors.newSingleThreadScheduledExecutor() causes things to hang. To fix the problem, I had to use Executors.newSingleThreadScheduledExecutor(new Thread(_)). It appears that the only difference is that the first version is equivalent to Executors.newSingleThreadScheduledExecutor(Executors.defaultThreadFactory()), although nothing in the docs makes it clear why this is the case.
Why do we set mayInterruptIfRunning = false? Isn't the whole point of cancellation to interrupt a running task?
I have to admit that I do not understand this entirely. Again, the docs were not especially clarifying on this point. Switching the flag to true does not seem to change the behavior at all, at least in the case of Ctrl-c interrupts.
Is this the recommended way to define the ScheduledExecutorService? I did not see examples in the docs.
Clearly not. The way that I came up with was loosely inspired by this snippet from the cats effect source code.
This program waits 1 second, and then returns () (then unexpectedly hangs). What if I wanted to return something else? For example, let's say I wanted to return a string, the result of some long-running computation. How would I extract that value from IO.cancelable? The difficulty, it seems, is that IO.cancelable returns the cancelation operation, not the return value of the process to be cancelled.
The IO.cancellable { ... } block returns IO[A] and the callback cb function has type Either[Throwable, A] => Unit. Logically this suggests that whatever is fed into the cb function is what the IO.cancellable expression will returned (wrapped in IO). So to return the string "hello" instead of (), we rewrite delayedTick:
def delayedTick(d: FiniteDuration)
(implicit sc: ScheduledExecutorService): IO[String] = { // Note IO[String] instead of IO[Unit]
implicit val processRunner: JVMProcessRunner[IO] = new JVMProcessRunner
IO.cancelable[String] { cb => // Note IO.cancelable[String] instead of IO[Unit]
val r = new Runnable {
def run() =
cb(Right("hello")) // Note "hello" instead of ()
}
val f: ScheduledFuture[_] = sc.schedule(r, d.length, d.unit)
IO(f.cancel(true))
}
}
You need explicitly terminate the executor at the end, as it is not managed by Scala or Cats runtime, it wouldn't exit by itself, that's why your App hands up instead of exit immediately.
mayInterruptIfRunning = false gracefully terminates a thread if it is running. You can set it as true to forcely kill it, but it is not recommanded.
You have many way to create a ScheduledExecutorService, it depends on need. For this case it doesn't matter, but the question 1.
You can return anything from the Cancelable IO by call cb(Right("put your stuff here")), the only thing blocks you to retrieve the return A is when your cancellation works. You wouldn't get anything if you stop it before it gets to the point. Try to return IO(f.cancel(mayInterruptIfRunning)).delayBy(FiniteDuration(2, TimeUnit.SECONDS)).void, you will get what you expected. Because 2 seconds > 1 second, your code gets enough time to run before it has been cancelled.

why would python3 recursive function return null

I have this function that when hitting a rate limit will call itself again. It should eventually succeed and return the working data. It works normally then rate limiting works as expected, and finally when the data goes back to normal I get:
TypeError: 'NoneType' object is not subscriptable
def grabPks(pageNum):
# cloudflare blocks bots...use scraper library to get around this or build your own logic to store and use a manually generated cloudflare session cookie... I don't care 😎
req = scraper.get("sumurl.com/"+str(pageNum)).content
if(req == b'Rate Limit Exceeded'):
print("adjust the rate limiting because they're blocking us :(")
manPenalty = napLength * 3
print("manually sleeping for {} seconds".format(manPenalty))
time.sleep(manPenalty)
print("okay let's try again... NOW SERVING {}".format(pageNum))
grabPks(pageNum)
else:
tree = html.fromstring(req)
pk = tree.xpath("/path/small/text()")
resCmpress = tree.xpath("path/a//text()")
resXtend = tree.xpath("[path/td[2]/small/a//text()")
balance = tree.xpath("path/font//text()")
return pk, resCmpress, resXtend, balance
I've tried to move the return to outside of the else scope but then it throws:
UnboundLocalError: local variable 'pk' referenced before assignment
Your top level grabPks doesnt return anything if it is rate limited.
Think about this:
Call grabPks()
You're rate limited so you go into the if statement and call grabPks() again.
This time it succeeds so grabPks() returns the value to the function above it.
The first function now falls out of the if statement, gets to the end of the function and returns nothing.
Try return grabPks(pageNum) instead inside your if block.
well okay... I needed to return grabPKs to make it play nice...:
def grabPks(pageNum):
# cloudflare blocks bots...use scraper library to get around this or build your own logic to store and use a manually generated cloudflare session cookie... I don't care 😎
req = scraper.get("sumurl.com/"+str(pageNum)).content
if(req == b'Rate Limit Exceeded'):
print("adjust the rate limiting because they're blocking us :(")
manPenalty = napLength * 3
print("manually sleeping for {} seconds".format(manPenalty))
time.sleep(manPenalty)
print("okay let's try again... NOW SERVING {}".format(pageNum))
return grabPks(pageNum)
else:
tree = html.fromstring(req)
pk = tree.xpath("/path/small/text()")
resCmpress = tree.xpath("path/a//text()")
resXtend = tree.xpath("[path/td[2]/small/a//text()")
balance = tree.xpath("path/font//text()")
return pk, resCmpress, resXtend, balance

AwesomeWM client created/removed callback

I am using awesome WM and I want to run a lua function after a client is created/deleted. Specifically, I want to change the name of a tag to the name of one of the clients that are on the tag.
I do this with a timer, but I think the best way to do this would be to register a callback function to awesomeWM that it will invoke when a client is created/removed.
Are there some hooks/callbacks that I can implement to tell awesome to do this for me?
---------------------------------------------UPDATE----------------------------------------
I tried using the signals, but i cant find the correct signal that changes calls my function AFTER the window is created and attached to the tag. I tried this with manage/unmanage tagged/untagged, and tag.new, etc, but no one helps.
Any ideas?
here is the code:
override_name_char = "<"
function tag_name_from_client(c)
if string.match(c.name, "Mozilla Firefox") then
return "Firefox"
end
if string.match(c.name, "Sublime Text") then
return "Sublime"
end
if string.match(c.name, "/bin/bash") then
return "Shell"
end
return ""
end
function tag_name_from_tag(tag)
if tag.name:match(override_name_char) then
return tag.name
end
for _, c in pairs(tag:clients()) do
return " "..tostring(awful.tag.getidx(tag)).." "..tag_name_from_client(c)
end
return tostring(awful.tag.getidx(tag))
end
function refresh_tag_name()
for s = 1, screen.count() do
for _,tag in pairs(awful.tag.gettags(s)) do
tag.name = tag_name_from_tag(tag)
end
end
end
client.connect_signal("tagged", refresh_tag_name)
client.connect_signal("untagged", refresh_tag_name)
--tag_timer = timer({timeout = 0.5})
--tag_timer:connect_signal("timeout", function()
--refresh_tag_name()
--end)
--tag_timer:start()
Thanks in advance for any help regarding this.
One of possible ways for v3.5.6, try this in your rc.lua
local naughty = require("naughty")
client.connect_signal("manage", function (c)
--filter client by class name
if c.class:lower() == "gedit" then
-- do things on client start
naughty.notify({text = "Gedit launched!"})
-- add exit signal for this client
c:connect_signal("unmanage", function() naughty.notify({text = "Gedit closed!"}) end)
end
end)
"A new client is created" is the manage signal.
"A new client was destroyed" is the unmanage signal.
So, something like the following (untested):
local function choose_name_for_tag(t)
for _, c in ipairs(t:clients() do
return "has client: " .. tostring(c.name or "unknown")
end
return "has no clients"
end
local function update_state()
for _, t in pairs(root.tags()) do
t.name = choose_name_for_tag(t)
end
end
client.connect_signal("manage", update_state)
client.connect_signal("unmanage", update_state)
tag.connect_signal("tagged", function(t)
t.name = choose_name_for_tag(t)
end)
tag.connect_signal("untagged", function(t)
t.name = choose_name_for_tag(t)
end)

How do you use lua in redis to return usable result to nodejs

one of the module i am implementing for my mobile app api is to get all outstanding notifications from , submitting username.
i used a list called username:notifications to store all outstanding id of notifications.
For example, in my test case, ['9','10',11'] is the result after calling for
lrange username:notifications 0 -1
So i wrote a lua script to get lrange and for each result,
hgetall notification:id
And for some reason, lua could not send the table, result to nodejs in usable state. Wondering if anyone
has a solution for multiple hgetall requests and returning them to nodejs
Here goes the rest of the code:
-- #KEYS: "username"
-- #ARGV: username
-- gets all fields from a hash as a dictionary
local hgetall = function (key)
local bulk = redis.call('HGETALL', key)
local result = {}
local nextkey
for i, v in ipairs(bulk) do
if i % 2 == 1 then
nextkey = v
else
result[nextkey] = v
end
end
end
local result = {}
local fields = redis.call('LRANGE' , ARGV[1], 0,-1)
for i, field in ipairs(fields) do
result[field] = hgetall('notification:'..field)
end
return result
You cannot return a "dictionary" from a Lua script, it is not a valid Redis type (see here).
What you can do is something like this:
local result = {}
local fields = redis.call('LRANGE' , ARGV[1], 0, -1)
for i=1,#fields do
local t = hgetall('notification:' .. fields[i])
result[#result+1] = fields[i]
result[#result+1] = #t/2
for j=1,#t do
result[#result+1] = t[j]
end
end
return result
The result is a simple list with this format:
[ field_1, nb_pairs_1, pairs..., field_2, nb_pairs_2, ... ]
You will need to decode it in your Node program.
EDIT: there is another solution, probably simpler in your case: encode the result in JSON and return it as a string.
Just replace the last line of your code by:
return cjson.encode(result)
and decode from JSON in your Node code.

Frank Cucumber Test Case Hangs When Using "when I wait" Test

I'm using frank-cucumber to test my iOS app and have run into some problems when my test is of the following form
When I wait to see "OpenButton"
If a UIView with the accessibility label "OpenButton" never shows up, instead of timing out and reporting an error on the test after WAIT_TIMEOUT is hit, cucumber just hangs.
Since I don't see WAIT_TIMEOUT even used in the core_frank_steps.rb I wonder if this is the reason why any test case of the form "When I wait.." will just hang.
Note: core_frank_steps.rb can be found here
# Polls every 0.1s , returns true when element is present
# #param selector [String] Frankly selector e.g. view marked:''
# #param timeout [Int] seconds to wait
def wait_for_element(selector, timeout=10)
#the return value of the yield expression isn't working, so we use a closure
res = nil
wait_until(:timeout => timeout, :message => "Waited for element #{selector} to exist") {
res = element_exists(selector)
}
res
end
The above function helped us get around some of these wait scenarios.

Resources