I have recently been working on a coding standard and would like to use codesniffer to check my files according to this standard.
Since i am new to Codesniffer i figured i'd go test the standards first before creating my own standard.
I have however run into a problem with codesniffer and i am unsure wether this is a bug or something i am doing wrong.
I've had pear install code sniffer using the commandline command pear install CodeSniffer after that i tried using different standards on my test file:
<?php
public class Application_IndexController() {
DEFINE WEBSITE_URL = 'https://localhost/';
public $avast = '';
private $_ye = '';
protected $_swabs = '';
public setAvast($avast){
$this->avast = $avast;
}
private getYe(){
return $this->_ye;
}
protected changeProtected($_swabs){
if($_swabs && $this->swabs) {
$this->_swabs = $swabs;
} elseif($swabs) {
$this->_swabs = $swabs;
} else {
return null;
}
}
public iDontKnowWhatImDoing($harhar) {
Switch($harhar) {
case 1:
$yargh = "Avast ye "
. "swabs!";
echo $yargh;
break;
default:
$array = array(
"Sailor 1", "Sailor 2", "Sailor 3",
"Sailor 4", "Sailor 5", "Sailor 5"
);
break;
}
}
}
?>
Suffice to say i was in a rather silly mood while writting this file, but regardless it fullfills it's purpose.
I've run all of the standards on this file and only a few of them actually work, the other seem to return the same error all the time.
The 'generic', 'psr1' and 'psr2' standards work perfectly fine yet the 'phpcs', 'pear', 'mysource', 'zend' and 'squiz' standards all result in a single error:
$stackPtr is not a class member var
It seems rather odd that 5 out of 8 just don't work including phpcs's own standard.
Firstly, the reason you are getting that error message is because your file has parse errors. The class definition is not correct and the DEFINE WEBSITE_URL = 'https://localhost/'; is also not valid PHP code. All your function declarations are missing function after the visibility keyword as well.
The best way to check for parse errors it to run php -l /path/to/code (that's a lowercase L).
PHPCS doesn't actually parse your file like PHP does. Instead, it is a static code analyser, but it does get into situations where the code looks wrong and it is unable to continue. This is just one of those cases.
Secondly, the reason why some of the standards work and some don't is because all the standards have different checks they are performing. Many of the standards share these checks. In this particular case, some of the standards have checks for variable names and they failed because of the incorrect function declarations. They can't really figure out why they failed because they are too far into the file (121 tokens) but they know something went wrong. I know the error message isn't very helpful, but it's enough to let you know something bad happened and there is a problem with the file. In this case, the parse errors.
So in summary: if you fix the parse errors, all the PHP_CodeSniffer standards will run on your code.
Going forward, it's always useful to check for parse errors in your code using the php -l command or by including that into a build script (if you use continuous integration) before the PHPCS checks.
In case it helps, here is your code with the parse errors fixed:
<?php
define('WEBSITE_URL', 'https://localhost/');
class Application_IndexController {
public $avast = '';
private $_ye = '';
protected $_swabs = '';
public function setAvast($avast){
$this->avast = $avast;
}
private function getYe(){
return $this->_ye;
}
protected function changeProtected($_swabs){
if($_swabs && $this->swabs) {
$this->_swabs = $swabs;
} elseif($swabs) {
$this->_swabs = $swabs;
} else {
return null;
}
}
public function iDontKnowWhatImDoing($harhar) {
Switch($harhar) {
case 1:
$yargh = "Avast ye "
. "swabs!";
echo $yargh;
break;
default:
$array = array(
"Sailor 1", "Sailor 2", "Sailor 3",
"Sailor 4", "Sailor 5", "Sailor 5"
);
break;
}
}
}
?>
Related
I am very new to php and phpunit test cases. I am trying to write a testcase to save the values into database using $_POST in test case. When I execute the test case, POST is returning null values. Please help how to use $_POST variable in php unit testing.
TEST CLASS-
public function setUp() {
$this->resetInstance();
$this->CI->load->model('save_data_model');
$this->obj = $this->CI->save_data_model;
}
public function test_SaveData()
{
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = array('value1'=>'10','value2'=>'100');
$actual = $this->obj->SaveData('1');
$this->assertNotNull($actual);
}
}
MODEL -
public function SaveData($id)
{
$sql['value1'] = $_POST['js_data']['input_value1'];
$sql['value2'] = $_POST['js_data']['input_value1'];
$sql['id'] = $id;
if(!empty($id))
{
$this->db->where('id',$id);
if($this->db->update('table_name',$sql))
{
return 'Updated';
}
else
{
return 'Not Updated';
}
}
}
Severity: NoticeMessage: Undefined index: js_dataFilename in SaveData.php
Database error: A Database Error Occurred
NULL VALUE FOR value1
UPDATE `table_name` SET `value1` = NULL, `value2` = NULL
WHERE `id` = '1'
I see you are a phpunit/tests newbie. That's a good thing.
You are setting $_POST['value1'] but you intend to retrieve $_POST['js_data']['input_value1'] in your model.
But, besides that, I can give you a few advices:
1) don't use $_POST in your models
2) declare public variables for the attributes of your models (such as public $value1; public $id;...)
3) then, at your test you should set: $this->obj->value1 = 'xxxx'; .....
4) afterwards check your output with assertions. SaveData will return a string in the function you wrote. Always. So you should try assertEquals instead
5) you could have assertNotNull as a secondary assertion as your code can change. Test what your code should and what it should not do is a good practice.
BTW, you should try to learn more on what a model stands for. Keep improving.
Is it possible ( of course it is) and how to customize the test name displayed in the report?
For example, I have a login test that run 4 times ( 4 different browsers) but reported test name is always login.
I'd like to attach the browser at the end , to see something like login_FF,login_IE,.....
Any idea?
I use testNG!
TestNG does provide options to customize the reporting, refer their site directly. But it does involve pretty good amount of effort........
If you test extends ITest you can set it there. Here is an example I'm currently using:
private final ThreadLocal<String> testName = new ThreadLocal<>();
...
#BeforeMethod(alwaysRun = true)
public void prepare(Method method, Object[] testData) {
if (testData == null || testData.length == 0) {
testName.set(String.format("%s.%s", getClass().getSimpleName(), method.getName()));
} else {
testName.set(
String.format(
"%s.%s %s", getClass().getSimpleName(), method.getName(), Arrays.toString(testData)));
}
}
We have a symfony 2 console command app. Inside a command (extending \Symfony\Component\Console\Command\Command) we call another command.
Code:
$this->getApplication()->run(new StringInput('cache:flush'), new NullOutput());
This was working fine until the update to the recent Symfony version
But now I hit the exception in the following Symfony function (\Symfony\Component\Console\Input\ArgvInput::parseArgument())
private function parseArgument($token)
{
$c = count($this->arguments); ## $c is 0 !
// if input is expecting another argument, add it
if ($this->definition->hasArgument($c)) {
$arg = $this->definition->getArgument($c);
$this->arguments[$arg->getName()] = $arg->isArray()? array($token) : $token;
// if last argument isArray(), append token to last argument
} elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
$arg = $this->definition->getArgument($c - 1);
$this->arguments[$arg->getName()][] = $token;
// unexpected argument
} else {
throw new \RuntimeException('Too many arguments.'); ### this exception is thrown
}
}
Both of the commands (the original one dev:setup:run and the one we call cache:flush) do not need parameters.
References: https://github.com/netz98/n98-magerun/issues/90
This commit causes Symfony2 to not behave like expected, as you can see in the comments.
However, this change is reverted, but only in the Symfony2.2 branch (which is a mistake, I guess). You need to update your Console dependency to some 2.2.x version.
You can savely update to the 2.2.x version, because there are no BC breaks in the Console component (just some really cool features)
We are rying to use WF with multiple tracking participants which essentially listen to different queries - one for activity states, one for custom tracknig records which are a subclass of CustomTrackingRecord.
The problem is that we can use both TrackingParticipants indivisually, but not together - we never get our subclass from CustomTrackingRecord but A CustomTrackingRecord.
If I put bopth queries into one TrackingParticipant and then handle everythign in one, both work perfectly (which indicates teh error is not where we throw them).
The code in question for the combined one is:
public WorkflowServiceTrackingParticipant ()
{
this.TrackingProfile = new TrackingProfile()
{
ActivityDefinitionId = "*",
ImplementationVisibility = ImplementationVisibility.All,
Name = "WorkflowServiceTrackingProfile",
Queries = {
new CustomTrackingQuery() { Name = "*", ActivityName = "*" },
new ActivityStateQuery() {
States = {
ActivityStates.Canceled,
ActivityStates.Closed,
ActivityStates.Executing,
ActivityStates.Faulted
}
},
}
};
}
When using two TrackingParticipants we have two TrackingProfile (with different names) that each have one of the queries.
in the track method, when using both separate, the lines:
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
Console.WriteLine("*** ActivityTracking: " + record.GetType());
if (record is ActivityBasedTrackingRecord)
{
System.Diagnostics.Debugger.Break();
}
never result in the debugger hitting, when using only the one to track our CustomTrackingRecord subclass (ActivityBasedTrackingRecord) then it works.
Anyone else knows about this? For now we have combined both TrackingParticipants into one, but this has the bad side effect that we can not dynamically expand the logging possibilities, which we would love to. Is this a known issue with WWF somewhere?
Version used: 4.0 Sp1 Feature Update 1.
I guess I encounterad the exact same problem.
This problem occurs due to the restrictions of the extension mechanism. There can be only one instance per extension type per workflow instance (according to Microsoft's documentation). Interesting enough though, one can add multiple instances of the same type to one workflow's extensions which - in case of TrackingParticipant derivates - causes weird behavior, because only one of their tracking profiles is used for all participants of the respective type, but all their overrides of the Track method are getting invoked.
There is a (imho) ugly workaround to this: derive a new participant class from TrackingParticipant for each task (task1, task2, logging ...)
Regards,
Jacob
I think that this problem isn't caused by extension mechanism, since DerivedParticipant 1 and DerivedParticipant 2 are not the same type(WF internals just use polymorphism on the base class).
I was running on the same issue, my Derived1 was tracking records that weren't described in its profile.
Derived1.TrackingProfile.Name was "Foo" and Derived2.TrackingProfile.Name was null
I changed the name from null to "Bar" and it worked as expected.
Here is a WF internal reference code, describing how is the Profile selected
// System.Activities.Tracking.RuntimeTrackingProfile.RuntimeTrackingProfileCache
public RuntimeTrackingProfile GetRuntimeTrackingProfile(TrackingProfile profile, Activity rootElement)
{
RuntimeTrackingProfile runtimeTrackingProfile = null;
HybridCollection<RuntimeTrackingProfile> hybridCollection = null;
lock (this.cache)
{
if (!this.cache.TryGetValue(rootElement, out hybridCollection))
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection = new HybridCollection<RuntimeTrackingProfile>();
hybridCollection.Add(runtimeTrackingProfile);
this.cache.Add(rootElement, hybridCollection);
}
else
{
ReadOnlyCollection<RuntimeTrackingProfile> readOnlyCollection = hybridCollection.AsReadOnly();
foreach (RuntimeTrackingProfile current in readOnlyCollection)
{
if (string.CompareOrdinal(profile.Name, current.associatedProfile.Name) == 0 && string.CompareOrdinal(profile.ActivityDefinitionId, current.associatedProfile.ActivityDefinitionId) == 0)
{
runtimeTrackingProfile = current;
break;
}
}
if (runtimeTrackingProfile == null)
{
runtimeTrackingProfile = new RuntimeTrackingProfile(profile, rootElement);
hybridCollection.Add(runtimeTrackingProfile);
}
}
}
return runtimeTrackingProfile;
}
I'm currently trying to implement an automated bug reporter for a Flex application, and would like to return error messages to a server along with the function/line number that caused the error. Essentially, I'm trying to get the getStackTrace() information without going into debug mode, because most users of the app aren't likely to have the debug version of flash player.
My current method is using the UncaughtErrorEvent handler to catch errors that occur within the app, but the error message only returns the type of error that has occurred, and not the location (which means it's useless). I have tried implementing getStackTrace() myself using a function name-grabber such as
private function getFunctionName (callee:Function, parent:Object):String {
for each ( var m:XML in describeType(parent)..method) {
if ( this[m.#name] == callee) return m.#name;
}
return "private function!";
}
but that will only work because of arguments.callee, and so won't go through multiple levels of function calls (it would never get above my error event listener).
So! Anyone have any ideas on how to get informative error messages through the global
error event handler?
EDIT: There seems to be some misunderstanding. I'm explicitly avoiding getStackTrace() because it returns 'null' when not in debug mode. Any solution that uses this function is what I'm specifically trying to avoid.
Just noticed the part about "I don't want to use debug." Well, that's not an option, as the non-debug version of Flash does not have any concept of a stack trace at all. Sucks, don't it?
Not relevant but still cool.
The rest is just for with the debug player.
This is part of my personal debug class (strangely enough, it is added to every single project I work on). It returns a String which represents the index in the stack passed -- class and method name. Once you have those, line number is trivial.
/**
* Returns the function name of whatever called this function (and whatever called that)...
*/
public static function getCaller( index:int = 0 ):String
{
try
{
throw new Error('pass');
}
catch (e:Error)
{
var arr:Array = String(e.getStackTrace()).split("\t");
var value:String = arr[3 + index];
// This pattern matches a standard function.
var re:RegExp = /^at (.*?)\/(.*?)\(\)/ ;
var owner:Array = re.exec(value);
try
{
var cref:Array = owner[1].split('::');
return cref[ 1 ] + "." + owner[2];
}
catch( e:Error )
{
try
{
re = /^at (.*?)\(\)/; // constructor.
owner = re.exec(value);
var tmp:Array = owner[1].split('::');
var cName:String = tmp.join('.');
return cName;
}
catch( error:Error )
{
}
}
}
return "No caller could be found.";
}
As a side note: this is not set up properly to handle an event model -- sometimes events present themselves as either not having callers or as some very weird alternate syntax.
You don't have to throw an error to get the stack trace.
var myError:Error = new Error();
var theStack:String = myError.getStackTrace();
good reference on the Error class
[EDIT]
Nope after reading my own reference getStackTrace() is only available in debug versions of the flash player.
So it looks like you are stuck with what you are doing now.