с использованием [email protected]^1.0.0-beta.1.0.0" ,Как загрузить плагин Aurelia-проверки в тесте Карма не на пользовательский элемент
Столбики ниже обсуждения тестирования пользовательского элемента с aurelia, поэтому плагин загружается во время тестирования. Я пробовал много решений, но ничего не работает (возможно, потому, что я не использую собственный элемент). Я не хочу использовать пользовательский элемент, потому что модель представления участвуя в динамическом составе. После того, как форма успешно опубликована, я заменю моделью «спасибо», чтобы очистить все и показать, что форма была отправлена.
How to load an Aurelia plugin in Karma
Load aurelia-validation plugin during Jasmine unit tests - with webpack
https://github.com/aurelia/validation/issues/377
я получаю тот же ответ на многие из этих сообщений, когда я импортировать мой взгляд-модель в мой тест:
Error: (SystemJS) Did you forget to add ".plugin('aurelia-validation)" to your main.js?
Вот сокращенный вариант моя модель-образец src и тест, если это помогает ...
employment.html
<template>
<section class="au-animate">
<compose view.bind="view"></compose>
</section>
</template>
employment.js
import {inject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
import { sendto } from './env';
import Canidate from './canidate.js';
import 'fetch';
import { ValidationControllerFactory, ValidationRules } from 'aurelia-validation';
import {BootstrapFormRenderer} from './resources/renderers/bootstrap-form-renderer'
@inject(HttpClient, ValidationControllerFactory)
export class Employment {
constructor(http, controllerFactory) {
this.view = "./employment-form.html";
this.helpMsg = null
this.loading = false;
this.canidate = new Canidate();
this.controller = controllerFactory.createForCurrentScope();
this.controller.addRenderer(new BootstrapFormRenderer());
this._http = http;
}
submit() {
this.loading = true;
return this.controller.validate()
.then(result => {
if (result.isValid) {
return this._post();
}
})
.catch(error => {
this.canidate.error = error;
return this._post();
})
.then(() => this.loading = false);
}
_post() {
return this._http.fetch(sendto(), {
method: `POST`,
body: json(this.canidate)
}).then(response => response.json())
.then(() => {
this.helpMsg = null;
this.view = "./thanks.html";
}).catch(err => {
this.helpMsg = `there was an error submitting your form. ` +
`Please try again or contact us direct from the Contact Page`;
});
}
}
ValidationRules
.ensure(a => a.fullName).required()
.ensure(a => a.age).required()
.ensure(a => a.city).required()
.ensure(a => a.phone).required().matches(/\d{3}-\d{3}-\d{4}/)
.withMessage('Please format your phone number like ###-###-####')
.ensure(a => a.email).email()
.ensure(a => a.experience).required()
.on(Canidate);
employment.spec.js
import {Employment} from '../../src/employment';
import * as env from '../../src/env';
import Canidate from '../../src/canidate';
import {ValidationControllerFactory, ValidationController} from 'aurelia-validation';
import {StageComponent, ComponentTester} from 'aurelia-testing';
import {bootstrap} from 'aurelia-bootstrapper';
class HttpStub {
constructor() {
this.url = null;
this.config = null;
this.resolve = null;
this.reject = null;
}
fetch(url, blob) {
this.url = url;
this.blob = blob;
let promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
return promise;
}
configure(func) {
this.config = func;
}
}
describe('the Employment module',() => {
let sut;
let http;
let controller;
let component;
beforeAll(done => {
component = StageComponent.withResources().inView('<div></div>').boundTo({});
component.bootstrap(aurelia => aurelia.use.standardConfiguration().plugin('aurelia-validation'));
component.create(bootstrap).then(done);
});
afterAll(() => {
component.dispose();
});
beforeEach(() => {
const factory = jasmine.setupSpy('factory', ValidationControllerFactory.prototype);
controller = jasmine.setupSpy('controller', ValidationController.prototype);
http = new HttpStub();
factory.createForCurrentScope.and.returnValue(controller);
controller.validate.and.returnValue(Promise.resolve({valid: true}));
sut = new Employment(http, factory);
});
it('initiates the current view model variables',() => {
expect(sut.view).toEqual('./employment-form.html');
expect(sut.canidate).toEqual(new Canidate());
expect(sut.helpMsg).toEqual(null);
expect(sut.loading).toBeFalsy();
});
it('fetches with post data', done => {
const expectJson = '{"fullName":"tom","age":2,"city":"lex","phone":"1900",' +
'"email":"@.com",'"experience":"none"}';
sut.canidate.fullName = 'tom';
sut.canidate.age = 2;
sut.canidate.city = 'lex';
sut.canidate.phone = '1900';
sut.canidate.email = '@.com';
sut.canidate.experience = 'none';
spyOn(env, "sendto").and.returnValue('test');
http.itemStub = sut.canidate;
sut.submit().then(() => {
expect(http.url).toEqual('test');
expect(http.blob.method).toEqual('POST');
expect(sut.loading).toBeFalsy();
let fr = new FileReader();
fr.addEventListener('loadend', function() {
expect(fr.result).toEqual(expectJson);
done();
});
fr.readAsText(http.blob.body);
});
expect(sut.loading).toBeTruthy();
setTimeout(() => http.resolve({ json:() => sut.canidate }));
});
it('successfully posts the data', done => {
sut.submit().then(() => {
expect(sut.helpMsg).toEqual(null);
expect(sut.view).toEqual('./thanks.html');
done();
});
setTimeout(() => http.resolve({ json:() => {} }));
});
it('shows a help msg when posts fails', done => {
sut.submit().then(() => {
expect(sut.helpMsg).toContain('there was an error submitting your form');
expect(sut.view).toEqual('./employment-form.html');
done();
});
setTimeout(() => http.reject());
});
});
UPDATE
Возможно, я где-нибудь попаду? Я сделал то, что предложил @MartinMason, и переместил мой ValidationRules
в ctor модели представления и вместо того, чтобы использовать .on(Candidate)
, я сделал .on(this.candidate)
. Это позволило запустить мои тесты, но каждый тест для моей модели модели employment
потерпел неудачу с тем же сообщением Did you forget to add ".plugin('aurelia-validation)" to your main.js?
. Затем я пошел в ссылку github в начале этого сообщения и добавил в beforeAll
, что предложил jeremy, и я получил сообщение об ошибке, похожее на ValidationRules
.
Error: Unable to parse accessor function:
function (a) {
++cov_x4vangzdw.f[2];
++cov_x4vangzdw.s[10];
return a.fullName;
} (line 57)
getAccessorExpression
parseProperty
ensure
ensure
Employment
[email protected]_packages/system-polyfills.src.js:1188:34
[email protected]_packages/system-polyfills.src.js:1147:18
[email protected]_packages/system-polyfills.src.js:935:20
[email protected]_packages/system-polyfills.src.js:826:17
[email protected]_packages/system-polyfills.src.js:102:22
[email protected]_packages/system-polyfills.src.js:67:15
TypeError: undefined is not an object (evaluating 'sut.submit') (line 160)
[email protected]_packages/system-polyfills.src.js:1188:34
[email protected]_packages/system-polyfills.src.js:1147:18
[email protected]_packages/system-polyfills.src.js:935:20
[email protected]_packages/system-polyfills.src.js:826:17
[email protected]_packages/system-polyfills.src.js:102:22
[email protected]_packages/system-polyfills.src.js:67:15
и здесь Canidate.js
где ПолноеИмя исходит от
export default class {
fullName = '';
age = null;
city = '';
phone = '';
email = '';
experience = '';
}
Так что, если я изменить ValidationRules.ensure(a => a.fullname)
к ValidationRules.ensure('fullName')
ошибка уходит (я думаю, мне нужно добавить ValidationParser
в тесте? ... еще не получили, что далеко еще, я просто хочу, чтобы мои предыдущие тесты, чтобы пройти первый)
UPDATE
После исправления моих тестов на счет aurelia-validation
они проходят снова. Поэтому перемещение ValidationRules
на ctor, а затем добавление объектов aurelia-testing
обратно в функцию beforeAll
заставило его работать.Я все еще могу сделать .on(Canidate)
вместо .on(this.canidate)
в ValidationRules
, и тесты/сайт работают хорошо, но не уверены, какое влияние это будет иметь при фактическом тестировании правил проверки. Думаю, было бы неплохо, если бы jeremy мог сообщить нам, если это правильно.
введите ваш тестовый код –
@JeremyDanyow, я добавил все свои тесты, когда они посмотрели, прежде чем валидация была добавлена в модель просмотра 'employment.js'. Я пробовал много вещей, не показанных, что в этих ссылках я ссылаюсь на сообщение, некоторые из которых вы предлагаете как загрузку с помощью «ComponentTester», чтобы добавить плагин в 'beforeAll'. Я также попробовал глобальный 'beforeEach' –
, который смог воспроизвести это путем клонирования' skeleton-esnext' и добавления двух файлов выше и 'aurelia-validation' из' jspm'. В модели «занятости» я вынул все, кроме вызова «ValidationControllerFactory» в ctor и 'ValidationRules'. В тестовом файле я только что оставил первый тест. Тесты прекратились, когда я первоначально клонировал репо, но затем не удалось, когда я выполнил вышеуказанные шаги. –