2

我刚刚开始使用 Angular 模式表单进行开发,并且正在努力为我的自定义字段指令编写任何测试。

我已经尝试编译通过我的指令配置运行的模式表单 html 标记,测试它针对模式中的数据的显示条件。但是,它似乎从未运行我的控制器,并且我无法获得对指令 HTML 元素的引用。有人可以给我一些关于如何获得指令参考的指导吗?以下是我到目前为止的内容:

angular.module('schemaForm').config(['schemaFormProvider',
    'schemaFormDecoratorsProvider', 'sfPathProvider',
    function(schemaFormProvider, schemaFormDecoratorsProvider, sfPathProvider) {
        var date = function (name, schema, options) {
            if (schema.type === 'string' && schema.format == 'date') {
                var f = schemaFormProvider.stdFormObj(name, schema, options);
                f.key = options.path;
                f.type = 'date';
                options.lookup[sfPathProvider.stringify(options.path)] = f;
                return f;
            }
        };
        schemaFormProvider.defaults.string.unshift(date);
        schemaFormDecoratorsProvider.addMapping('bootstrapDecorator', 'date',
            'app/modules/json_schema_form/schema_form_date_picker/schema_form_date_picker.html');
    }]);

  var dateControllerFunction =  function($scope) {
      $scope.isCalendarOpen = false;

      $scope.showCalendar = function () {
        $scope.isCalendarOpen = true;
      };

      $scope.calendarSave = function (date) {
        var leaf_model = $scope.ngModel[$scope.ngModel.length - 1];
        var formattedDate = $scope.filter('date')(date, 'yyyy-MM-dd');
        leaf_model.$setViewValue(formattedDate);

        $scope.isCalendarOpen = false;
      };
  };

  angular.module('schemaForm').directive('schemaFormDatePickerDirective', ['$filter', function($filter) {
    return {
      require: ['ngModel'],
      restrict: 'A',
      scope: false,
      controller : ['$scope', dateControllerFunction],
      link: function(scope, iElement, iAttrs, ngModelCtrl) {
          scope.ngModel = ngModelCtrl;
          scope.filter = $filter
      }
    };
  }]);
<div ng-class="{'has-error': hasError()}">
  <div ng-model="$$value$$" schema-form-date-picker-directive>
    <md-input-container>
        <!-- showTitle function is implemented by ASF -->
        <label ng-show="showTitle()">{{form.title}}</label>
        <input name="dateTimePicker" ng-model="$$value$$" ng-focus="showCalendar()" ng-disabled="isCalendarOpen">
    </md-input-container>
    <time-date-picker ng-model="catalogue.effectiveFrom" ng-if="isCalendarOpen" on-save="calendarSave($value)" display-mode="date"></time-date-picker>
  </div>
  <!-- hasError() defined by ASF -->
  <span class="help-block" sf-message="form.description"></span>
</div>

和规格:

'use strict'

describe('SchemaFormDatePicker', function() {
  var $compile = undefined;
  var $rootScope = undefined;
  var $scope = undefined
  var scope = undefined
  var $httpBackend = undefined;
  var elem = undefined;
  var html = '<form sf-schema="schema" sf-form="form" sf-model="schemaModel"></form>';
  var $templateCache = undefined;
  var directive = undefined;

  beforeEach(function(){
    module('app');
  });

  beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_, _$httpBackend_) {
    $compile = _$compile_
    $rootScope = _$rootScope_
    $httpBackend = _$httpBackend_
    $templateCache = _$templateCache_
  }));

  beforeEach(function(){
    //Absorb call for locale
    $httpBackend.expectGET('assets/locale/en_gb.json').respond(200, {});
    $templateCache.put('app/modules/json_schema_form/schema_form_date_picker/schema_form_date_picker.html', '');
    $scope = $rootScope.$new()
    $scope.schema = {
       type: 'object',
       properties: {
         party: {
           title: 'party',
           type: 'string',
           format: 'date'
     }}};
     $scope.form = [{key: 'party'}];
     $scope.schemaModel = {};
   });

  describe("showCalendar", function () {
    beforeEach(function(){
      elem = $compile(html)($scope);
      $scope.$digest();
      $httpBackend.flush();
      scope = elem.isolateScope();
    });
    it('should set isCalendarOpen to true', function(){
      var result = elem.find('time-date-picker');
      console.log("RESULT: "+result);

    ));
  });
});
});

4

1 回答 1

0

如果您查看以下取自项目本身的示例,您可以看到当它使用 $compile 时,它angular.element()​​在设置 tmpl 时首先使用它。

此外,提供的测试模块名称为“app”,而代码示例的模块名称为“schemaForm”。Angular Schema Form repo的 1.0.0 版本中的示例都使用 sinon 和 chai,我不确定如果不使用它们需要进行哪些更改。

注意: runSync(scope, tmpl);是 1.0.0 的新增功能,因为它现在通过异步函数运行以处理 $ref 包含。

/* eslint-disable quotes, no-var */
/* disabling quotes makes it easier to copy tests into the example app */
chai.should();

var runSync = function(scope, tmpl) {
  var directiveScope = tmpl.isolateScope();
  sinon.stub(directiveScope, 'resolveReferences', function(schema, form) {
    directiveScope.render(schema, form);
  });
  scope.$apply();
};

describe('sf-array.directive.js', function() {
  var exampleSchema;
  var tmpl;
  beforeEach(module('schemaForm'));
  beforeEach(
    module(function($sceProvider) {
      $sceProvider.enabled(false);

      exampleSchema = {
        "type": "object",
        "properties": {
          "names": {
            "type": "array",
            "description": "foobar",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "title": "Name",
                  "type": "string",
                  "default": 6,
                },
              },
            },
          },
        },
      };
    })
  );

  it('should not throw needless errors on validate [ノಠ益ಠ]ノ彡┻━┻', function(done) {
    tmpl = angular.element(
      '<form name="testform" sf-schema="schema" sf-form="form" sf-model="model" json="{{model | json}}"></form>'
    );

    inject(function($compile, $rootScope) {
      var scope = $rootScope.$new();
      scope.model = {};

      scope.schema = exampleSchema;

      scope.form = [ "*" ];

      $compile(tmpl)(scope);
      runSync(scope, tmpl);

      tmpl.find('div.help-block').text().should.equal('foobar');

      var add = tmpl.find('button').eq(1);
      add.click();

      $rootScope.$apply();

      setTimeout(function() {
        var errors = tmpl.find('.help-block');
        errors.text().should.equal('foobar');
        done();
      }, 0);
    });
  });
});

于 2017-07-24T12:59:12.703 回答