如何为 jasmine 编写自定义匹配器以查找对象属性是否位于对象 属性 值范围内?

How to write a custom matcher for jasmine to find if the object properties lie within a range of object property values?

我正在尝试为 Jasmine 实现自定义匹配器,我想在其中检查给定对象 属性 值是否在其他两个对象 属性 值的范围内。

这是我目前得到的:

let matcher = {
            toLieWithin: function (util: jasmine.MatchersUtil, customEqualityTesters: Array<jasmine.CustomEqualityTester>): jasmine.CustomMatcher {
                return {
                    compare: function (actual: any, expected: any): jasmine.CustomMatcherResult {
                        let result: jasmine.CustomMatcherResult = {
                            pass: false,
                            message: ''
                        };

                        result.pass = liesWithin(actual, expected);

                        return result;
                    }
                }
            }
        }; 

function liesWithin<T>(objActual: T, objExpected: T[]): boolean {
        let output: boolean;
        if(objExpected) {
          output = objActual.x > objExpected[0].x && objActual.x < objExpected[1].x && objActual.y > objExpected[0].y && objExpected[1].y;
        }
return output;    
}

在这里,我假设实际有两个属性 xy。预期的是两个对象的数组,每个对象也有两个属性 xy.

actual = {x: -5, y: -10}; expected = [{x: -10, y: -17},{x: 0, y: 0}];

现在,对于上面给出的简单示例,我相信这种情况是有效的。但是当我试图将它实现为泛型时,我如何找到该对象具有哪些属性?我的方法正确吗?谁能给我一些想法,我该如何实现这样的方法。

谢谢。

看起来您的 liesWithin 函数走在了正确的轨道上,您只需要考虑 expected 对象可能不会按您期望的顺序返回的情况。此代码也应涵盖这些情况:

// Helper to reduce repeated code
function isWithinRange(val, a, b) {
    return (val > a && val < b) || (val > b && val < a);
}

function liesWithin<T>(objActual: T, objExpected: T[]): boolean {
    if (objExpected) {
        let props = Object.keys(objActual);
        // Splitting X and Y checks into two for readability
        let isInYRange = isWithinRange( objActual[ props[0] ], objExpected[0][ props[0] ], objExpected[1][ props[0] ] );
        let isInXRange = isWithinRange( objActual[ props[1] ], objExpected[0][ props[1] ], objExpected[1][ props[1] ] );
        return isInXRange && isInYRange;
    }
    return;
}