Unit testing directive, templates of which are all with a file with script tags

I find it difficult to determine how to include my directive templates (which are in the same file in different script tags) in my Karma unit tests.

The error I am getting is:

PhantomJS 1.9 (Linux) ERROR SyntaxError: Parse error at /var/www/html/tweak/core/global/views/js/modules/datable/templates.html:1 PhantomJS 1.9 (Linux): Executed 0 of 0 ERROR (0.313 secs / 0 secs) 

Here are the relevant parts of the code:

My meat directives:

 return { scope : { columns : '=', config : '=' }, templateUrl : 'datable/table.html', restrict : 'E', controller : 'datableCtrl', link : linkingFunction }; 

My template file:

 <script type="text/ng-template" id="datable/table.html"> <!-- data rows --> <tr ng-repeat="row in rows track by $id($index)" class="datable-row" ng-hide="loading"> <td ng-repeat="column in columns track by $id($index)" ng-class="{'edit-on': editMode == 'on'}" class="{{column.classes.join(' ') + ' column' + $index}}" ng-style="column.style"> <div ng-include="editMode == 'on' && column.editable ? 'datable/editCell.html' : 'datable/normalCell.html'"> </div> </td> <!-- save button --> <td ng-show="editMode == 'on'" style="width:1px;"> <button class="btn"> Save </button> </td> <!-- / save button --> </tr> <!-- / data rows --> </script> <script type="text/ng-template" id="datable/editCell.html"> <div ng-switch="column.inputType"> <!-- text input --> <div ng-switch-when="text"> <div ng-class="{ 'input-append' : column.append != '', 'input-prepend' : column.prepend != '' }"> <span class="add-on" ng-show="column.prepend"> {{column.prepend}} </span> <input type="text" ng-model="row[column.model]" ng-keydown="query()" ng-class="inputClass.join(' ')" ng-attrs="column.inputAttrs"> <span class="add-on" ng-show="column.append"> {{column.append}} </span> </div> </div> <!-- end text input --> <!-- select input --> <div ng-switch-when="select"> <select ng-model="row[column.model]" ng-change="query()" ng-options="item.value as item.name for item in column.options" ng-class="inputClass.join(' ')" ng-attrs="column.inputAttrs"> <option value=""> -- </option> </select> </div> <!-- end select --> <!-- radio / checkbox --> <div ng-switch-default> <label ng-repeat="(key, value) in column.options track by $id($index)"> <input type="{{column.inputType}}" ng-class="inputClass.join(' ')" ng-change="query()" value="{{key}}" ng-checked="row[column.model].indexOf('key') > -1" ng-attrs="column.inputAttrs"> <span> {{value}} </span> </label> </div> <!-- end radio / checkbox --> </div> </script> <script type="text/ng-template" id="datable/normalCell.html"> <div class="read-only"> <span> {{column.prepend}} </span> <!-- <span> {{row[column.model] | datableFilter : column.filter}} </span> --> <span ng-bind-html-unsafe="(row[column.model] + '') | datableFilter : column.filter"></span> <span> {{column.append}} </span> </div> </script> 

My unit tests:

 'use strict' describe("datable", function() { describe('directive', function () { var $rootScope, $compile, element; beforeEach(module('datable')); beforeEach(module('/var/www/html/tweak/core/global/views/js/modules/datable/templates.html')); beforeEach(inject(function (_$rootScope_, _$compile_) { $rootScope = _$rootScope_; $compile = _$compile_; $rootScope.tableConfig = { editable : true }; $rootScope.columns = []; element = angular.element('<datable config="tableConfig" columns="columns"></datable>'); $compile(element)($rootScope); $rootScope.$digest(); })); it('should have ng-scope class', function() { expect(element.hasClass('ng-scope')).toBe(true); }); }); }); 

My karma configuration:

 var branch = 'tweak'; basePath = '/var/www/html/' + branch + '/'; files = [ // Dependencies JASMINE, JASMINE_ADAPTER, 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js', 'https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js', 'http://code.angularjs.org/1.1.5/angular-mocks.js', // other requirements 'core/global/views/js/modules/rest/module.js', // the project source 'core/global/views/js/modules/datable/module.js', 'core/global/views/js/modules/datable/values.js', 'core/global/views/js/modules/datable/services.js', 'core/global/views/js/modules/datable/filters.js', 'core/global/views/js/modules/datable/directives.js', 'core/global/views/js/modules/datable/controllers.js', 'core/global/views/js/modules/datable/*.html', // my spec suite 'core/global/views/js/modules/datable/tests.js' ]; exclude = [ ]; reporters = ['progress']; port = 9876; runnerPort = 9100; colors = true; logLevel = LOG_INFO; autoWatch = true; browsers = ['PhantomJS']; captureTimeout = 60000; 
+6
source share
1 answer

I think your error is due to the fact that you are trying to upload your HTML file to the list of files that javascript usually accepts. I have a solution for you.

Before starting, I have karma 0.10.2, and it looks like you are at 0.8.x or lower? It works for me in 0.10.2, but I can not install 0.8.x. I will try to translate to 0.8.x, but I will not be able to verify what I am doing, so I will describe mainly from the point of view of 0.10.x. In any case, it may be easier to move to the last karma, if you can.

Config

0.10.x

External HTML parts can be loaded by karma-ng-html2js-preprocessor . This is usually used to load directly into directives via templateUrl and similar methods. In 0.10.2, you need to make sure that this package is installed (using npm), and then include the following in your karma configuration:

 preprocessors: { '**/*.html' : ['ng-html2js'] }, ngHtml2JsPreprocessor: { cacheIdFromPath: function(filepath) { // If you had more than one html file you would want to do something more clever here. return 'inlinetemplates'; }, moduleName: 'inlinetemplates' }, plugins: [ ..., 'karma-ng-html2js-preprocessor' ], files: [ ..., 'app/alltemplates.html', // your main template html // Don't include paths for individual files that are inlined in the file above ] 

This will allow you to load a module with module('inlinetemplates') , which will insert the contents of your main template file (rather than individual templates) into $templateCache .

0.8.x

So, translation for 0.8.x ... I think you need to use html2js , which is not so powerful, but included in karma in this version. You do not need to install or include it in plugins, and you cannot configure the way it is used, so you just need to

 preprocessors = { '**/*.html': ['html2js'] } 

The created module and the element that it inserts into $templateCache will be named using the path that you use to link to your main html template.

Javascript

0.10.x

Now you can download the corresponding module and access the contents of the main template file using

 var templates = $templateCache.get('inlinetemplates') 

All that remains to be done is to push your inline templates from the contents of the main template to $templateCache . This is done using the angular script directive, so we just need to compile / link the file that we downloaded using angular. You can do it very simply with

 $compile(templates)(scope); 

So, adding this together, you can include the following in any describe block that your templates should load.

 beforeEach(module('inlinetemplates')); beforeEach(inject(function($compile, $templateCache, $rootScope) { var templatesHTML = $templateCache.get('inlinetemplates'); $compile(templatesHTML)($rootScope); })); 

0.8.x

 var mainTemplateLocation = 'path/used/to/refer/to/main/templates/in/karma/conf.html'; beforeEach(module(mainTemplateLocation)); beforeEach(inject(function($compile, $templateCache, $rootScope) { var templatesHTML = $templateCache.get(mainTemplateLocation); $compile(templatesHTML)($rootScope); })); 

Summarizing

Again, I can’t guarantee that the 0.8.x instructions will work, especially not without configuration, but this certainly works in 0.10.x.

Karma already has the ability to push external HTML packages into your tests, all that was missing could correctly interpret your main template.

+7
source

Source: https://habr.com/ru/post/956195/


All Articles