2016-12-20 3 views
2

с использованием [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 мог сообщить нам, если это правильно.

+0

введите ваш тестовый код –

+0

@JeremyDanyow, я добавил все свои тесты, когда они посмотрели, прежде чем валидация была добавлена ​​в модель просмотра 'employment.js'. Я пробовал много вещей, не показанных, что в этих ссылках я ссылаюсь на сообщение, некоторые из которых вы предлагаете как загрузку с помощью «ComponentTester», чтобы добавить плагин в 'beforeAll'. Я также попробовал глобальный 'beforeEach' –

+0

, который смог воспроизвести это путем клонирования' skeleton-esnext' и добавления двух файлов выше и 'aurelia-validation' из' jspm'. В модели «занятости» я вынул все, кроме вызова «ValidationControllerFactory» в ctor и 'ValidationRules'. В тестовом файле я только что оставил первый тест. Тесты прекратились, когда я первоначально клонировал репо, но затем не удалось, когда я выполнил вышеуказанные шаги. –

ответ

3

Я разработал проект скелета и изменил проект skeleton-typescript-aspnetcore, включив интеграцию проверки aurelia в ветку integrate_validation. https://github.com/SoftwareMasons/skeleton-navigation/tree/integrate_validation Когда ValidationRules применяются к экземпляру в конструкторе класса, я могу пройти тесты на жасмин. Однако, когда правила применяются к классу, я никогда не могу заставить статический метод ValidateRules.initialize когда-либо правильно называться, поэтому ошибки возникают в assertInitialized методе проверки aurelia.

Я включил все, что я пытался заставить его работать в файле registionForm.spec.ts, а также краткое описание того, что я пытался. Надеюсь, мои неудачи помогут вам найти путь к успеху. На данный момент это приемлемый рабочий вопрос, но если вы найдете лучший способ, я был бы признателен, если вы сообщите нам об этом.

+0

Я собираюсь отметить это как ответ, так как он ведет меня по правильному пути. Дополнительный шаг, который я должен был сделать, - это мой вопрос. –