Yii - CHttpRequesterror while functional unittesting in module - php

When I'm trying to execute a functional unittest of a module within my Yii code, I keep receiving the following error:
CException: CHttpRequest is unable to determine the request URI.
At first, I though it was because it couldn't find the module. However, If I change the url to a wrong one, I get a correct error,s tating it couldn't find the view.
This is how my testing code looks like
public function testViewControllerModule()
{
ob_start();
Yii::app()->runController('module/controller/view');
}
Any ideas on what I might be missing?

bool.devs answer works so far.
This blog post explains the origin of the exception pretty well:
http://mattmccormick.ca/2012/09/14/unit-testing-url-routes-in-yii-framework/
In my case, I generalized the solution and have set the following variables in /www/protected/tests/bootstrap.php:
...
$_SERVER['SCRIPT_FILENAME'] = 'index-test.php';
$_SERVER['SCRIPT_NAME'] = '/index-test.php';
$_SERVER['REQUEST_URI'] = 'index-test.php';
Yii::createWebApplication($config);
Consider using 'index-test.php' instead of 'index.php' because it contains the config 'test.php' which is responsible for fixtures and maybe other test relevated configurations.
If someone has better suggestions feel free to comment :)
Kind regards

I think it's because you haven't set any server variables, i.e $_SERVER and you might be doing something like this in your controller:
Yii::app()->request ....
So before you run your test, make sure you use a fixture for the server variables also. I think this should suffice for now:
$_SERVER=array(
'REQUEST_URI'=>'index.php', // the other fields should follow
);
However to run functional tests i would recommend using SeleniumRC, you won't have to do these workarounds then, and can simulate user clicks also, i think.
Read the initial guide to Functional Testing , read the selenium rc phpunit guide, and also the CWebTestCase documentation.
Notes: You might still have to use fixtures for some variables, and i don't have much experience in testing(which is bad), so i'm not very sure if i am completely correct about selenium.

Related

PHPUnit get good feedback from the test

this question for me is to found a way to improve my test. When i test my code, usually I use this code:
$this->assertContains('textExample', $client->getResponse()->getContent());
when the test get OK all is right, but when the test fail the feedback from phpunit is so heavy, because php unit echo to terminal all the page into have search the textExample.
I would filter $client->getResponse()->getContent()) and search textExample in the precise part of site where i search it (div, h2...) and not have that heavy feedback form phpunit.
I hope I was clear, if not i'll try to re-explain.
Why don't you use either tearDwon() or onNotSuccessfulTest() methods. This way you could handle the error and filter if you need.
For instance you could try something like this to start:
public function onNotSuccessfulTest($e) {
// inspect $e to get the information you need, for ie:
print_r(get_class_methods($e)); die();
parent::onNotSuccessfulTest($e);
}
Check here for more information.

Find double defined functions in PHP

I work in a php project with multiple independent developers and recently we had case where a function getmicrotime() was twice defined.
all worked fine, because they were defined in different files that were not both included in a single call ... until some refactory.
in the standardcase php would just output a fatal error, but here the output was blocked. (because a thirdparty website called a website ...) so we did not get the output, just the information that nothing worked anymore.
To the point:
Is there any method, external script, etc to check if functions with the same name are defined twice in the project?
i thought about reg. expr search, but ofcourse class methods can have the same name like a::meth1 and b:meth1 .... so its not that easy.
i am talking about a project with ~100.000 lines of ugly code ... so manual checking is not possible
Thanks in advance.
Consider static code analysis. I would suggest Sonar + PHP plugin: http://docs.codehaus.org/display/SONAR/PHP+Plugin
Here is the life example how it works:
http://nemo.sonarqube.org/dashboard/index/net.php.pear.phpcodesniffer
You can always write a simple script (i.e. perl or python) which will find all duplicates. The algorithm would be simple...

Using Kohana in File outside Kohana

Here's the situation:
I have a catch-all on my domain email (so *#domain.com) redirecting to a piping script located at /home/domain/scripts/piper.php. This piper script is not within the Kohana ORM, but all of my other files are. I want to try to use Kohana inside this piper.php file.
I have tried (unsuccessfully) all of the following:
Including Kohana
I couldn't figure out what needed to be included, and more importantly how to override the url variable that Kohana uses to determine the right controller. Also, this is a catch-all piper, so it isn't using HTTP (to my knowledge), so much as executing a command.
Piping
I tried piping to the following:
/home/domain/public_html/index.php --uri="piper"
But cPanel makes this impossible, as you can only specify the destination script, and not the proper flags and such (unless I am missing something).
PHP exec()
I tried using the following line:
exec("php /home/domain/public_html/index.php --uri=\"/piper\"")
I was hoping that the stdin data would be maintained across the exec() command, but I could never get it to recognize the uri command, though I can run this on my localhost and it works just fine.
I was using http://www.coderelic.com/2011/10/creating-cron-jobs-in-kohana-3-x-is-a-piece-of-cake/ as a reference, but can't get anything to work.
I'm happy with either one of these solutions such that I can see an incoming email, parse it, then send emails based on the parameters.
Let me know if you need more information! I'm le stumped.
/home/domain/public_html/index.php --uri="piper" would be a valid way to do it. If your host sucks and doesn't let you specify that, put it into a bash script instead and reference that.
If you are on any recent version of kohana (3.2 or 3.3), a better way to do this would be to use Minion to run the command line task. This is what Minion was designed for.
All you need to do is to:
modify your piper.php script to be a valid PHP class;
place it in /application/classes/ folder;
Kohana will automatically load your class file (like include) during initialization.
Then you can use your piper class as usual class by $piper = new Piper; ....
UPD
You have to serve your emails trough Kohana.
Create controller, for example pipe (route it with /pipe URL):
public function action_pipe() {
$pipe = new Pipe; // This creates new Pipe object (your emails serving class)
$pipe->serve(); // Sserve emails within `serve()` method of Pipe class
}
Although admittedly, I'm not sure if these other answers are correct because I can't figure out how to reproduce the results.
What ended up working for my situation was to create a Controller_Piper class that is called in the /home/domain/scripts/piper.php. What I did was to copy the code from /home/domain/public_html/index.php and changed the following:
echo Request::factory("/piper")
->execute()
->send_headers(TRUE)
->body();
This loads the piper controller and executes everything very nicely. Not sure if it's the cleanest, but it does work.

JS Lexer to detect function calls

In order to localize strings used within my javascript, I want scan all my js files for such strings.
I am using a t() function to request string translations as follows:
t("Hello world");
or with dynamic portions:
t("Hello #user", {"#user": "d_inevitable"});
I want to detect all calls to the t() function and thus gather the strings contained in the first argument in a php "build" script, but skipping the following:
function foo(t) {
t("This is not the real t, do not localize this!");
}
function bar() {
var t = function(){}; //not the real t either...
}
function zoo() {
function t() {
//This also isn't the real t() function.
}
}
t("Translate this string, because this is the real t() in its global scope");
So the simple rule here is that the t function being invokes must be in global scope in order for the first argument to qualify as a translation string.
As a rule, dynamic runtime data as first argument is not allowed. The first argument to t() must always be a "constant" literal string.
I think php codesniffer will help me do it, however all the documentation I could find on it is about enforcing code standard (or detecting violations of it). I need lower level access to its js lexer.
My question is:
Would the php codesniffer's js lexer be able to help me solve my problem?
If so how do I access that lexer?
Are there any other php libs that could help me find the calls to t()?
Please do not suggest stand-alone regular expressions as they cannot possibly solve my problem in full.
Thank you in advance.
What you are describing is basically a coding standard. Certainly, ensuring strings are localised correctly is part of many project standards. So I think PHPCS is the right tool for you, but you will need to write a custom sniff for it because nothing exists to do exactly what you are after.
The best thing to do is probably clone the PHPCS Git repo from Github and then create a new directory under CodeSniffer/Standards to contain your custom sniff. Let's say you call it MyStandard. Make sure you create a Sniffs directory under it and then a subdirectory to house your new sniff. Take a look at the other standards in there to see how they work. You'll also find it easier to copy an existing ruleset.xml file from another standard and just change the cotent to suit you. if you don't want to include any other sniffs from anywhere (you just want to run this one check over your code) then you can just specify a name and description and leave the rest blank.
There is a basic tutorial that covers that.
Inside your sniff, you'll obviously want it to check JS files only, so make sure you specify that in the supportedTokenizers member var (also in the docs). This will ensure PHP and CSS files are always ignored.
When you get down to the actual checking, you'll have full low-level access to the parsed and tokenised content of your file. There are a lot of helper functions to check things like if the code inside other scopes, or to help you move backwards and forwards through the stack looking for bits of code you need.
TIP: run PHPCS using the -v option to see the token output on your file. It should help you see the structure more easily.
If you want to really do things properly, you can even create a nice unit test for your sniff to make sure it keeps running over time.
After all this, you'd check your code like this:
phpcs --standard=MyStandard /path/to/code
And you can use a lot of integrations that exist for PHPCS inside code editors.
You might decide to add a new more sniffs to the standard to check other things, which you can then do easily using your ruleset.xml file or by writing more custom sniff classes.
I hope that helps a bit. If you do decide to write your own sniff and need help, just let me know.

Conditional Component Loading in CakePHP

I'm using the DebugKit component in my project but I want to turn it on only on the staging server and have it not load when running from the production server.
I know I can turn it off with the debug config value but I want to keep that value at 1 for both servers.
I tried conditionally defining a contstant 'DEBUG_KIT' in bootstrap.php as either the component name (ie. 'DebugKit.Toolbar') or null. Then using that constant in the var $component definition at the top of the app_controller file. Well, Cake doesn't like having a null in the component array and barfs. Doesn't like an empty string either.
I feel like I'm missing something but can't quite see the forest for the trees. Thanks in advance!
I think the fundamental purpose of DebugKit is tied to being in debug mode, so I can understand that the tools don't provide the capacity to be disabled without also disabling debug mode.
That said, if you absolutely must do this, I think your best bet is to directly modify app/plugins/debugkit/controllers/components/toolbar.php, supplementing the existing debug-mode check in ToolbarComponent::initialize with a check against your constant.
(For what it's worth, I think you'd be better off turning debug-mode off on your production server, and using errors/warnings logged in /app/tmp/logs/error.log to identify issues that have slipped through your testing.)
I do something similar in my apps: I would use the __construct method to detect the presence DEBUG_KIT and add it to the $components array. This function gets called before the $components array is processed, so you can add/remove components transparently.
In your app_controller
function __construct(){
if(DEBUG_KIT){
$this->components[] = 'DebugKit.Toolbar'
}
parent::__construct();
}
If you have a _construct function in any or your individual controllers, remember to include parent::_construct(); otherwise you'll 'break the chain'.
Hope this helps
First, thanks to Adam Giles for a great answer. I hadn't thought to look at the __construct() callback. That just may be a better way than I found. And to Daniel Wright, point made sir. I'll probably change my production server to 0 debug soon and start watching the error logs.
I found my own answer shortly after posting this question. The DebugKit has an 'autoRun' parameter that will turn it on and off. So, I first set a global constant in bootstrap.php like this:
define( 'IS_DEV', ($_SERVER['SERVER_NAME'] == 'staging.example.com') );
Then in app_controller.php, I use it to set the 'autoRun' parameter in the $components statement.
var $components = array( 'DebugKit.Toolbar'=>array('autoRun'=>IS_DEV) );
This seems to work pretty well so far.

Categories