What is the purpose of passing "globals()" as web.py fvars? - web.py

web.application accepts an undocumented fvars argument to which the web.py tutorial passes globals() like so:
import web
class index:
def GET(self):
return "Hello, world!"
urls = (
'/', 'index'
)
if __name__ == "__main__":
app = web.application(urls, globals())
I've seen at least one application that passes locals(). What is this variable used for, and why would you want to pass it locals() or globals()?

It's used by application.handle() (which in turn calls application._delegate()) to convert the handler class from a string to the class object itself. Source code here.
For example, in your code snippet above, urls = ('/', 'index') is the URL-to-class-string mapping. So web.application needs your globals() dict to be able to look up the string 'index' and get the class itself.
I actually think this is a somewhat non-Pythonic design. Why not just pass in the class directly? I think web.py supports that approach too. However, I believe the classes were done as strings so autoreload is simpler. The autoreload code uses fvars heavily.
Re locals(): at the module level, locals() doesn't really make sense, but it returns the same dictionary as globals(), which is why that would work.

Related

GWT-Jackson-APT fails on $wnd.window JSON web-worker code for encoding strings

Finally having gotten GWT-Jackson-APT processors working and properly generating code for my classes, the one remaining hiccup I have is that for some reason gwt-jackson-apt uses the window JSON stringify (& parse) function.
$wnd.window.JSON.stringify(STRING)
The problem is that due to this being on a web-worker, $wnd.window is not defined. Even though JSON.stringify() is available in web-worker, the result is that the code won't run correctly, even though if I modify it to be just JSON.stringify() before uploading it works pefectly.
Is there a clean way to redefine which of these functions gets used in this instance?
What is the best means of going about fixing this so that my web-worker code doesn't try to call the functions that are not available in their context.
The library right now uses the elemental2 version of JSON Global.JSON.stringify
and if we look at the implementation of the JSON in the Global class we will find that it is assigned to the window instance here :
#JsType(isNative = true, name = "window", namespace = JsPackage.GLOBAL)
public class Global {
public static JSONType JSON;
}
when this is used as Global.JSON.stringify(someJsonObject) from GWT java code when compile it will produce $wnd.window.JSON.stringify(someJsonObject) or something very similar.
in order to fix this we need to access the native JSON in a different way that does not link it the current window instance.
one solution to this is to use JsInterop to interface directly with the JSON, something like this
#JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class JSON {
public native static String stringify(Object jsonObj);
}
with this implementation we can use the JSON without the window prefix and when we use it in java like this JSON.stringify(someJsonObject) and notice how we no longer use the one from Global we end up with a generated Js that looks like this $wnd.JSON.stringify(someJsonObject)
i run a small test and implemented this JSON in the jackson-apt lib and switched to use the new implementation instead of using Global.JSON and all tests passed.
to me this looks like a good issue to be reported on the project repository. and i will apply the fix ASAP.

How can I fake a Class used insite SUT using FakeItEasy

Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.

PHPUnit mock a controller with reference parameter?

I have a class:
class Hello {
function doSomething(&$reference, $normalParameter) {
// do stuff...
}
}
Then I have a controller:
class myController {
function goNowAction() {
$hello = new Hello();
$var = new stdClass();
$var2 = new stdClass();
$bla = $hello->doSomething($var, $var2);
}
}
The "goNow" action I call using my tests like so:
$this->dispatch('/my/go-now');
I want to mock the "doSomething" method so it returns the word "GONOW!" as the result. How do I do that?
I've tried creating a mock
$mock = $this->getMock('Hello ', array('doSomething'));
And then adding the return:
$stub->expects($this->any())
->method('discoverRoute2')
->will($this->returnValue("GONOW!"));
But I'm stumped as to how to hook this up to the actual controller that I'm testing. What do I have to do to get it to actually call the mocked method?
You could create a mock for the reference, or if it is just a simple reference as your code shows, send a variable. Then the normal mock call may be called and tested.
$ReferenceVariable= 'empty';
$mock = $this->getMock('Hello ', array('doSomething'));
$stub->expects($this->any())
->method('discoverRoute2')
->will($this->returnValue("GONOW!"));
$this->assertEquals('GONOW!', $stub->doSomething($ReferenceVariable, 'TextParameter'));
Your example code does not explain your problem properly.
Your method allows two parameters, the first being passed as a reference. But you create two objects for the two parameters. Objects are ALWAYS passed as a reference, no matter what the declaration of the function says.
I would suggest not to declare a parameter to be passed as a reference unless there is a valid reason to do so. If you expect a parameter to be a certain object, add a typehint. If it must not be an object, try to avoid passing it as a reference variable (this will lead to confusing anyways, especially if you explicitly pass an object as a reference because everybody will try to figure out why you did it).
But your real question is this:
But I'm stumped as to how to hook this up to the actual controller that I'm testing. What do I have to do to get it to actually call the mocked method?
And the answer is: Don't create the object directly in the controller with new Hello. You have to pass the object that should get used into that controller. And this object is either the real thing, or the mock object in the test.
The way to achieve this is called "dependency injection" or "inversion of control". Explanaitions of what this means should be found with any search engine.
In short: Pass the object to be used into another object instead of creating it inside. You could use the constructor to accept the object as a parameter, or the method could allow for one additional parameter itself. You could also write a setter function that (optionally) gets called and replaces the usual default object with the new instance.

PlayFramework instantiate object in current request scope?

I am currently active PlayFramework learner who came from world of PHP.
For example I have a Head block object in my app, which should hold title, charset encoding, meta information, etc. Something similar to Magento blocks, but without XML declaration
package blocks.Page
object Head {
var title: String = "";
}
In Application.index() method I have
blocks.Page.Head.title
Ok(views.html.application.index());
And finally in html template
#import blocks.Page.Head
<title>#Head.title</title>
However, blocks.Page.Head object is defined for entire application scope, not for single request. This object is the same for each request.
What is the right way to do, what I am trying to do? I can create container with all blocks and instantiate it with each request, then just pass to all templates. But I have a feeling that this is wrong way.
Just use usual class instead of object and pass instance to template as parameter.
Like this:
package blocks.Page
case class Head(title: String = "")
Controller:
val head = Head("Blah")
Ok(views.html.application.index(head))
And template will looks like:
#(head: blocks.Page.Head)
...
<title>#head.title</title>
I know the feeling when coming from a request-oriented language like PHP :). However, consider application-wide access as a gift of a VM (in PHP we need to go the extra mile of using some bytecode and data caching tool like APC or eAccellerator).
I would probably create a blockManager class which gives you static access to blocks by name/tag/id from the template: Block.get("MyBlock"). Then you can define and later modify your caching / storing strategy (holding in memory vs. loading from storage) without affecting your templates.

Reference class in browser friendly and node.js friendly way

I've got the following code at the top of my CoffeeScript
program to reference a BinaryNode class from a BinaryTree
class.
Since I want to be able to use the BinaryTree class from
a node.js program or from the browser I have the following
if/else statement to reference the BinaryNode.
file: BinaryTree.coffee
isNodeJs = exports?
if isNodeJs
{BinaryNode} = require('./binary_node')
else
BinaryNode = window.BinaryNode
class BinaryTree
(code for BinaryTree goes here)
Somehow this if/else bugs me specially if I will need to
add it on a lot of different classes that make up the
program.
Are there any other better ways to perform this check?
(From my comment above)
The branching can be shortened to:
{BinaryNode} = require?("/.binary_node") or window
(provided you don't have a global require function somewhere in your browser code, of course)