0

我一直在尝试配置 ng-html2js 以用于我的简单指令测试(可以在此处找到整个项目源代码)。

相关的代码是:

角\karma.conf.js

module.exports = function(config) {
    config.set({

        basePath: './app',

        preprocessors: {
            'components/**/*.tpl.html': ["ng-html2js"]
        },

        ngHtml2JsPreprocessor: {
            cacheIdFromPath: function (filepath) {
                console.info('ngHtml2JsPreprocessor: Loaded template from path "' + filepath + '"');
                return filepath;
            },
            moduleName: 'jasmineTemplates'
        },

        files: [
            'bower_components/angular/angular.js',
            'bower_components/angular-mocks/angular-mocks.js',
            'components/**/*.js',
            'components/**/*.tpl.html'
        ],

        autoWatch: true,

        frameworks: ['jasmine'],

        browsers: ['PhantomJS'],

        plugins: [
            'karma-ng-html2js-preprocessor',
            'karma-phantomjs-launcher',
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-jasmine'
        ]

    });
};

角\应用\组件\分页表\分页表.js

var COMPONENT_NAME = 'PaginatedTable';
var EVENTS = {
    ORDERED_BY: COMPONENT_NAME + ': Ordered table',
    FILTERED_BY: COMPONENT_NAME + ': Filtered rows'
};

angular.module('paginatedTable', [])

    .controller('paginatedTableCtrl',
        ["$scope", "$sce", "$filter",
            function($scope, $sce, $filter) {
                $scope.getHeader = function (column) {
                    var header = column.titleTpl ? column.titleTpl : column.title ? column.title : capitalizeFirstLetter(column.value);
                    var icon = ($scope.sortBy && $scope.sortBy.reverse) ? '▾' : '▴';
                    var isSelected = ($scope.sortBy && $scope.sortBy.property) === column.value;
                    return header + ' <span ng-show="' + (isSelected) + '">' + icon + '</span>';
                };

                $scope.getProperty = function (column, row) {
                    return column.format ? column.format(row) : row[column.value];
                };

                $scope.filterRows = function () {
                    if ($scope.data) {
                        $scope.rows = $filter('filter')($scope.data, $scope.filterQuery);
                        setMetadata('rowsCount', $scope.rows.length);
                        $scope.$emit(EVENTS.FILTERED_BY, {
                            id: $scope.id,
                            filterQuery: $scope.filterQuery
                        });
                    }
                };

                $scope.sortByColumn = function (column) {
                    $scope.sortBy = $scope.sortBy || {};

                    if ($scope.sortBy.property && $scope.sortBy.property == column.value) {
                        $scope.sortBy.reverse = !$scope.sortBy.reverse;
                    } else {
                        $scope.sortBy.property = column.value;
                        $scope.sortBy.reverse = column.reverseOrder || false;
                    }

                    $scope.sortTable();
                };

                $scope.sortTable = function (silent) {
                    if ($scope.rows && $scope.sortBy && $scope.sortBy.property) {
                        var sortingParameters = {
                            rows: $scope.rows,
                            property: $scope.sortBy.property,
                            reverse: $scope.sortBy.reverse,
                            // Optional
                            defaultProperty: $scope.sortBy.default,
                            defaultReverse: $scope.sortBy.defaultReverse
                        };

                        $scope.rows = sortRowsByProperty(sortingParameters);
                        $scope.currentPage = 0;

                        if (silent !== true) {
                            $scope.$emit(EVENTS.ORDERED_BY, {
                                id: $scope.id,
                                sortBy: $scope.sortBy
                            });
                        }
                    }
                };

                $scope.loadPreviousPage = function () {
                    $scope.currentPage = fixSmallerPage($scope.currentPage - 1);
                };

                $scope.loadNextPage = function () {
                    $scope.currentPage = fixLargerPage($scope.currentPage + 1);
                };

                $scope.loadPage = function (newPage) {
                    newPage = fixSmallerPage(newPage);
                    newPage = fixLargerPage(newPage);
                    $scope.currentPage = newPage;
                };

                $scope.getTotalPagesArray = function () {
                    return $scope.pageCount > 0 ? new Array($scope.pageCount) : [];
                };

                $scope.$watchGroup(['data', 'filterQuery'], function() {
                    $scope.filterRows();
                });

                $scope.$watch('rows', function(rows) {
                    if (rows) {
                        $scope.pageCount = getPageCount();
                        $scope.sortTable(true);
                    }
                });

                function getPageCount () {
                    return Math.ceil($scope.rows.length / $scope.pageSize);
                }

                function fixSmallerPage (newPage) {
                    return newPage >= 0 ? newPage : 0;
                }

                function fixLargerPage (newPage) {
                    return newPage < $scope.pageCount ? newPage : $scope.pageCount;
                }

                function capitalizeFirstLetter (string) {
                    return isString(string) && string.length ? string.charAt(0).toUpperCase() + string.slice(1) : '';
                }

                function sortRowsByProperty (settings) {
                    if (settings.rows) {
                        var propertySteps = settings.property.split('.');

                        settings.rows.sort(function (row_a, row_b) {
                            var value_a = getRowProperty(row_a, propertySteps),
                                value_b = getRowProperty(row_b, propertySteps),
                                reverse = settings.reverse;

                            if (value_a === value_b) {
                                if (!settings.defaultProperty || settings.defaultProperty === settings.property) {
                                    return 0;
                                } else {
                                    value_a = row_a[settings.defaultProperty];
                                    value_b = row_b[settings.defaultProperty];
                                    reverse = settings.defaultReverse;
                                }
                            }

                            return compareProperties(value_a, value_b, reverse);
                        });

                        return settings.rows;
                    }
                }

                function getRowProperty (row, propertySteps) {
                    var value = row;

                    for (var i in propertySteps) {
                        value = value[propertySteps[i]];
                    }

                    return value;
                }

                function setMetadata(key, value) {
                    if ($scope.metadata) {
                        $scope.metadata[key] = value;
                    }
                }

                function compareProperties (value_a, value_b, reverse) {
                    var sign = reverse ? -1 : 1;

                    if (isString(value_a) || isString(value_b)) {
                        return sign * compareStrings(value_a, value_b);
                    }
                    return sign * (value_a - value_b);
                }

                function compareStrings (str_a, str_b) {
                    if (str_a === '') return -1;
                    if (str_b === '') return 1;
                    str_a = ('' + str_a).toLowerCase();
                    str_b = ('' + str_b).toLowerCase();
                    return ((str_a < str_b) ? -1 : ((str_a > str_b) ? 1 : 0));
                }
            }
        ])

    .directive('paginatedTable',
        function() {
            return {
                restrict: 'E',
                replace: true,
                controller : 'paginatedTableCtrl',
                templateUrl: getPath() + 'paginatedTable.tpl.html',
                scope: {
                    id: '=',
                    columns: '=',
                    data: '=',
                    pageSize: '=',
                    sortBy: '=?',
                    filterQuery: '=?',
                    numeration: '=?',
                    scopeVariables: '=scope',
                    onLoad: '=?',
                    metadata: '=?'
                },
                link: function ($scope, element, attributes) {
                    var objectProperties = ['sortBy', 'metadata'];
                    bindScopeVariables($scope);

                    for (var i in objectProperties) {
                        var property = objectProperties[i];
                        $scope[property] = $scope[property] || {};
                    }

                    if (!$scope.sortBy.property) {
                        $scope.sortBy.property = $scope.sortBy.default;
                        $scope.sortBy.reverse = $scope.sortBy.defaultReverse;
                    }

                    $scope.currentPage = 0;
                    $scope.metadata.$scope = $scope;
                    $scope.filterRows();

                    if (typeof $scope.onLoad === 'function') $scope.onLoad($scope);
                }
            };

            function bindScopeVariables ($scope) {
                var scopeVariables = $scope.scopeVariables;

                if (isObject(scopeVariables)) {
                    var keys = Object.keys(scopeVariables);

                    for (var i in keys) {
                        var key = keys[i];
                        $scope[key] = scopeVariables[key];
                    }
                }

                delete $scope.scopeVariables;
            }

            function getPath () {
                var scripts = document.getElementsByTagName('script');

                for (var i in scripts) {
                    var scriptPath = scripts[i].src;

                    if (scriptPath.indexOf('paginatedTable.js') > -1) {
                        return scriptPath.substring(0, scriptPath.lastIndexOf('/') + 1);
                    }
                }
            }
        }
    )

    .directive('bindCompiledHtml', [
        "$compile",
        function ($compile) {
            return {
                restrict: 'A',
                link: function($scope, element, attrs) {
                    $scope.$watch(function () {
                        return $scope.$eval(attrs.bindCompiledHtml);

                    }, function (value) {
                        element.html(value);
                        $compile(element.contents())($scope);
                    });
                }
            }
        }
    ])

    .filter('limitToRange', function() {
        return function(rows, limits) {
            return rows ? rows.slice(+limits[0], +limits[1]) : undefined;
        }
    });

function isString (object) {
    return typeof object === 'string';
}

function isObject (object) {
    return typeof object === 'object';
}

angular\app\components\paginatedTable\paginatedTableDirective.spec.js

(function () {

describe('paginatedTable directive', function () {
    var $scope, $compile, dummyRows;

    beforeEach(function () {
        module("jasmineTemplates");
        module("paginatedTable");
        //module("components/paginatedTable/paginatedTable.tpl.html");

        inject(["$compile", "$rootScope",
            function ($compile_, $rootScope) {
                $scope = $rootScope.$new();
                $compile = $compile_;
            }
        ]);

        dummyRows = [
            { keyName: 'value0' },
            { keyName: 'value2', drawSolver: '2' },
            { keyName: 'value1' },
            { keyName: 'value2', drawSolver: '1' },
            { keyName: 'value4' }
        ];
    });

    describe('link function', function () {
        it('should call the onLoad callback if defined', function() {
            // Arrange
            $scope.onLoad = function () {
                console.log('Loaded directive');
            }
            spyOn(console, 'log');

            initializeScopePaginatedTableSettings();

            var directive = getCompiledDirective($scope);
            dump(directive);

            // Act
            $scope.$apply();
            $httpBackend.flush();

            // Assert
            expect(console.log).toHaveBeenCalled();
        });
    });

    /*describe('something', function () {
        it('should do something', function () {

        });
    });*/

    function initializeScopePaginatedTableSettings() {
        $scope.paginatedTable = {
            'columns': [
                {
                    value: 'keyName',
                    title: 'Title',
                    format: function (row) {
                        return '<span>' + row.title + '</span>';
                    }
                },
                {
                    value: 'score',
                    mouseover: 'Sort by score',
                    reverseOrder: true
                },
            ],
            'sortBy': {
                property: 'title',
                default: 'title'
            },
            'pageSize': 1,
            'rows': dummyRows
        }
    }

    function getCompiledDirective($scope) {
        var html = '<paginated-table '
            + 'columns="paginatedTable.columns" '
            + 'data="paginatedTable.rows" '
            + 'sort-by="paginatedTable.sortBy" '
            + 'page-size="paginatedTable.pageSize" '
            + 'numeration="paginatedTable.numeration" '
            + 'filter-query="filterQuery" '
            + 'metadata="paginatedTable.metadata" '
            + 'on-load="onLoad"'
            + '/></paginated-table>';

        var compiledDirective = $compile(html)(angular.extend($scope, {}));

        return compiledDirective;
    }
});

这会返回意外获取请求的错误,这应该通过导入 ng-html2js 生成的“jasmineTemplates”来解决,如 karma.conf.js 上配置的那样。

并且 TPL 路径与事先处理的 ng-html2js 相同:

在此处输入图像描述

如果有帮助,树结构如下所示:

在此处输入图像描述

编辑:在 Chrome 而不是 PhantomJS 上运行 karma 仍然会引发相同的错误,所以我想这不是 PhantomJS 特定的。

4

1 回答 1

0

在测试用例文件中创建控制器时,为实际控制器中的所有依赖项创建模拟。我得到了一个类似的错误,我通过在测试用例中包含所有依赖项来修复它。

于 2016-07-12T10:32:10.733 回答