3

更新: この問題に関するバグ レポートを提出しました。バグ #4150051


?: を elvis 演算子 / 三項演算子 / null coelscing として呼び出すことができます。実装が非常に貧弱であり、ACF でこの演算子に関する適切なドキュメントが作成されていません。TestBox (v2.3.0+00044 と 2.2.0+00021 の両方を試しました) BDD で使用すると、いくつかの問題が発生します。ここでは、この問題を実証するために非常に単純なテスト バンドル (aTest.cfc) を作成しました。

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");

            } );    

        } );
    }
}

このテスト ケースを Lucee で実行しても問題はありません。しかし、Adobe ColdFusion ではエラーが発生します。テスト結果のスクリーンショットを添付して参照してください。 ここに画像の説明を入力 1.最初の仕様では、ダンプが未定義として来ていることがわかります。

  1. 2 番目の仕様では、expect 内で elvis 演算子を指定すると、expect( itemTypeConfig.someConfig ?: "I am null" ).toBe(1);実際の undefined が返されます

  2. 3 番目の仕様では、仕様 2 の実際の未定義の問題を修正するための回避策として一時変数を使用しようとしています itemTypeConfig = {}; var actualResult = itemTypeConfig.someConfig ?: "I am null"; expect( actualResult ).toBe(1); が、actualResult は未定義です

  3. 4 番目の仕様では、BDD テスト スイートでこの 3 項演算子を使用せずに Shockedkeyexists を使用していますが、正常に動作しています。

スタンドアロンの cfm ファイルで同様の動作を作成しようとしましたが、再現できませんでした。それがテストボックスの問題なのか、それともクロージャ内のelvis演算子を処理するACFなのかはわかりません。この問題を説明する正確な用語がわかりません

4

1 に答える 1

7

これは、Adobe ColdFusion リリース 2016 の解析バグです (ColdFusion 11 で動作します)。問題を示すこのコードにあなたの例を減らしました。クロージャー呼び出しを少なくとも 2 深さでネストした場合にのみ発生します。

clos = function( func ) { func(); };

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

あなたが報告したように、出力は「undefined 」ですが、「 I am null」が期待されています。

Adobe Bug baseにアクセスして、チケットを入力してください。修正されるまで、BDD テストで elvis 演算子を使用することはできません。

質問を単純化して、これを使用することをお勧めします。これは、はるかに小さい再現ケースです。

于 2016-05-06T17:20:04.770 に答える