我一直在尝试配置ng-html2js来进行简单的指令测试(整个项目源可以找到here)。
相关的代码片段是:
角\ 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'
]
});
};
角\应用\部件\ paginatedTable \ paginatedTable.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';
}
角\应用\部件\ 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;
}
});
这会返回意外获取请求的错误,该错误应该通过导入&#34; jasmineTemplates&#34;来解决。由karma.conf.js上配置的ng-html2js生成。
TPL路径与之前处理的ng-html2js相同:
树形结构,如果它有帮助,如下所示:
编辑:在Chrome上运行业力而不是PhantomJS仍然会出现同样的错误,所以我认为这不是PhantomJS特有的。
答案 0 :(得分:0)
在测试用例文件中创建控制器时,为实际控制器中的所有依赖项创建模拟。我得到了一个类似的错误,我修复了包含测试用例中的所有依赖项。