Search code examples
coldfusionbddcoldfusion-2016

Adobe ColdFusion 2016 testbox BDD elvis operator issue


Update: Submitted a bug report for this issue, Bug #4150051


You could call ?: as elvis operator / ternary operator / null coelscing. It is very poor implementation & luck of proper documentation about this operator in ACF. There are some issues while using it in TestBox (Tried both v2.3.0+00044 & 2.2.0+00021) BDD. Here I have created very simple test bundle (aTest.cfc) to demonstrate this issue.

component extends="testbox.system.BaseSpec"{
    function run(){
        describe( "checking the ACF issues in ternary operaors", function(){
            it( "Just dump, it will pass. But see the dump above", function(){
                itemTypeConfig = {};
                writeDump( itemTypeConfig.someConfig ?: "I am null" );

                itemTypeConfig = {"someConfig":"abcd"};
                writeDump( itemTypeConfig.someConfig ?: "I am null" );
            } );

            it( "Check with elvis operator inside expect", function(){
                itemTypeConfig = {};
                expect( itemTypeConfig.someConfig ?: "I am null" ).toBe(1);

                itemTypeConfig = {"someConfig":"abcd"};
                expect( itemTypeConfig.someConfig ?: "I am null" ).toBe(1);
            } );

            it( "Check with expect with some temp variable", function(){
                itemTypeConfig = {};
                var actualResult = itemTypeConfig.someConfig ?: "I am null";
                expect( actualResult ).toBe(1);

                itemTypeConfig = {"someConfig":"abcd"};
                var actualResult = itemTypeConfig.someConfig ?: "I am null";
                expect( actualResult ).toBe("abcd");
            } );    

            it( "Check with expect with struct key exists", function(){
                itemTypeConfig = {};
                if ( structkeyexists(itemTypeConfig, "someConfig") )
                    var actualResult = itemTypeConfig.someConfig;
                else
                    var actualResult = 1;
                expect( actualResult ).toBe(1);

                itemTypeConfig = {"someConfig":"abcd"};
                if ( structkeyexists(itemTypeConfig, "someConfig") )
                    var actualResult = itemTypeConfig.someConfig;
                else
                    var actualResult = 1;
                expect( actualResult ).toBe("abcd");

            } );    

        } );
    }
}

While running this test case in Lucee, there is no problem. But in Adobe ColdFusion, I am getting errors. refer attached the screen shot of the test result. enter image description here 1. You can see dump are coming as undefined in first spec.

  1. In second spec, if you give the elvis operator inside the expect, expect( itemTypeConfig.someConfig ?: "I am null" ).toBe(1); It is giving actual undefined

  2. In third spec, I am trying to use temporary variable as work around to fix the actual undefined issue in spec 2 itemTypeConfig = {}; var actualResult = itemTypeConfig.someConfig ?: "I am null"; expect( actualResult ).toBe(1); But it is giving actualResult is undefined

  3. In fourth spec, I am using the struckkeyexists with out using this ternary operator in BDD test suites & it is working fine.

I tried to create similar behaviour in standalone cfm file, But I could not able reproduce it. I am not sure, whether it is issue in testbox or May be ACF handling the elvis operator inside the closures. I am not sure about the exact terminology to describe this issue


Solution

  • This is a parsing bug in Adobe ColdFusion Release 2016. (It works in ColdFusion 11). I reduced your example down to this code which demonstrates the issue. It only happens when you have nested the closure call at least 2 deep.

    clos = function( func ) { func(); };
    
    clos( function(){
        clos( function(){
            writeDump( foo ?: "I am null" );
        } );
    } );
    

    The output is "undefined" as you reported, yet "I am null" is expected.

    Please go to the Adobe Bug base and put in a ticket. Until it is fixed, you won't be able to use the elvis operator in your BDD tests.

    I would recommend simplifying your question to use this, much smaller repro case.