can anyone tell me why this one line after the last break; stays uncovered and therefore the method get a coverage fo 0%!
private function isADateParameter($fieldName, $fieldValue){
if(!is_array($fieldValue)){
$this->addPayloadError('filter',320, $fieldName. 'is a date field and needs an array filter like {"gt":"2015-05-01"}');
return false;
}
foreach ($fieldValue as $criteria => $date){
$ar_date = explode('-', $date);
switch(false){
case in_array($criteria, ['gt', 'lt', 'gte', 'lte']):
$this->addPayloadError('filter',321, $fieldName. ' supports only constraints gt, lt, gte or lte');
break;
case preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date):
$this->addPayloadError('filter',322, $fieldName. ' supports only date in format YYYY-MM-DD');
break;
case checkdate($ar_date[1], $ar_date[2], $ar_date[0]):
$this->addPayloadError('filter',323, $date. ' is not a real date');
break;
} //uncovered red line in html report
}
if(isset($this->payloadErrors['filter']) && count($this->payloadErrors['filter']) > 0){
return false;
}
return true;
}
See this bug report, specifially the close note:
This is not a bug. In theory "$value" could be something else than 1, 2 or 3 and in that case the switch() would not leave due to one of the values. Xdebug can not make assumptions on what "doSomething()" returns an has no way to know that all that ever is returned than 1, 2 or 3. The last } of each function and method includes an implicit "return NULL;" - which PHP sees as executable code. Because there is a possible code path where the } is not hit, it is marked as "not executed".
In your case, you have three case statements, that I imagine you've written tests for, but there's a third, implied path that you may or may not be testing for - what to do if none of the three cases match?
tl;dr: Add a default case to the switch, and make sure your tests exercise it. Or don't and ignore that coverage line.
Related
I'm trying to use SequenceReader<T> in .Net Core Preview 8 to parse Guacamole Protocol network traffic.
The traffic might look as follows:
5.error,14.some text here,1.0;
This is a single error instruction. There are 3 fields:
OpCode = error
Reason = some text here
Status = 0 (see Status Codes)
The fields are comma delimited (semi-colon terminated), but they also have the length prefixed on each field. I presume that's so that you could parse something like:
5.error,24.some, text, with, commas,1.0;
To produce Reason = some, text, with, commas.
Simple comma delimited parsing is simple enough to do (with or without SequenceReader). However, to utilise the length I've tried the following:
public static bool TryGetNextElement(this ref SerializationContext context, out ReadOnlySequence<byte> element)
{
element = default;
var start = context.Reader.Position;
if (!context.Reader.TryReadTo(out ReadOnlySequence<byte> lengthSlice, Utf8Bytes.Period, advancePastDelimiter: true))
return false;
if (!lengthSlice.TryGetInt(out var length))
return false;
context.Reader.Advance(length);
element = context.Reader.Sequence.Slice(start, context.Reader.Position);
return true;
}
Based on my understanding of the initial proposal, this should work, though also could be simplified I think because some of the methods in the proposal make life a bit easier than that which is available in .Net Core Preview 8.
However, the problem with this code is that the SequenceReader does not seem to Advance as I would expect. It's Position and Consumed properties remain unchanged when advancing, so the element I slice at the end is always an empty sequence.
What do I need to do in order to parse this protocol correctly?
I'm guessing that .Reader here is a property; this is important because SequenceReader<T> is a mutable struct, but every time you access .SomeProperty you are working with an isolated copy of the reader. It is fine to hide it behind a property, but you'd need to make sure you work with a local and then push back when complete, i.e.
var reader = context.Reader;
var start = reader.Position;
if (!reader.TryReadTo(out ReadOnlySequence<byte> lengthSlice,
Utf8Bytes.Period, advancePastDelimiter: true))
return false;
if (!lengthSlice.TryGetInt(out var length))
return false;
reader.Advance(length);
element = reader.Sequence.Slice(start, reader.Position);
context.Reader = reader; // update position
return true;
Note that a nice feature of this is that in the failure cases (return false), you won't have changed the state yet, because you've only been mutating your local standalone clone.
You could also consider a ref-return property for .Reader.
I am trying to read and parse and excel and some unclear things come into play as usual for me.
Here is what i have:
while (true)
{
comVariantCell1 = cells.item(row, 1).value().variantType();
comVariantCell2 = cells.item(row, 2).value().variantType();
//if an empty cell is found, processing will stop and user will get an error message in order to solve the inconsistency.
if (comVariantCell1 != COMVariantType::VT_EMPTY && comVariantCell2 != COMVariantType::VT_EMPTY)
{
//both cells have values, check their types.
importedLine = conNull();
progress1.setText(strfmt("Importing row %1", row));
if (cells.item(row, 1).value().variantType() == COMVariantType::VT_BSTR)
{
importedLine += cells.item(row, 1).value().bStr();
}
else
{
importedLine += cells.item(row, 1).value().double();
}
importedLine += cells.item(row, 2).value().double();
importedLinesCollection += [importedLine]; //conIns(importedLinesCollection, row - 1, (importedLine));
row++;
}
else
{
info (strFmt("Empty cell found at line %1 - import will not continue and no records were saved.", row));
break;
}
}
Excel format:
Item number Transfer Qty
a100 50.5
a101 10
a102 25
This worked well to check if the cell type is string: COMVariantType::VT_BSTR
but what should i use to check for a real or integer value ?
I am pretty sure in this case, the quantity will be not contain real values but anyway, it could be useful in the future to make the difference between these two types.
I have to mention that, even if i have an int value and I use cells.item(row, 1).value().int() it won't work. I can't see why.
Why do i want to make the difference? Because if it's forbidden to have real values in the quantity column ( at least in my case ), i want to check that and give the user the opportunity to put a correct value in that place and maybe further investigate why that happened to be there.
Take a look on how it is done in \Classes\SysDataExcelCOM\readRow.
It is basically using switch to test the type. This is really boring!
Also take a look on ExcelIO, a class I made some years ago. It reads Excel and returns each row as a container. This is a more high-level approach.
As a last resort you could save the Excel as a tab separated file. Then use TextIO to read the content. This will be at least 10 times faster than using Excel!
I am using papaya to view DICOM images. http://ric.uthscsa.edu/mango/papaya.html
I wanted to know how can I move to the next slice using the keyboard keys.
Since all the command is embedded on the javascript file, is there a specific function I should be looking for ?
Please help.
See the incrementAxial(), incrementCoronal(), and incrementSagittal() functions in viewer.js:
papaya.viewer.Viewer.prototype.incrementAxial
papaya.viewer.Viewer.prototype.incrementCoronal
papaya.viewer.Viewer.prototype.incrementSagittal
They take one argument, a boolean to indicate whether to increment (true) or decrement (false).
In order to know which one to increment, you need to know which slice direction is the main slice. See below for an example of how that it is handled:
if (this.mainImage.sliceDirection === papaya.viewer.ScreenSlice.DIRECTION_AXIAL) {
this.incrementAxial(false);
} else if (this.mainImage.sliceDirection === papaya.viewer.ScreenSlice.DIRECTION_CORONAL) {
this.incrementCoronal(false);
} else if (this.mainImage.sliceDirection === papaya.viewer.ScreenSlice.DIRECTION_SAGITTAL) {
this.incrementSagittal(true);
}
EDIT: I accidentally misrepresented the problem when trying to pare-down the example code. A key part of my code is that I am attempting to sort the array after adding elements to it. The hang appears on sort, not insert. The following abstracted code will consistently hang:
<?=
local('a' = array)
#a->insert('test1' = map('a'='1'))
#a->insert('test2' = map('b'='2')) // comment-out to make work
#a->sort
#a
?>
I have a result set for which I want to insert a pair of values into an array for each unique key, as follows:
resultset(2) => {
records => {
if(!$logTypeClasses->contains(field('logTypeClass'))) => {
local(i) = pair(field('logTypeClass'), map('title' = field('logType'), 'class' = field('logTypeClass')))
log_critical(#i)
$logTypeClasses->insert(#i) // Lasso hangs on this line, will return if commented-out
}
}
}
Strangely, I cannot insert the #i local variable into thread variable without Lasso hanging. I never receive an error, and the page never returns. It just hangs indefinitely.
I do see the pairs logged correctly, which leads me to believe that the pair-generating syntax is correct.
I can make the code work as long as the value side of the pair is not a map with values. In other words, it works when the value side of the pair is a string, or even an empty map. As soon as I add key=value parameters to the map, it fails.
I must be missing something obvious. Any pointers? Thanks in advance for your time and consideration.
I can verify the bug with the basic code you sent with sorting. The question does arise how exactly one sorts pairs. I'm betting you want them sorted by the first element in the pair, but I could also see the claim that they should be sorted by last element in the pair (by values instead of by keys)
One thing that might work better is to keep it as a map of maps. If you need the sorted data for some reason, you could do map->keys->asArray->sort
Ex:
local(data) = map('test1' = map('a'=2,'b'=3))
#data->insert('test2' = map('c'=33, 'd'=42))
local(keys) = #data->keys->asArray
#keys->sort
#keys
Even better, if you're going to just iterate through a sorted set, you can just use a query expression:
local(data) = map('test1' = map('a'=2,'b'=3))
#data->insert('test2' = map('c'=33, 'd'=42))
with elm in #data->eachPair
let key = #elm->first
let value = #elm->second
order by #key
do { ... }
I doubt you problem is the pair with map construct per se.
This test code works as expected:
var(testcontainer = array)
inline(-database = 'mysql', -table = 'help_topic', -findall) => {
resultset(1) => {
records => {
if(!$testcontainer->contains(field('name'))) => {
local(i) = pair(field('name'), map('description' = field('description'), 'name' = field('name')))
$testcontainer->insert(#i)
}
}
}
}
$testcontainer
When Lasso hangs like that with no feedback and no immediate crash it is usually trapped in some kind of infinite loop. I'm speculating that it might have to do with Lasso using references whenever possible. Maybe some part of your code is using a reference that references itself. Or something.
I have a lex file port_regex.l that contains the following code.
DECIMAL_16bits [ \t]*[:digit:]{1,4}[ \t]*
SPACE [ \t]
%x S_rule S_dst_port
%%
%{
BEGIN S_rule;
%}
<S_rule>(dst-port){SPACE} {
BEGIN(S_dst_port);
}
<S_dst_port>\{{DECIMAL_16bits}\} {
printf("\n\nMATCH [%s]\n\n", yytext);
BEGIN S_rule;
}
. { ECHO; }
%%
int main(void)
{
while (yylex() != 0)
;
return(0);
}
int yywrap(void)
{
return 1;
}
I create an executable from it as follows.
flex port_regex.l
gcc lex.yy.c -o port_regex
which creates an executable called port_regex.
I have a file that contains test data called port.file which is given below.
dst-port {234}
dst-port {236}
dst-port {233}
dst-port {2656}
How do I test the port.file using port_regex executable.
can I do something like
./port_regex < port.file
I tried the above and it doesn't seem to work??
So long as your application doesn't become a lot more complex, I think using start conditions is a good way to go, instead of introducing a yacc-generated parser.
A couple of thoughts:
The examples I see sometimes use parentheses with BEGIN (BEGIN(comment)) and sometimes not (BEGIN comment). I doubt that it makes any difference, but you should be consistent.
The book says that the default rule to echo unmatched characters is still in effect, even under exclusive start conditions, so you shouldn't need
. { ECHO; }
and since your start conditions are exclusive, it wouldn't fire anyway. Just to make sure, you might rewrite it as
<*>.|\n ECHO;