extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
1,230 lines (1,033 loc) • 293 kB
JavaScript
describe("Ext.data.Model", function() {
beforeEach(function() {
Ext.ClassManager.enableNamespaceParseCache = false;
Ext.data.Model.schema.setNamespace('spec');
});
afterEach(function() {
Ext.ClassManager.enableNamespaceParseCache = true;
Ext.data.Model.schema.clear(true);
});
describe('use of raw Model class', function() {
it("should be able to use Ext.data.Model directly on a store", function() {
var data = [
{ forename: 'Nige', surname: 'White' },
{ forename: 'Don', surname: 'Griffin' },
{ forename: 'Phil', surname: 'Guerrant' },
{ forename: 'Kevin', surname: 'Krohe' },
{ forename: 'Evan', surname: 'Trimboli' }
];
var store = new Ext.data.Store({
model: Ext.data.Model,
data: data
});
// The raw data object should be inported directly as the records' data objects
expect(store.getAt(0).data).toEqual(data[0]);
expect(store.getAt(1).data).toEqual(data[1]);
expect(store.getAt(2).data).toEqual(data[2]);
expect(store.getAt(3).data).toEqual(data[3]);
expect(store.getAt(4).data).toEqual(data[4]);
// Set functionality should work
store.getAt(0).set('forename', 'Nigel');
expect(store.getAt(0).get('forename')).toBe('Nigel');
});
});
describe("getField/getFields", function() {
var A;
beforeEach(function() {
A = Ext.define('spec.A', {
extend: Ext.data.Model,
fields: ['id', 'name', 'key']
});
});
afterEach(function() {
Ext.undefine('spec.A');
A = null;
});
describe("getFields", function() {
it("should return an array", function() {
expect(Ext.isArray(A.getFields())).toBe(true);
});
it("should return all fields in the model", function() {
expect(A.getFields().length).toBe(3);
});
it("should be able to be called on an instance", function() {
var o = new A();
expect(o.getFields().length).toBe(3);
});
});
describe("getField", function() {
it("should return null if no field with a matching name is found", function() {
expect(A.getField('foo')).toBeNull();
});
it("should return the field", function() {
expect(A.getField('key').isField).toBe(true);
});
it("should be able to be called on an instance", function() {
var o = new A();
expect(o.getField('name').isField).toBe(true);
});
});
});
describe("defining models", function() {
var A, B;
afterEach(function() {
Ext.undefine('specModel');
Ext.undefine('spec.A');
Ext.undefine('spec.B');
Ext.undefine('spec.model.sub.C');
A = B = null;
});
describe('entityName', function () {
beforeEach(function () {
Ext.define('specModel', {
extend: 'Ext.data.Model'
});
Ext.define('spec.A', {
extend: 'Ext.data.Model'
});
Ext.define('spec.B', {
extend: 'Ext.data.Model'
});
Ext.define('spec.model.sub.C', {
extend: 'Ext.data.Model'
});
});
it('should generate proper default entityName for top-level', function () {
expect(specModel.entityName).toBe('specModel');
});
it('should generate proper default entityName for namespaced entity', function () {
expect(spec.A.entityName).toBe('A');
expect(spec.B.entityName).toBe('B');
});
it('should generate proper default entityName for a deep namespaced entity', function () {
expect(spec.model.sub.C.entityName).toBe('model.sub.C');
});
});
describe("fields", function() {
afterEach(function() {
Ext.undefine('spec.A');
Ext.undefine('spec.B');
A = B = null;
});
function defineA(fields, cfg) {
cfg = Ext.apply({
extend: Ext.data.Model,
fields: fields
}, cfg);
A = Ext.define('spec.A', cfg);
}
function defineB(fields, cfg) {
cfg = Ext.apply({
extend: A,
fields: fields
}, cfg);
// This will warn about redefining field 'id'
spyOn(Ext.log, 'warn');
B = Ext.define('spec.B', cfg);
}
it("should be able to define a string name field and default the type to auto", function() {
defineA(['id']);
var field = A.getField('id');
expect(field.isField).toBe(true);
expect(field.getType()).toBe('auto');
expect(A.getFields().length).toBe(1);
});
it("should be able to define an object field and default the type to auto", function() {
defineA([{
name: 'id'
}]);
var field = A.getField('id');
expect(field.isField).toBe(true);
expect(field.getType()).toBe('auto');
expect(A.getFields().length).toBe(1);
});
it("should read the type parameter from the field", function() {
defineA([{
name: 'id',
type: 'int'
}]);
expect(A.getField('id').getType()).toBe('int');
});
it("should retain the field definition order", function() {
defineA(['id', 'd', 'a', 'c', 'b'] );
var fields = A.getFields(),
names = [];
Ext.Array.forEach(fields, function(field) {
names.push(field.getName());
});
expect(names).toEqual(['id', 'd', 'a', 'c', 'b']);
expect(fields.length).toBe(5);
});
it("should be able to define a field with a - in the name", function() {
defineA(['the-field']);
var field = A.getField('the-field');
expect(field.isField);
});
describe("id field", function() {
it("should create a field matching the idProperty if it doesn't exist", function() {
defineA([]);
var fields = A.getFields();
expect(fields.length).toBe(1);
expect(fields[0].getName()).toBe(A.prototype.idProperty);
});
it("should append the id field to the end if it doesn't exist", function() {
defineA(['a', 'b']);
var fields = A.getFields();
expect(fields[2].getName()).toBe('id');
});
it("should not create an extra field if the idProperty field is already defined", function() {
defineA([{
name: 'id',
type: 'int'
}]);
var field = A.getField('id');
expect(field.getType()).toBe('int');
});
it("should create an idField when the name isn't the default", function() {
defineA([], {
idProperty: 'name'
});
expect(A.getField('name').isField).toBe(true);
});
it("should clear any defaultValue on the idField", function() {
defineA([{
name: 'id',
type: 'int'
}]);
expect(A.getField('id').defaultValue).toBeNull();
});
it("should set allowNull on the idField", function() {
defineA([{
name: 'id',
type: 'int'
}]);
expect(A.getField('id').allowNull).toBe(true);
});
});
describe("subclassing", function() {
it("should inherit the fields from the superclass", function() {
defineA(['id', 'name']);
defineB([]);
expect(B.getFields().length).toBe(2);
});
it("should append new fields to the end", function() {
defineA(['id', 'name']);
defineB(['foo', 'bar']);
var fields = B.getFields();
expect(fields.length).toBe(4);
expect(fields[2].getName()).toBe('foo');
expect(fields[3].getName()).toBe('bar');
});
it("should not modify the fields in the superclass", function() {
defineA(['id', 'name']);
defineB(['foo', 'bar']);
var fields = A.getFields();
expect(fields.length).toBe(2);
expect(fields[0].getName()).toBe('id');
expect(fields[1].getName()).toBe('name');
});
it("should be able to override a field in the base", function() {
defineA(['id']);
defineB([{
name: 'id',
type: 'int'
}]);
expect(A.getField('id').getType()).toBe('auto');
expect(B.getField('id').getType()).toBe('int');
});
it("should copy fields for deep subclasses", function() {
defineA(['id']);
defineB(['bField']);
Ext.define('spec.C', {
extend: B,
fields: ['cField']
});
Ext.define('spec.D', {
extend: spec.C,
fields: ['dField']
});
var fields = spec.C.getFields();
expect(fields.length).toBe(3);
expect(fields[2].getName()).toBe('cField');
fields = spec.D.getFields();
expect(fields.length).toBe(4);
expect(fields[2].getName()).toBe('cField');
expect(fields[3].getName()).toBe('dField');
Ext.undefine('spec.C');
Ext.undefine('spec.D');
});
describe("id field", function() {
describe("not changing the idProperty", function() {
it("should inherit the idProperty & keep the generated idField in position", function() {
defineA(['foo', 'bar']);
defineB(['baz']);
var fields = spec.A.getFields();
expect(fields.length).toBe(3);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('bar');
expect(fields[2].name).toBe('id');
expect(spec.A.getField('id')).toBe(fields[2]);
fields = spec.B.getFields();
expect(fields.length).toBe(4);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('bar');
expect(fields[2].name).toBe('id');
expect(fields[3].name).toBe('baz');
expect(spec.B.getField('id')).toBe(fields[2]);
expect(spec.A.idField.name).toBe('id');
expect(spec.B.idField.name).toBe('id');
});
it("should inherit the idProperty & keep a defined idField in position", function() {
defineA(['foo', 'id', 'bar']);
defineB(['baz']);
var fields = spec.A.getFields();
expect(fields.length).toBe(3);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('bar');
expect(spec.A.getField('id')).toBe(fields[1]);
fields = spec.B.getFields();
expect(fields.length).toBe(4);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('bar');
expect(fields[3].name).toBe('baz');
expect(spec.B.getField('id')).toBe(fields[1]);
expect(spec.A.idField.name).toBe('id');
expect(spec.B.idField.name).toBe('id');
});
});
describe("changing the idProperty", function() {
describe("id declared as a field in superclass & subclass", function() {
it("should keep both idFields in the defined order", function() {
defineA(['foo', 'id', 'bar']);
defineB(['customId', 'baz'], {idProperty: 'customId'});
var fields = spec.A.getFields();
expect(fields.length).toBe(3);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('bar');
expect(spec.A.getField('id')).toBe(fields[1]);
fields = spec.B.getFields();
expect(fields.length).toBe(5);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('bar');
expect(fields[3].name).toBe('customId');
expect(fields[4].name).toBe('baz');
expect(spec.B.getField('id')).toBe(fields[1]);
expect(spec.B.getField('customId')).toBe(fields[3]);
expect(spec.A.idField.name).toBe('id');
expect(spec.B.idField.name).toBe('customId');
});
});
describe("id declared as field only in superclass", function() {
it("should keep a defined idField from the parent, but it should not be the idField", function() {
defineA(['foo', 'id', 'bar']);
defineB(['baz'], {idProperty: 'customId'});
var fields = spec.A.getFields();
expect(fields.length).toBe(3);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('bar');
expect(spec.A.getField('id')).toBe(fields[1]);
fields = spec.B.getFields();
expect(fields.length).toBe(5);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('bar');
expect(fields[3].name).toBe('baz');
expect(fields[4].name).toBe('customId');
expect(spec.B.getField('id')).toBe(fields[1]);
expect(spec.B.getField('customId')).toBe(fields[4]);
expect(spec.A.idField.name).toBe('id');
expect(spec.B.idField.name).toBe('customId');
});
});
describe("id declared as a field only in subclass", function() {
it("should remove the generated id field and leave the declared idField in place", function() {
defineA(['foo']);
defineB(['bar', 'customId', 'baz'], {idProperty: 'customId'});
var fields = spec.A.getFields();
expect(fields.length).toBe(2);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
fields = spec.B.getFields();
expect(fields.length).toBe(4);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('bar');
expect(fields[2].name).toBe('customId');
expect(fields[3].name).toBe('baz');
expect(spec.B.getField('id')).toBeNull();
expect(spec.A.idField.name).toBe('id');
expect(spec.B.idField.name).toBe('customId');
});
});
describe("id not declared as a field", function() {
it("should replace a generated idField from the parent", function() {
defineA(['foo', 'bar']);
defineB(['baz'], {idProperty: 'customId'});
var fields = spec.A.getFields();
expect(fields.length).toBe(3);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('bar');
expect(fields[2].name).toBe('id');
fields = spec.B.getFields();
expect(fields.length).toBe(4);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('bar');
expect(fields[2].name).toBe('customId');
expect(fields[3].name).toBe('baz');
expect(spec.B.getField('id')).toBeNull();
expect(spec.A.idField.name).toBe('id');
expect(spec.B.idField.name).toBe('customId');
});
});
});
});
describe("versionProperty", function() {
it("should append versionProperty if it's not declared as a field", function() {
defineA(['foo'], {
versionProperty: 'version'
});
var fields = spec.A.getFields(),
version = fields[2];
expect(fields.length).toBe(3);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('id');
expect(fields[2].name).toBe('version');
expect(version.critical).toBe(true);
expect(version.defaultValue).toBe(1);
});
it("should leave a declared versionProperty in position", function() {
defineA(['foo', {
name: 'version',
type: 'int'
}, 'bar'], {
versionProperty: 'version'
});
var fields = spec.A.getFields(),
version = fields[1];
expect(fields.length).toBe(4);
expect(fields[0].name).toBe('foo');
expect(fields[1].name).toBe('version');
expect(fields[2].name).toBe('bar');
expect(fields[3].name).toBe('id');
expect(version.critical).toBe(true);
expect(version.defaultValue).toBe(1);
});
});
});
describe("configs the model sets on the field", function() {
describe("ordinal", function() {
function expectOrdinal(name, ordinal, cls) {
cls = cls || A;
var field = cls.getField(name);
expect(field.ordinal).toBe(ordinal);
}
it("should set the ordinal for each field in order", function() {
defineA(['foo', 'bar', 'baz']);
var fields = A.getFields();
expectOrdinal('foo', 0);
expectOrdinal('bar', 1);
expectOrdinal('baz', 2);
});
it("should append the id field to the end", function() {
defineA(['foo', 'bar', 'baz']);
expectOrdinal('id', 3);
});
it("should not move the id field if it exists", function() {
defineA(['id', 'foo', 'bar', 'baz']);
expectOrdinal('id', 0);
});
describe("subclassing", function() {
it("should append field to the end", function() {
defineA(['id', 'foo']);
defineB(['bar', 'baz']);
expectOrdinal('bar', 2, B);
expectOrdinal('baz', 3, B);
});
it("should not move a field if redefined", function() {
defineA(['id', 'foo']);
defineB(['bar', 'baz', {
name: 'foo',
type: 'int'
}]);
expectOrdinal('foo', 1, B);
});
it("should append a custom id field to the end", function() {
defineA(['id', 'foo']);
defineB(['bar'], {
idProperty: 'customId'
});
expectOrdinal('customId', 3, B);
});
});
});
describe("definedBy", function() {
it("should set the defined class on all fields", function() {
defineA(['foo', 'bar']);
expect(A.getField('foo').definedBy).toBe(A);
expect(A.getField('bar').definedBy).toBe(A);
});
it("should set the defined class on an id field", function() {
defineA(['foo', 'bar']);
expect(A.getField('id').definedBy).toBe(A);
});
describe("subclassing", function() {
it("should set the subclass on the field", function() {
defineA(['foo']);
defineB(['bar']);
expect(B.getField('bar').definedBy).toBe(B);
});
it("should retain the superclass on the field", function() {
defineA(['foo']);
defineB(['bar']);
expect(B.getField('foo').definedBy).toBe(A);
});
it("should set the if the field is redefined", function() {
defineA(['foo']);
defineB(['bar', {
name: 'foo',
type: 'int'
}]);
expect(B.getField('foo').definedBy).toBe(B);
});
});
});
});
describe("calculated fields", function() {
describe("subclassing", function() {
it("should inherit calculated fields", function() {
defineA(['foo', {
name: 'bar',
calculate: function(data) {
return data.foo * 2;
}
}]);
defineB();
var rec = new B({
foo: 10
});
expect(rec.get('bar')).toBe(20);
});
// This tests the initialization order of the field rankings on the Model
it("should inherit calculated fields when the parent has been instanced first", function() {
defineA(['foo', {
name: 'bar',
calculate: function(data) {
return data.foo * 2;
}
}]);
defineB();
var rec = new A({
foo: 10
});
expect(rec.get('bar')).toBe(20);
rec = new B({
foo: 20
});
expect(rec.get('bar')).toBe(40);
});
})
});
});
describe("proxy", function() {
function defineA(proxy, cfg) {
cfg = Ext.apply({
extend: Ext.data.Model,
fields: ['id'],
proxy: proxy
}, cfg);
A = Ext.define('spec.A', cfg);
}
it("should ask the schema to construct a proxy by default", function() {
defineA();
var schema = A.schema,
schemaConfig = schema.constructProxy(A),
proxy = A.getProxy();
expect(proxy.alias).toEqual(['proxy.' + schemaConfig.type]);
expect(proxy.getUrl()).toBe(schemaConfig.url);
});
it("should use the defaultProxy instead of the schema proxy", function() {
defineA(null, {
statics: {
defaultProxy: { type: 'memory' }
}
});
var schema = A.schema,
schemaConfig = schema.constructProxy(A),
proxy = A.getProxy();
expect(proxy.alias).toEqual(['proxy.memory']);
expect(proxy.alias).not.toEqual(['proxy.' + schemaConfig.type]);
});
it("should create a proxy type string", function() {
defineA('jsonp');
expect(A.getProxy() instanceof Ext.data.proxy.JsonP).toBe(true);
});
it("should create a proxy from a config", function() {
defineA({
type: 'ajax',
url: '/foo'
});
expect(A.getProxy().getUrl()).toBe('/foo');
});
it("should infer the reader type from the proxy", function() {
Ext.define('spec.CustomReader', {
extend: 'Ext.data.reader.Json',
alias: 'reader.custom'
});
Ext.define('spec.CustomProxy', {
extend: 'Ext.data.proxy.Ajax',
alias: 'proxy.custom',
reader: 'custom'
});
defineA('custom');
expect(A.getProxy().getReader().$className).toBe('spec.CustomReader');
Ext.undefine('spec.CustomReader');
Ext.undefine('spec.CustomProxy');
});
it("should use a passed instance", function() {
var proxy = new Ext.data.proxy.Ajax();
defineA(proxy);
expect(A.getProxy()).toBe(proxy);
proxy = null;
});
describe("subclassing", function() {
function defineB(proxy, cfg) {
cfg = Ext.apply({
extend: A
}, cfg);
if (proxy) {
cfg.proxy = proxy;
}
B = Ext.define('spec.B', cfg);
}
it("should inherit a config from the parent", function() {
defineA({
type: 'ajax',
url: '/foo'
});
defineB();
expect(B.getProxy().getUrl()).toBe('/foo');
});
it("should override anything on the parent", function() {
defineA({
type: 'ajax',
url: '/foo'
});
defineB({
type: 'ajax',
url: '/bar'
});
expect(B.getProxy().getUrl()).toBe('/bar');
});
it("should clone an existing instance", function() {
defineA({
type: 'ajax',
url: '/foo'
});
// trigger creation
A.getProxy();
defineB();
expect(B.getProxy()).not.toBe(A.getProxy());
expect(B.getProxy().getUrl()).toBe('/foo');
});
it("should not modify the super instance", function() {
defineA({
type: 'ajax',
url: '/foo'
});
defineB();
B.getProxy().setUrl('/bar');
expect(A.getProxy().getUrl()).toBe('/foo');
});
it("should not use the defaultProxy when defaultProxy is defined on parent", function() {
defineA(null, {
statics: {
defaultProxy: { type: 'memory' }
}
});
defineB();
var schema = B.schema,
schemaConfig = schema.constructProxy(B),
proxy = B.getProxy();
expect(proxy.alias).toEqual(['proxy.' + schemaConfig.type]);
expect(proxy.getUrl()).toBe(schemaConfig.url);
});
});
it("should use a memory proxy for direct instances of Ext.data.Model", function() {
var model = new Ext.data.Model();
expect(model.getProxy().isMemoryProxy).toBe(true);
});
it("should use a memory proxy for direct instances of Ext.data.TreeModel", function() {
var model = new Ext.data.TreeModel();
expect(model.getProxy().isMemoryProxy).toBe(true);
});
});
// TODO:
describe("associations", function() {
});
describe("identifier", function() {
var idgen;
function defineA(identifier, fields, cfg) {
cfg = Ext.apply({
extend: Ext.data.Model,
fields: fields || ['id', 'name'],
identifier: identifier
}, cfg);
A = Ext.define('spec.A', cfg);
}
afterEach(function() {
idgen = null;
var Generator = Ext.data.identifier.Generator;
Generator.all = {
uuid: Generator.all.uuid
}; // clear generator id map
});
it("should default to identifier.Sequential", function() {
defineA();
var r = new A();
expect(r.getId()).toBe('A-1');
r = new A();
expect(r.getId()).toBe('A-2');
});
it("should create an identifier from a type string", function() {
defineA('negative');
var r = new A();
expect(r.getId()).toBe(-1);
r = new A();
expect(r.getId()).toBe(-2);
});
it("should create an identifier from a config object", function() {
defineA({
type: 'sequential',
prefix: 'foo'
});
var r = new A();
expect(r.getId()).toBe('foo1');
r = new A();
expect(r.getId()).toBe('foo2');
});
it("should share an instance across models using an id", function() {
var B = Ext.define('spec.B', {
extend: Ext.data.Model,
identifier: {
// sequential is the default
id: 'x',
prefix: 'ID_',
seed: 1000
}
});
defineA('x');
var a = new A();
var b = new B();
expect(a.id).toBe('ID_1000');
expect(b.id).toBe('ID_1001');
});
describe("subclassing", function() {
function defineB (identifier, cfg) {
cfg = Ext.apply({
extend: A,
identifier: identifier
}, cfg);
B = Ext.define('spec.B', cfg);
}
describe("defined on the subclass", function() {
it("should use a string type", function() {
defineA({
type: 'negative'
});
defineB('sequential');
var a = new A();
var b = new B();
expect(a.id).toBe(-1);
expect(b.id).toBe(1);
});
it("should use an object type", function() {
defineA({
type: 'negative'
});
defineB({
type: 'sequential'
});
var a = new A();
var b = new B();
expect(a.id).toBe(-1);
expect(b.id).toBe(1);
});
it("should use an instance", function() {
idgen = new Ext.data.identifier.Sequential();
defineA({
type: 'sequential'
});
defineB(idgen);
expect(B.identifier).toBe(idgen);
});
});
describe("inheriting from parent", function() {
it("should clone an instance if it's cloneable", function() {
defineA({
type: 'sequential',
prefix: 'foo'
});
defineB();
idgen = B.identifier;
expect(idgen).not.toBe(A.identifier);
expect(idgen.getPrefix()).toBe('foo');
});
it("should not clone the instance if it's not cloneable", function() {
defineA('uuid');
defineB();
expect(B.identifier).toBe(A.identifier);
});
it("should not clone if an id is specified", function() {
defineA({
type: 'sequential',
prefix: 'ID_',
seed: 1000,
id: 'xxx'
});
defineB();
expect(B.identifier).toBe(A.identifier);
var a = new A();
var b = new B();
expect(a.id).toBe('ID_1000');
expect(b.id).toBe('ID_1001');
});
});
});
});
describe("validators", function() {
function validate(cls, fieldName, value) {
var field = cls.getField(fieldName);
return field.validate(value, '|');
}
function expectError(cls, fieldName, value, expected) {
var msg = validate(cls, fieldName, value);
if (msg === true) {
msg = [];
} else {
msg = msg.split('|');
}
expect(msg).toEqual(expected);
}
var presenceMsg = 'Must be present',
formatMsg = 'Is in the wrong format',
emailMsg = 'Is not a valid email address';
describe("on the field", function() {
function defineA(validatorCfg, fields, cfg) {
cfg = Ext.apply({
extend: Ext.data.Model,
fields: fields || [{
name: 'name',
validators: validatorCfg
}]
}, cfg);
A = Ext.define('spec.A', cfg);
}
it("should accept a validator string name", function() {
defineA('presence');
expectError(A, 'name', null, [presenceMsg]);
});
it("should accept an object configuration", function() {
defineA({
type: 'format',
matcher: /foo/
});
expectError(A, 'name', null, [formatMsg]);
});
it("should accept a function", function() {
defineA(function() {
return 'Fail';
});
expectError(A, 'name', null, ['Fail']);
});
it("should accept an array of strings", function() {
defineA(['presence', 'email']);
expectError(A, 'name', null, [presenceMsg, emailMsg]);
});
it("should accept an array of configs", function() {
defineA([{
type: 'presence'
}, {
type: 'format',
matcher: /foo/
}]);
expectError(A, 'name', null, [presenceMsg, formatMsg]);
});
it("should accept an array of functions", function() {
defineA([function() {
return 'Fail1';
}, function() {
return 'Fail2';
}]);
expectError(A, 'name', null, ['Fail1', 'Fail2']);
});
it("should be able to define multiple fields", function() {
defineA(null, [{
name: 'name',
validators: 'presence'
}, {
name: 'email',
validators: 'email'
}]);
expectError(A, 'name', null, [presenceMsg]);
expectError(A, 'email', null, [emailMsg]);
});
});
describe("on the model", function() {
function defineA(validators, fields, cfg) {
cfg = Ext.apply({
extend: Ext.data.Model,
fields: fields || ['id', 'name', 'rank', 'email'],
validators: validators
}, cfg);
A = Ext.define('spec.A', cfg);
}
describe("array style", function() {
it("should accept an array of validators", function() {
defineA([{
field: 'name',
type: 'presence'
}]);
expectError(A, 'name', null, [presenceMsg]);
});
it("should accept multiple validators for a single field", function() {
defineA([{
field: 'name',
type: 'presence'
}, {
field: 'name',
type: 'format',
matcher: /foo/
}]);
expectError(A, 'name', null, [presenceMsg, formatMsg]);
});
it("should be able to pass validators for multiple fields", function() {
defineA([{
field: 'name',
type: 'presence'
}, {
field: 'email',
type: 'email'
}]);
expectError(A, 'name', null, [presenceMsg]);
expectError(A, 'email', null, [emailMsg]);
});
it("should accept a function validator", function() {
var fn = function() {
return 'Failed';
};
defineA([{
field: 'name',
fn: fn
}]);
expectError(A, 'name', null, ['Failed']);
});
});
describe("object style", function() {
it("should accept a string", function() {
defineA({
name: 'presence'
});
expectError(A, 'name', null, [presenceMsg]);
});
it("should accept a function", function() {
var fn = function() {
return 'Failed';
};
defineA({
name: fn
});
expectError(A, 'name', null, ['Failed']);
});
it("should accept config object", function() {
defineA({
name: {
type: 'format',
matcher: /foo/
}
});
expectError(A, 'name', null, [formatMsg]);
});
it("should accept an array of strings", function() {
defineA({
name: ['presence', 'email']
});
expectError(A, 'name', null, [presenceMsg, emailMsg]);
});
it("should accept an array of functions", function() {
var fn1 = function(){
return 'Fail1';
},
fn2 = function(){
return 'Fail2'
};
defineA({
name: [fn1, fn2]
});
expectError(A, 'name', null, ['Fail1', 'Fail2']);
});
it("should accept an array of objects", function() {
defineA({
name: [{
type: 'format',
matcher: /foo/
}, {
type: 'length',
min: 3
}]
});
expectError(A, 'name', 'x', [formatMsg, 'Length must be at least 3']);
});
it("should accept a mixed array", function() {
var fn = function(){
return 'Fail';
};
defineA({
name: ['email', {
type: 'length',
min: 3
}, fn]
});
expectError(A, 'name', 'x', [emailMsg, 'Length must be at least 3', 'Fail']);
});
it("should be able to declare multiple fields at once", function() {
defineA({
name: 'presence',
email: 'email'
});
expectError(A, 'name', null, [presenceMsg]);
expectError(A, 'email', null, [emailMsg]);
});
});
});
describe("on both the field and model", function() {
function defineA(validators, fields, cfg) {
cfg = Ext.apply({
extend: Ext.data.Model,
fields: fields,
validators: validators
}, cfg);
A = Ext.define('spec.A', cfg);
}
describe("model array style", function() {
it("should merge with a string", function() {
defineA([{
field: 'name',
type: 'presence'
}], [{
name: 'name',
validators: 'email'
}]);
expectError(A, 'name', null, [presenceMsg, emailMsg]);
});
it("should merge with an object", function() {
defineA([{
field: 'name',
type: 'presence'
}], [{
name: 'name',
validators: {
type: 'format',