2016-07-12 13 views
0

Ich habe versucht, ng-html2js zu arbeiten für meine einfache Direktive testen (ganzes Projekt Quelle kann here gefunden werden).Kann ng-html2js nicht richtig arbeiten mit Karma + Jasmin + Phantomjs

Die relevanten Teile des Codes sind:

Winkel \ 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' 
     ] 

    }); 
}; 

Winkel \ components \ app \ 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'; 
} 

Winkel \ app \ components \ paginatedTable \ paginatedTableDirect ive.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; 
    } 
}); 

Dies gibt einen Fehler von unerwarteten Erhaltungs-Anforderung, die durch den Import der „jasmineTemplates“ erzeugt durch ng-html2js auf karma.conf.js so konfiguriert gelöst haben sollte.

Und der TPL Weg ist der gleiche ng-html2js verarbeitet vorher:

enter image description here

Strukturbaum, falls es hilft, geht wie folgt vor:

enter image description here

EDIT : Lauf Karma auf Chrome statt PhantomJS wirft immer noch den gleichen Fehler so nehme ich an würde dies nicht PhantomJS spezifisch ist.

Antwort

0

Während der Controller im Testfalldatei erstellen, erstellen Mocks für alle Abhängigkeiten in Ihrem eigentlichen Controller. Ich habe einen ähnlichen Fehler bekommen, den ich behoben habe, indem ich alle Abhängigkeiten in den Testfall aufgenommen habe.

+0

Könnten Sie bitte etwas näher erläutern? Ich verstehe nicht, was Sie mir sagen, @ user2427829 –

+0

Ihre paginatedTableCtrl injiziert $ sce und $ filter services, aber diese werden nicht in Ihren Testfällen verspottet. Versuchen Sie, Mocks für diese hinzuzufügen. Es könnte das Problem beheben. – user2427829

+0

Danke für den Tipp, aber leider hat es das Problem nicht gelöst. Ich habe die Abhängigkeiten auf beide Testdateien injiziert, aber es hat nichts verändert. In jedem Fall besteht "paginatedTableCtrl.spec.js" bereits die Tests bestanden. Nur "paginatedTableDirective.spec.js" schlägt aufgrund des Fehlers "unerwartete Anfrage" fehl. –

Verwandte Themen