Tuesday 22 October 2013

Follow-up to a "not a bug" status from Adobe: arrayFindNoCase() returns false negatives

G'day:
About a year ago I raised a ticket observing that arrayFindNoCase() doesn't really work so reliably: 3316776. A coupla weeks ago it was marked as "not a bug", which I find rather bemusing - as there's definitely buggy behaviour - but not as bemusing as the explanatory feedback from Adobe.

Awdhesh added this note to the ticket:

arrayFindNocase will find only the element of the array. If passes searched object is not same to its element (in the case of arrayFindNoCase([["a"],] [A]) ), it should work as expected. Its seems the current behavior is correct and as expected.

I don't really know what Awdesh is saying there: I suspect some English-dialectual differences are interfering, or just a case of "developers struggle to string coherent sentences together sometimes" (this is a general observation, not specifically relating to Awdesh).

But the crux of what Awdesh is saying is that "it works as expected". No, it doesn't. The code I posted demonstrated that. The simplest case that demonstrates it not working is as easy as this:

<cfset arrayToSearch = [["value"]]>
<cfdump var="#arrayToSearch#" label="arrayToSearch">


<h1>Control</h1>
<p>This demonstrates that the function works with same-case</p>
<cfset arrayToFind = ["value"]>

<cfdump var="#arrayToFind#" label="arrayToFind">

<cfoutput>
Was it found: #arrayFindNoCase(arrayToSearch, arrayToFind)#<br />
</cfoutput>
<hr />


<h1>Test</h1>
<p>This demonstrates that the function fails on different casing</p>
<cfset arrayToFind = ["VALUE"]>

<cfdump var="#arrayToFind#" label="arrayToFind">

<cfoutput>
Was it found: #arrayFindNoCase(arrayToSearch, arrayToFind)#<br />
</cfoutput>
<hr />

So the test here is in two parts. Firstly a control that simply tests whether the function works at all, using an array as the object to find. Note that the docs for arrayFindNoCase() specifically state "The function can search for simple objects such as strings or numbers and complex objects such as structures." (my emphasis). Whilst it doesn't specifically state it supports arrays, it does specifically exclude some data types, and does not list arrays, so one can assume it might support searching for an embedded array. The docs here aren't very clear, to be honest.

So the first test is to find an array inside my test array, and I've matched the case to encourage a positive result. The result is as follows:

arrayToSearch - array
1
arrayToSearch - array
1value

Control

This demonstrates that the function works with same-case
arrayToFind - array
1value
Was it found: 1

So, yes, the function will search for an array. And if the casing matches, it returns true.

Next, I use the same method, except this time testing with a case mismatch. This should still return true, as this function is arrayFindNoCase(). IE: it's case insensitive.

And the output is:

Test

This demonstrates that the function fails on different casing
arrayToFind - array
1VALUE
Was it found: 0
So... it doesn't work.

To recap:
  • this is a nocase function. So it should be case insensitive;
  • it is supposed to work with complex objects - such as structs - and I infer from that: arrays;
  • where the case matches, it works fine;
  • where the case doesn't match, it does not work.
So, Awdhesh, it is not behaving to spec. I don't think I can be any more bloody clear than that. Which is, I hasten to add, exactly what I put on the ticket in the first place. And I don't think it was unclear on the ticket, and the repro case on the ticket demonstrates my point. I can't help but thinking my efforts in providing all that info have been slightly wasted, given they seem to have been ignored.

As I can see how the handling of this ticket is going (badly), I've taken the liberty of extending my testing to cover other native CFML data-types too. This should remove a lot of doubt as to where there is work needed on this function.

There's too much code to include here, but it's all up on Github @ https://github.com/adamcameroncoldfusion/scratch/tree/master/blogExamples/arrays/bugs/arrayFindNoCase. If one runs main.cfm with a URL param caseSensitive with a boolean value, one will demonstrate either of arrayFind() (as a control), or arrayFindNoCase() (as a test). Sample results testing arrayFindNoCase():

arrayFindNoCase() testing

String

String with same case

array
Test passed

String with differing case

array
Test passed

Arrays

Array with element with same case

array
Test passed

Array with element with differing case

array
Not found

Structs

Struct with key/value with same case

array
Test passed

Struct with value with differing case

array
Test passed

Struct with key with differing case

array
Test passed

Objects

Object with property name/value with same case

array
Test passed

Object with property value with differing case

array
Not found

Object with property name with differing case

array
Test passed

XML

XML with element/attribute/value with same case

array
Not found

XML with element with different case

array
Not found

XML with attribute with different case

array
Not found

XML with attribute value with different case

array
Not found

XML with text with different case

array
Not found


It's mostly all right. Note that actually the case-sensitive version also doesn't work for all cases. So that needs work too.

Hopefully this will give Awdhesh enough to go on to crack on with fixing the issue.

--
Adam