text:
import { ERROR_FIELD_REQUIRED } from '../src/errors';
import FieldAllowedError from '../src/errors/FieldAllowedError';
import FieldDeniedError from '../src/errors/FieldDeniedError';
import FieldError from '../src/errors/FieldError';
import FieldFormatError from '../src/errors/FieldFormatError';
import FieldLengthError from '../src/errors/FieldLengthError';
import FieldMaxError from '../src/errors/FieldMaxError';
import FieldMaxLengthError from '../src/errors/FieldMaxLengthError';
import FieldMaxWordsError from '../src/errors/FieldMaxWordsError';
import FieldMinError from '../src/errors/FieldMinError';
import FieldMinLengthError from '../src/errors/FieldMinLengthError';
import FieldMinWordsError from '../src/errors/FieldMinWordsError';
import FieldNullableError from '../src/errors/FieldNullableError';
import FieldPatternError from '../src/errors/FieldPatternError';
import FieldRequiredError from '../src/errors/FieldRequiredError';
import FieldTypeError from '../src/errors/FieldTypeError';
import ValidationError from '../src/errors/ValidationError';
import SchemaField from '../src/SchemaField';

describe('SchemaField', () => {
  it('should be importable from package', () => {
    expect(typeof SchemaField).toEqual('function');
  });

  describe('clean(any)', () => {
    describe('with clean: Function', () => {
      const field = new SchemaField('field', {
        clean: (value) => value.trim(),
      });

      it('should return the cleaned value', () => {
        expect(field.clean(' test ')).toBe('test');
      });
    });

    describe('with clean: undefined', () => {
      const field = new SchemaField('field', {});

      it('should return the same input value', () => {
        expect(field.clean(' test ')).toBe('test');
      });
    });
  });

  describe('getAllowed()', () => {
    describe('with allowed: Array', () => {
      it('should return an array', () => {
        const field = new SchemaField('field', { allowed: [1, 0] });
        expect(field.getAllowed()).toStrictEqual([1, 0]);
      });
    });

    describe('with allowed: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getAllowed()).toBeUndefined();
      });
    });
  });

  describe('getDefaultValue()', () => {
    describe('with defaultValue: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { defaultValue: 99 });
        expect(field.getDefaultValue()).toBe(99);
      });
    });

    describe('with defaultValue: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getDefaultValue()).toBeUndefined();
      });
    });
  });

  describe('getDenied()', () => {
    describe('with denied: Array', () => {
      it('should return an array', () => {
        const field = new SchemaField('field', { denied: [1, 0] });
        expect(field.getDenied()).toStrictEqual([1, 0]);
      });
    });

    describe('with denied: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getDenied()).toBeUndefined();
      });
    });
  });

  describe('getFormat()', () => {
    describe('with format: String', () => {
      it('should return format', () => {
        const field = new SchemaField('field', { format: 'date' });
        expect(field.getFormat()).toEqual('date');
      });
    });

    describe('with format: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getFormat()).toBeUndefined();
      });
    });
  });

  describe('getItems()', () => {
    describe('with items: Object', () => {
      it('should return items', () => {
        const field = new SchemaField('field', { items: {} });
        expect(field.getItems()).toEqual({});
      });
    });

    describe('with items: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getItems()).toBeUndefined();
      });
    });
  });

  describe('getLabel()', () => {
    describe('with label: String', () => {
      it('should return label', () => {
        const field = new SchemaField('field', { label: 'My Field' });
        expect(field.getLabel()).toEqual('My Field');
      });
    });

    describe('with label: undefined', () => {
      it('should return field\'s name', () => {
        const field = new SchemaField('field', {});
        expect(field.getLabel()).toBe('field');
      });
    });
  });

  describe('getLength()', () => {
    describe('with length: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { length: 30 });
        expect(field.getLength()).toBe(30);
      });
    });

    describe('with length: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getLength()).toBeUndefined();
      });
    });
  });

  describe('getMaxLength()', () => {
    describe('with maxLength: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { maxLength: 30 });
        expect(field.getMaxLength()).toBe(30);
      });
    });

    describe('with maxLength: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getMaxLength()).toBeUndefined();
      });
    });
  });

  describe('getMax()', () => {
    describe('with max: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { max: 30 });
        expect(field.getMax()).toBe(30);
      });
    });

    describe('with max: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getMax()).toBeUndefined();
      });
    });
  });

  describe('getMaxWords()', () => {
    describe('with maxWords: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { maxWords: 30 });
        expect(field.getMaxWords()).toBe(30);
      });
    });

    describe('with maxWords: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getMaxWords()).toBeUndefined();
      });
    });
  });

  describe('getMinLength()', () => {
    describe('with minLength: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { minLength: 30 });
        expect(field.getMinLength()).toBe(30);
      });
    });

    describe('with minLength: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getMinLength()).toBeUndefined();
      });
    });
  });

  describe('getMin()', () => {
    describe('with min: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { min: 30 });
        expect(field.getMin()).toBe(30);
      });
    });

    describe('with min: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getMin()).toBeUndefined();
      });
    });
  });

  describe('getMinWords()', () => {
    describe('with minWords: Number', () => {
      it('should return a number', () => {
        const field = new SchemaField('field', { minWords: 30 });
        expect(field.getMinWords()).toBe(30);
      });
    });

    describe('with minWords: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getMinWords()).toBeUndefined();
      });
    });
  });

  describe('getName()', () => {
    it('should return field name', () => {
      const field = new SchemaField('field', {});
      expect(field.getName()).toBe('field');
    });
  });

  describe('getPattern()', () => {
    describe('with pattern: RegExp', () => {
      it('should return a RegExp', () => {
        const field = new SchemaField('field', { pattern: /^[0-9]+$/ });
        expect(field.getPattern()).toBeInstanceOf(RegExp);
      });
    });

    describe('with pattern: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getPattern()).toBeUndefined();
      });
    });
  });

  describe('getType()', () => {
    describe('with type: String', () => {
      it('should return a string', () => {
        const field = new SchemaField('field', { type: 'string' });
        expect(field.getType()).toBe('string');
      });
    });

    describe('with type: undefined', () => {
      it('should return undefined', () => {
        const field = new SchemaField('field', {});
        expect(field.getType()).toBeUndefined();
      });
    });
  });

  describe('isNullable()', () => {
    describe('with nullable: true', () => {
      it('should return true', () => {
        const field = new SchemaField('field', { nullable: true });
        expect(field.isNullable()).toBe(true);
      });
    });

    describe('with nullable: false', () => {
      it('should return false', () => {
        const field = new SchemaField('field', { nullable: false });
        expect(field.isNullable()).toBe(false);
      });
    });

    describe('with nullable: undefined', () => {
      it('should return false', () => {
        const field = new SchemaField('field', {});
        expect(field.isNullable()).toBe(false);
      });
    });
  });

  describe('isRequired()', () => {
    describe('with required: true', () => {
      it('should return true', () => {
        const field = new SchemaField('field', { required: true });
        expect(field.isRequired()).toBe(true);
      });
    });

    describe('with required: false', () => {
      it('should return false', () => {
        const field = new SchemaField('field', { required: false });
        expect(field.isRequired()).toBe(false);
      });
    });

    describe('with required: undefined', () => {
      it('should return false', () => {
        const field = new SchemaField('field', {});
        expect(field.isRequired()).toBe(false);
      });
    });
  });

  describe('parse(any)', () => {
    describe('with type: "boolean"', () => {
      const field = new SchemaField('field', { type: 'boolean' });

      it('should return a boolean', () => {
        expect(field.parse('false')).toBe(false);
        expect(field.parse('true')).toBe(true);
        expect(field.parse('FALSE')).toBe(false);
        expect(field.parse('TRUE')).toBe(true);
      });
    });

    describe('with type: "integer"', () => {
      const field = new SchemaField('field', { type: 'integer' });

      it('should return an integer', () => {
        expect(field.parse('12478.395')).toBe(12478);
        expect(field.parse('3.14')).toBe(3);
      });
    });

    describe('with type: "number"', () => {
      const field = new SchemaField('field', { type: 'number' });

      it('should return a number', () => {
        expect(field.parse('01010')).toBe(1010);
        expect(field.parse('12345')).toBe(12345);
        expect(field.parse('99.99')).toBe(99.99);
      });
    });

    describe('without type', () => {
      const field = new SchemaField('date', {
        parse(value) {
          const [year, month, day] = value.split('-');
          return new Date(year, parseInt(month, 10) - 1, day);
        },
      });

      it('should return value using parse function', () => {
        expect(field.parse('2018-04-05'))
          .toMatchObject(new Date(2018, 3, 5));
      });
    });
  });

  describe('validate(object)', () => {
    describe('with incorrect value', () => {
      const field = new SchemaField('field', { required: true });
      let error;

      try {
        field.validate(undefined);
      } catch (e) {
        error = e;
      }

      it('should throw FieldError', () => {
        expect(error).toBeInstanceOf(FieldRequiredError);
        expect(error).not.toBeUndefined();
      });

      it('should throw a FieldError with a "field" attribute', () => {
        expect(error.field).toBe('field');
      });

      it('should throw a FieldError with a "path" attribute', () => {
        expect(error.path).toBe('field');
      });

      it('should throw a FieldError with a "reason" attribute', () => {
        expect(error.reason).toBe(ERROR_FIELD_REQUIRED);
      });
    });

    describe('with allowed and denied', () => {
      it('should throw TypeError', () => {
        expect(() => (
          new SchemaField('field', {
            allowed: ['red'],
            denied: ['blue'],
          })
        )).toThrow(TypeError);
      });
    });

    describe('with allowed: (Array|Function)', () => {
      describe('allowed: Array', () => {
        const field = new SchemaField('field', { allowed: ['off', 'on'] });

        describe('with Array', () => {
          describe('with allowed values', () => {
            it('should not throw FieldAllowedError', () => {
              expect(() => { field.validate(['on']); })
                .not.toThrow(FieldAllowedError);
            });
          });

          describe('without allowed values', () => {
            it('should throw FieldAllowedError', () => {
              expect(() => { field.validate(['yes']); })
                .toThrow(FieldAllowedError);
            });
          });
        });
      });

      describe('allowed: Function', () => {
        const field = new SchemaField('field', {
          allowed: () => (['off', 'on']),
        });

        describe('with allowed values', () => {
          it('should not throw FieldAllowedError', () => {
            expect(() => { field.validate(['on']); })
              .not.toThrow(FieldAllowedError);
          });
        });

        describe('without allowed values', () => {
          it('should throw FieldAllowedError', () => {
            expect(() => { field.validate(['yes']); })
              .toThrow(FieldAllowedError);
          });
        });
      });
    });

    describe('with check: Function', () => {
      describe('check: Function', () => {
        const field = new SchemaField('field', {
          check: (value) => value % 2 === 0,
        });

        describe('with correct value', () => {
          it('should not throw FieldError', () => {
            expect(() => { field.validate(2); })
              .not.toThrow(FieldError);
          });
        });

        describe('with incorrect value', () => {
          it('should throw FieldError', () => {
            expect(() => { field.validate(1); })
              .toThrow(FieldError);
          });
        });
      });
    });

    describe('with defaultValue: (*|Function)', () => {
      describe('with option required=false', () => {
        const field = new SchemaField('field', {
          defaultValue: 'default',
          nullable: true,
          required: false,
        });

        describe('with null', () => {
          it('should not return default value', () => {
            expect(field.validate(null)).toBeNull();
          });
        });

        describe('with undefined', () => {
          it('should not return default value', () => {
            expect(field.validate(undefined)).toBeUndefined();
          });
        });
      });

      describe('with option required=true', () => {
        describe('defaultValue: Boolean', () => {
          const field = new SchemaField('field', {
            defaultValue: false,
            required: true,
          });

          describe('with undefined', () => {
            it('should return default value', () => {
              expect(field.validate(undefined)).toBe(field.getDefaultValue());
            });
          });

          describe('with value', () => {
            it('should not return default value', () => {
              expect(field.validate(true)).toBe(true);
            });
          });
        });

        describe('defaultValue: Function', () => {
          const defaultValue = () => new Date().getFullYear();
          const field = new SchemaField('field', {
            defaultValue,
            required: true,
          });

          describe('with undefined', () => {
            it('should return default value', () => {
              expect(field.validate(undefined)).toBe(defaultValue());
            });
          });

          describe('with value', () => {
            it('should not return default value', () => {
              expect(field.validate(2020)).toBe(2020);
            });
          });
        });

        describe('defaultValue: Number', () => {
          const field = new SchemaField('field', {
            defaultValue: 100,
            required: true,
          });

          describe('with undefined', () => {
            it('should return default value', () => {
              expect(field.validate(undefined)).toBe(field.getDefaultValue());
            });
          });

          describe('with value', () => {
            it('should not return default value', () => {
              expect(field.validate(50)).toBe(50);
            });
          });
        });

        describe('defaultValue: String', () => {
          const field = new SchemaField('field', {
            defaultValue: 'default',
            required: true,
          });

          describe('with undefined', () => {
            it('should return default value', () => {
              expect(field.validate(undefined)).toBe(field.getDefaultValue());
            });
          });

          describe('with value', () => {
            it('should not return default value', () => {
              expect(field.validate('test')).toBe('test');
            });
          });
        });

        describe('defaultValue: [Number]', () => {
          const field = new SchemaField('field', {
            type: ['number'],
            required: true,
            defaultValue: [0, 2],
          });

          describe('empty array', () => {
            it('should return default values', () => {
              expect(field.validate(undefined)).toEqual([0, 2]);
              expect(field.validate(null)).toEqual([0, 2]);
            });
          });

          describe('filled array', () => {
            it('should not be replaced with default value', () => {
              expect(field.validate([1, 3])).toEqual([1, 3]);
            });
          });
        });
      });
    });

    describe('with denied: (Array|Function)', () => {
      describe('denied: Array', () => {
        const field = new SchemaField('field', { denied: ['off', 'on'] });

        describe('with denied values', () => {
          it('should throw FieldDeniedError', () => {
            expect(() => { field.validate(['on']); })
              .toThrow(FieldDeniedError);
          });
        });

        describe('without denied values', () => {
          it('should not throw FieldDeniedError', () => {
            expect(() => { field.validate(['yes']); })
              .not.toThrow(FieldDeniedError);
          });
        });
      });

      describe('denied: Function', () => {
        const field = new SchemaField('field', {
          denied: () => (['off', 'on']),
        });

        describe('with denied values', () => {
          it('should throw FieldDeniedError', () => {
            expect(() => { field.validate(['on']); })
              .toThrow(FieldDeniedError);
          });
        });

        describe('without denied values', () => {
          it('should not throw FieldDeniedError', () => {
            expect(() => { field.validate(['yes']); })
              .not.toThrow(FieldDeniedError);
          });
        });
      });
    });

    describe('with items: (Object)', () => {
      describe('items.type: "boolean"', () => {
        const field = new SchemaField('field', {
          items: { type: 'boolean' },
        });

        describe('with boolean values', () => {
          it('should not throw ValidationError', () => {
            expect(() => { field.validate([true, false]); })
              .not.toThrow(ValidationError);
          });
        });

        describe('with mixed values', () => {
          it('should throw ValidationError', () => {
            expect(() => {
              field.validate([true, 100, 'false']);
            }).toThrow(ValidationError);
          });
        });
      });

      describe('items.type: "number"', () => {
        const field = new SchemaField('field', {
          items: { type: 'number' },
        });

        describe('with number values', () => {
          it('should not throw ValidationError', () => {
            expect(() => { field.validate([0, 1]); })
              .not.toThrow(ValidationError);
          });
        });

        describe('with mixed values', () => {
          it('should throw ValidationError', () => {
            expect(() => {
              field.validate([true, 100, 'false']);
            }).toThrow(ValidationError);
          });
        });
      });

      describe('items.type: "object"', () => {
        const field = new SchemaField('field', {
          items: { type: 'object' },
        });

        describe('with objects', () => {
          it('should not throw ValidationError', () => {
            expect(() => { field.validate([{}, []]); })
              .not.toThrow(ValidationError);
          });
        });

        describe('with mixed values', () => {
          it('should throw ValidationError', () => {
            expect(() => {
              field.validate([true, 100, 'false']);
            }).toThrow(ValidationError);
          });
        });
      });

      describe('items.type: "string"', () => {
        const field = new SchemaField('field', {
          items: { type: 'string' },
        });

        describe('with string values', () => {
          it('should not throw ValidationError', () => {
            expect(() => { field.validate(['a', 'b']); })
              .not.toThrow(ValidationError);
          });
        });

        describe('with mixed values', () => {
          it('should throw ValidationError', () => {
            expect(() => {
              field.validate([true, 100, 'false']);
            }).toThrow(ValidationError);
          });
        });
      });
    });

    describe('with length: (Number|Function)', () => {
      const field = new SchemaField('field', { length: 2 });

      describe('length: Number', () => {
        describe('with array of correct length', () => {
          it('should not throw FieldLengthError', () => {
            expect(() => { field.validate([1, 2]); })
              .not.toThrow(FieldLengthError);
          });
        });
        describe('with array of incorrect length', () => {
          it('should throw FieldLengthError', () => {
            expect(() => { field.validate([1]); })
              .toThrow(FieldLengthError);
          });
        });

        describe('with object of incorrect length', () => {
          it('should throw FieldLengthError', () => {
            expect(() => { field.validate({ length: 1 }); })
              .toThrow(FieldLengthError);
          });
        });

        describe('with object of correct length', () => {
          it('should not throw FieldLengthError', () => {
            expect(() => { field.validate({ length: 2 }); })
              .not.toThrow(FieldLengthError);
          });
        });

        describe('with string of incorrect length', () => {
          it('should throw FieldLengthError', () => {
            expect(() => { field.validate('x'); })
              .toThrow(FieldLengthError);
          });
        });

        describe('with string of correct length', () => {
          it('should not throw FieldLengthError', () => {
            expect(() => { field.validate('xx'); })
              .not.toThrow(FieldLengthError);
          });
        });
      });

      // todo add tests with length: Function
    });

    describe('with format: (String)', () => {
      describe('format: "date"', () => {
        const field = new SchemaField('field', { format: 'date' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('2020/05/13'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "datetime"', () => {
        const field = new SchemaField('field', { format: 'datetime' });

        describe('with string not containing fraction of seconds and timezone offset', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2021-01-30T08:00:00'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string containing fraction of seconds and not timezone offset', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13T10:00:00.000'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string containing timezone offset and no fraction of seconds', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13T10:00:00-10:00'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string containing timezone offset and fraction of seconds', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13T23:59:59.999-10:00'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of correct format containing Z offset', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13T10:00:00Z'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13 10:00:00'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "date-time"', () => {
        const field = new SchemaField('field', { format: 'date-time' });

        describe('with string containing no timezone offset', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('2021-01-30T08:00:00'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('2020-05-13 10:00:00'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "email"', () => {
        const field = new SchemaField('field', { format: 'email' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('valid.address@mail.com'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('invalid@mail'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "hostname"', () => {
        const field = new SchemaField('field', { format: 'hostname' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('www.host.com'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('www.invalid_host.com'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "ipv4"', () => {
        const field = new SchemaField('field', { format: 'ipv4' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('192.168.1.0'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('256.255.255.255'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "ipv6"', () => {
        const field = new SchemaField('field', { format: 'ipv6' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('ff:ff:ff:ff:ff:ff:ff:ff'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('gf:ff:ff:ff:ff:ff:ff:ff'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "time"', () => {
        const field = new SchemaField('field', { format: 'time' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('12:30:42-10:00'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of correct format containing second fraction', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('12:30:42.000-10:00'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of correct format containing Z offset', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('12:30:42Z'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('12:30:42'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      describe('format: "uri"', () => {
        const field = new SchemaField('field', { format: 'uri' });

        describe('with string of correct format', () => {
          it('should not throw FieldFormatError', () => {
            expect(() => { field.validate('ftp://ftp.is.co.za/rfc/rfc1808.txt'); })
              .not.toThrow(FieldFormatError);
          });
        });

        describe('with string of incorrect format', () => {
          it('should throw FieldFormatError', () => {
            expect(() => { field.validate('https://www.ietf.org/rfc/ rfc2396.txt'); })
              .toThrow(FieldFormatError);
          });
        });
      });

      // todo add tests with format: Function
    });

    describe('with max: (Number|Date|Function)', () => {
      describe('max: Number', () => {
        const field = new SchemaField('field', { max: 0 });

        describe('with number', () => {
          describe('with value higher than max', () => {
            it('should throw FieldMaxError', () => {
              expect(() => { field.validate(10); })
                .toThrow(FieldMaxError);
            });
          });

          describe('with value equal to max', () => {
            it('should not throw FieldMaxError', () => {
              expect(() => { field.validate(0); })
                .not.toThrow(FieldMaxError);
            });
          });

          describe('with value lower than max', () => {
            it('should not throw FieldMaxError', () => {
              expect(() => { field.validate(-10); })
                .not.toThrow(FieldMaxError);
            });
          });
        });

        describe('with array', () => {
          describe('with values higher than max', () => {
            it('should throw FieldMaxError', () => {
              expect(() => { field.validate([10]); })
                .toThrow(FieldMaxError);
            });
          });

          describe('with values equal to max', () => {
            it('should not throw FieldMaxError', () => {
              expect(() => { field.validate([0]); })
                .not.toThrow(FieldMaxError);
            });
          });

          describe('with values lower than max', () => {
            it('should not throw FieldMaxError', () => {
              expect(() => { field.validate([-10]); })
                .not.toThrow(FieldMaxError);
            });
          });
        });
      });

      describe('max: Date', () => {
        const date = new Date();
        const field = new SchemaField('field', { max: date });

        describe('with date higher than max', () => {
          it('should throw FieldMaxError', () => {
            expect(() => { field.validate(new Date(date.getTime() + 1000)); })
              .toThrow(FieldMaxError);
          });
        });

        describe('with date equal to max', () => {
          it('should not throw FieldMaxError', () => {
            expect(() => { field.validate(date); })
              .not.toThrow(FieldMaxError);
          });
        });

        describe('with date lower than max', () => {
          it('should not throw FieldMaxError', () => {
            expect(() => { field.validate(new Date(date.getTime() - 1000)); })
              .not.toThrow(FieldMaxError);
          });
        });
      });

      // todo add tests with max: Function
    });

    describe('with maxLength: (Number|Function)', () => {
      describe('maxLength: Number', () => {
        const field = new SchemaField('field', { maxLength: 5 });

        describe('with string', () => {
          describe('with length higher than maxLength', () => {
            it('should throw FieldMaxLengthError', () => {
              expect(() => { field.validate('000000'); })
                .toThrow(FieldMaxLengthError);
            });
          });

          describe('with length equal to maxLength', () => {
            it('should not throw FieldMaxLengthError', () => {
              expect(() => { field.validate('00000'); })
                .not.toThrow(FieldMaxLengthError);
            });
          });

          describe('with length lower than maxLength', () => {
            it('should not throw FieldMaxLengthError', () => {
              expect(() => { field.validate(''); })
                .not.toThrow(FieldMaxLengthError);
            });
          });
        });

        describe('with array', () => {
          describe('with length higher than maxLength', () => {
            it('should throw FieldMaxLengthError', () => {
              expect(() => { field.validate([0, 0, 0, 0, 0, 0]); })
                .toThrow(FieldMaxLengthError);
            });
          });

          describe('with length equal to maxLength', () => {
            it('should not throw FieldMaxLengthError', () => {
              expect(() => { field.validate([0, 0, 0, 0, 0]); })
                .not.toThrow(FieldMaxLengthError);
            });
          });

          describe('with length lower than maxLength', () => {
            it('should not throw FieldMaxLengthError', () => {
              expect(() => { field.validate([]); })
                .not.toThrow(FieldMaxLengthError);
            });
          });
        });
      });

      // todo add tests with maxLength: Function
    });

    describe('with maxWords: (Number|Function)', () => {
      describe('maxWords: Number', () => {
        const field = new SchemaField('field', { maxWords: 5 });

        describe('with length higher than maxWords', () => {
          it('should throw FieldMaxWordsError', () => {
            expect(() => { field.validate('0 0 0 0 0 0'); })
              .toThrow(FieldMaxWordsError);
          });
        });

        describe('with length equal to maxWords', () => {
          it('should not throw FieldMaxWordsError', () => {
            expect(() => { field.validate('0 0 0 0 0'); })
              .not.toThrow(FieldMaxWordsError);
          });
        });

        describe('with length lower than maxWords', () => {
          it('should not throw FieldMaxWordsError', () => {
            expect(() => { field.validate(''); })
              .not.toThrow(FieldMaxWordsError);
          });
        });
      });

      // todo add tests with maxWords: Function
    });

    describe('with min: (Number|Date|Function)', () => {
      describe('min: Number', () => {
        const field = new SchemaField('field', { min: 0 });

        describe('with number', () => {
          describe('with value lower than min', () => {
            it('should throw FieldMinError', () => {
              expect(() => { field.validate(-10); })
                .toThrow(FieldMinError);
            });
          });

          describe('with value equal to min', () => {
            it('should not throw FieldMinError', () => {
              expect(() => { field.validate(0); })
                .not.toThrow(FieldMinError);
            });
          });

          describe('with value higher than min', () => {
            it('should not throw FieldMinError', () => {
              expect(() => { field.validate(10); })
                .not.toThrow(FieldMinError);
            });
          });
        });

        describe('with array', () => {
          describe('with values lower than min', () => {
            it('should throw FieldMinError', () => {
              expect(() => { field.validate([-10]); })
                .toThrow(FieldMinError);
            });
          });

          describe('with values equal to min', () => {
            it('should not throw FieldMinError', () => {
              expect(() => { field.validate([0]); })
                .not.toThrow(FieldMinError);
            });
          });

          describe('with values higher than min', () => {
            it('should not throw FieldMinError', () => {
              expect(() => { field.validate([10]); })
                .not.toThrow(FieldMinError);
            });
          });
        });
      });

      describe('min: Date', () => {
        const date = new Date();
        const field = new SchemaField('field', { min: date });

        describe('with date lower than min', () => {
          it('should throw FieldMinError', () => {
            expect(() => { field.validate(new Date(date.getTime() - 1000)); })
              .toThrow(FieldMinError);
          });
        });

        describe('with date equal to min', () => {
          it('should not throw FieldMinError', () => {
            expect(() => { field.validate(date); })
              .not.toThrow(FieldMinError);
          });
        });

        describe('with date higher than min', () => {
          it('should not throw FieldMinError', () => {
            expect(() => { field.validate(new Date(date.getTime() + 1000)); })
              .not.toThrow(FieldMinError);
          });
        });
      });

      // todo add tests with min: Function
    });

    describe('with minLength: (Number|Function)', () => {
      describe('minLength: Number', () => {
        const field = new SchemaField('field', { minLength: 5 });

        describe('with string', () => {
          describe('with length lower than minLength', () => {
            it('should throw FieldMinLengthError', () => {
              expect(() => { field.validate(''); })
                .toThrow(FieldMinLengthError);
            });
          });

          describe('with length equal to minLength', () => {
            it('should not throw FieldMinLengthError', () => {
              expect(() => { field.validate('00000'); })
                .not.toThrow(FieldMinLengthError);
            });
          });

          describe('with length higher than minLength', () => {
            it('should not throw FieldMinLengthError', () => {
              expect(() => { field.validate('000000'); })
                .not.toThrow(FieldMinLengthError);
            });
          });
        });

        describe('with array', () => {
          describe('with length lower than minLength', () => {
            it('should throw FieldMinLengthError', () => {
              expect(() => { field.validate([]); })
                .toThrow(FieldMinLengthError);
            });
          });

          describe('with length equal to minLength', () => {
            it('should not throw FieldMinLengthError', () => {
              expect(() => { field.validate([0, 0, 0, 0, 0]); })
                .not.toThrow(FieldMinLengthError);
            });
          });

          describe('with length higher than minLength', () => {
            it('should not throw FieldMinLengthError', () => {
              expect(() => { field.validate([0, 0, 0, 0, 0, 0]); })
                .not.toThrow(FieldMinLengthError);
            });
          });
        });
      });

      // todo add tests with minLength: Function
    });

    describe('with minWords: (Number|Function)', () => {
      describe('minWords: Number', () => {
        const field = new SchemaField('field', { minWords: 5 });

        describe('with length lower than minWords', () => {
          it('should throw FieldMinWordsError', () => {
            expect(() => { field.validate(''); })
              .toThrow(FieldMinWordsError);
          });
        });

        describe('with length equal to minWords', () => {
          it('should not throw FieldMinWordsError', () => {
            expect(() => { field.validate('0 0 0 0 0'); })
              .not.toThrow(FieldMinWordsError);
          });
        });

        describe('with length higher than minWords', () => {
          it('should throw FieldMinWordsError', () => {
            expect(() => { field.validate('0 0 0 0 0 0'); })
              .not.toThrow(FieldMinWordsError);
          });
        });
      });

      // todo add tests with minWords: Function
    });

    describe('with nullable: (Boolean|Function)', () => {
      describe('nullable: true', () => {
        const field = new SchemaField('field', { nullable: true });

        describe('with undefined', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(undefined); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with null', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(null); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with empty string', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(''); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with boolean', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(false); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with number', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(1337); })
              .not.toThrow(FieldNullableError);
          });
        });
      });

      describe('nullable: false', () => {
        const field = new SchemaField('field', { nullable: false });

        describe('with undefined', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(undefined); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with null', () => {
          it('should throw FieldNullableError', () => {
            expect(() => { field.validate(null); })
              .toThrow(FieldNullableError);
          });
        });

        describe('with empty string', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(''); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with boolean', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(false); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with number', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(1337); })
              .not.toThrow(FieldNullableError);
          });
        });
      });

      describe('nullable: Function', () => {
        const options = { context: { checked: false } };
        const field = new SchemaField('field', {
          nullable: (context) => context.checked === false,
        });

        describe('with undefined', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(undefined, options); })
              .not.toThrow(FieldNullableError);
          });
        });

        describe('with null', () => {
          it('should not throw FieldNullableError', () => {
            expect(() => { field.validate(null, options); })
              .not.toThrow(FieldNullableError);
          });
        });
      });
    });

    describe('with pattern: (String|RegExp|Function)', () => {
      describe('pattern: String', () => {
        const field = new SchemaField('field', { pattern: '^[01]+$' });

        describe('with incorrect value', () => {
          it('should throw FieldPatternError', () => {
            expect(() => { field.validate('12345'); })
              .toThrow(FieldPatternError);
          });
        });

        describe('with correct value', () => {
          it('should not throw FieldPatternError', () => {
            expect(() => { field.validate('01101'); })
              .not.toThrow(FieldPatternError);
          });
        });

        describe('with undefined', () => {
          it('should not throw FieldPatternError', () => {
            expect(() => { field.validate(undefined); })
              .not.toThrow(FieldPatternError);
          });
        });
      });

      describe('pattern: RegExp', () => {
        const field = new SchemaField('field', { pattern: /^[01]+$/ });

        describe('with incorrect value', () => {
          it('should throw FieldPatternError', () => {
            expect(() => { field.validate('12345'); })
              .toThrow(FieldPatternError);
          });
        });

        describe('with correct value', () => {
          it('should not throw FieldPatternError', () => {
            expect(() => { field.validate('01101'); })
              .not.toThrow(FieldPatternError);
          });
        });

        describe('with undefined', () => {
          it('should not throw FieldPatternError', () => {
            expect(() => { field.validate(undefined); })
              .not.toThrow(FieldPatternError);
          });
        });
      });

      describe('pattern: Function', () => {
        const options = { context: { basic: true } };
        const field = new SchemaField('field', {
          pattern: (context) => (context.basic ? /^[a-z0-9]+$/ : /^[a-z0-9_-]+$/),
        });

        describe('with incorrect value', () => {
          it('should throw FieldPatternError', () => {
            expect(() => { field.validate('abc_123', options); })
              .toThrow(FieldPatternError);
          });
        });

        describe('with correct value', () => {
          it('should not throw FieldPatternError', () => {
            expect(() => { field.validate('abc123', options); })
              .not.toThrow(FieldPatternError);
          });
        });

        describe('with undefined', () => {
          it('should not throw FieldPatternError', () => {
            expect(() => { field.validate(undefined, options); })
              .not.toThrow(FieldPatternError);
          });
        });
      });
    });

    describe('with required: (Boolean|Function)', () => {
      describe('required: true', () => {
        const field = new SchemaField('field', { required: true });

        describe('with undefined', () => {
          it('should throw FieldRequiredError', () => {
            expect(() => { field.validate(undefined); })
              .toThrow(FieldRequiredError);
          });
        });

        describe('with null', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(null); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with empty string', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(''); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with boolean', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(false); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with number', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(1337); })
              .not.toThrow(FieldRequiredError);
          });
        });
      });

      describe('required: false', () => {
        const field = new SchemaField('field', { required: false });

        describe('with undefined', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(undefined); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with null', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(null); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with empty string', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(''); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with boolean', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(false); })
              .not.toThrow(FieldRequiredError);
          });
        });

        describe('with number', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(1337); })
              .not.toThrow(FieldRequiredError);
          });
        });
      });

      describe('required: Function', () => {
        const options = { context: { checked: true } };
        const field = new SchemaField('field', {
          required: (context) => context.checked === true,
        });

        describe('with undefined', () => {
          it('should throw FieldRequiredError', () => {
            expect(() => { field.validate(undefined, options); })
              .toThrow(FieldRequiredError);
          });
        });

        describe('with null', () => {
          it('should not throw FieldRequiredError', () => {
            expect(() => { field.validate(null, options); })
              .not.toThrow(FieldRequiredError);
          });
        });
      });
    });

    describe('with type: (Array|String)', () => {
      describe('type: Array', () => {
        describe('type: ["boolean"]', () => {
          const field = new SchemaField('field', { type: ['boolean'] });

          describe('with boolean values', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate([true, false, false]); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with mixed values', () => {
            it('should throw FieldTypeError', () => {
              expect(() => {
                field.validate([true, 100, 'false']);
              }).toThrow(FieldTypeError);
            });
          });
        });

        describe('type: ["number"]', () => {
          const field = new SchemaField('field', { type: ['number'] });

          describe('with number values', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate([0, 1, 2]); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with mixed values', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([true, 100, 'false']); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: ["object"]', () => {
          const field = new SchemaField('field', { type: ['object'] });

          describe('with objects', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate([{}, {}]); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with mixed values', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([{}, true, 100, 'false']); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: ["string"]', () => {
          const field = new SchemaField('field', { type: ['string'] });

          describe('with string values', () => {
            it('should not throw FieldTypeError', () => {
              const result = () => { field.validate(['a', 'b', 'c']); };
              expect(result).not.toThrow(FieldTypeError);
            });
          });

          describe('with mixed values', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([true, 100, 'false']); })
                .toThrow(FieldTypeError);
            });
          });
        });
      });

      describe('type: String', () => {
        describe('type: "array"', () => {
          const field = new SchemaField('field', { type: 'array' });

          describe('with array', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate([]); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with boolean', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(true); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with number', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(1337); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with object', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate({}); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with string', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate('abc'); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: "boolean"', () => {
          const field = new SchemaField('field', { type: 'boolean' });

          describe('with boolean', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate(true); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with array', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([]); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with number', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(1337); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with object', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate({}); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with string', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate('abc'); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: "integer"', () => {
          const field = new SchemaField('field', { type: 'integer' });

          describe('with integer', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate(1337); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with array', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([]); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with boolean', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(true); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with float', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(99.99); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with object', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate({}); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with string', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate('abc'); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: "number"', () => {
          const field = new SchemaField('field', { type: 'number' });

          describe('with integer', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate(1337); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with float', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate(99.99); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with array', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([]); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with boolean', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(true); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with object', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate({}); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with string', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate('abc'); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: "object"', () => {
          const field = new SchemaField('field', { type: 'object' });

          describe('with object', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate({}); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with array', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate([]); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with boolean', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(true); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with number', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(1337); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with string', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate('abc'); })
                .toThrow(FieldTypeError);
            });
          });
        });

        describe('type: "string"', () => {
          const field = new SchemaField('field', { type: 'string' });

          describe('with string', () => {
            it('should not throw FieldTypeError', () => {
              expect(() => { field.validate('abc'); })
                .not.toThrow(FieldTypeError);
            });
          });

          describe('with array', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate([]); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with boolean', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(true); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with number', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate(1337); })
                .toThrow(FieldTypeError);
            });
          });

          describe('with object', () => {
            it('should throw FieldTypeError', () => {
              expect(() => { field.validate({}); })
                .toThrow(FieldTypeError);
            });
          });
        });
      });
    });

    // todo add tests to check rootOnly option
  });
});

redpajama_set_name: RedPajamaGithub


text:
Merhy vs Clarkson
Saturday 15th December 2018
Spiroudome Arena, Hainaut, Belgium
12 Round Contest @ Cruiserweight
reach 71.7" / 182cm
UD KO TKO KO UD < form RTD TKO TKO TKO UD <
tape rankings @ Cruiserweight
Merhy vs Clarkson Info
Ryad Merhy beat Samuel Clarkson by knockout in the 4th round on Saturday 15th December 2018 at Spiroudome Arena in Hainaut.
The fight took place over rounds in the Cruiserweight division, which meant the weight limit was 200 pounds (14.3 stone or 90.7 KG).
Merhy vs Clarkson stats
Ryad Merhy stepped into the ring with a record of 26 wins, 1 loss and draws, 21 of those wins coming by the way of knock out.
Samuel Clarkson made his way to the ring with a record of 21 wins, 4 loses and draws, with 14 of those wins by knock out.
The stats suggested Merhy had advantage in power over Clarkson, with a 81% knock out percentage over Clarkson's 67%.
Ryad Merhy was the younger man by 2 years, at 28 years old.
Ryad Merhy fought out of the orthodox stance, while Samuel Clarkson was a southpaw.
Merhy was arguably the more experienced fighter, having had 2 more fights, and made his debut in 2013, 1 year and 10 months later than Clarkson, who's first professional fight was in 2011. He had fought 54 more professional rounds, 144 to Clarkson's 90.
Merhy vs Clarkson form
Merhy had beaten 2 of his last 3 opponents, stopping 1 of them, going the distance once.
In his last fight leading up to this contest, he had defeated Demetrius Banks on 20th October 2018 by unanimous decision in their 8 round contest at Country Hall de Liège, Liege, Belgium.
Previous to that, he had defeated Soso Abuladze on 29th June 2018 by knockout in the 6th round at Belleheide Center, Oost-Vlaanderen.
Going into that contest, he had been beaten by Arsen Goulamirian on 24th March 2018 by technical knockout in the 11th round in their WBA World Cruiserweight championship fight at Palais des Sports, Bouches-du-Rhône, France.
Clarkson had lost to all of his last 1 opponents.
In his last fight before this contest, he had lost to Dmitry Bivol on 14th April 2017 by technical knockout in the 4th round in their WBA Interim World Light heavyweight championship fight at MGM National Harbor, Maryland, USA.
Merhy's last 3 fights had come over a period of 6 months and 26 days, meaning he had been fighting on average every 1 month and 21 days. In those fights, he fought a total of 25 rounds, meaning that they had lasted 8.3 rounds on average.
Merhy vs Clarkson News
Sorry, we couldn't find any recent news for Merhy vs Clarkson

redpajama_set_name: RedPajamaCommonCrawl


text:
Europe makes speed limiters, breathalysers, driver monitors mandatory from 2022
Derek Fung
A whole raft of safety features will become compulsory in new cars, trucks, vans and buses from 2022 in a bid to reduce deaths and serious injuries.
The European Commission, Parliament and Council have approved legislation to make a raft of safety features, including intelligent speed limiters, breathalyser interlocks and driver safety monitors, standard on vehicles starting from 2022.
The legislation now waits to be formally approved by the European Parliament and EU member states. Ratification is expected to completed by September 2019.
When approved, a suite of a new safety equipment will become mandatory on all-new vehicles from May 2022. These systems are compulsory for new versions of existing models from May 2024.
One of the headline items of this safety package is intelligent speed limiting, which will use GPS and sign recognition to advise the driver of the current speed limit. It will also reduce engine power to limit the car's speed unless it is manually overridden.
The EU hopes to eliminate drunk driving via the alcohol interlock system, while distraction, drowsiness and inattention monitors will also become standard.
Other safety features mandated from 2022 include advanced autonomous emergency braking, lane keeping assistance, reversing cameras and sensors, event data recorder, improved seat belts, and pole side impact protection.
From 2022 trucks and buses will be required to be detect vulnerable road users at the front and sides, and also improve the driver's direct vision of said road users.
Tyre pressure monitors will become standard on all EU-bound vans, trucks and buses.
According to the EU, the new safety systems are projected to save 7300 lives and prevent 38,900 serious injuries by 2030.
MORE: Safety coverage
2020 Genesis GV80 first drive: Does it hit the mark?
Kia has partnered with Uber to offer free trips to the Australian Open (sponsored)
2020 Jeep Gladiator review: The Wrangler-based ute you've always wanted
How did Audi break the Nürburgring lap record? We ride shotgun in the record-breaking Audi RS Q8
2020 Peugeot 508 GT v Skoda Superb 162TSI comparison
Mitsubishi being investigated in Germany over diesel emissions defeat devices
General Motors unveils autonomous car without steering wheel or pedals
Gone in 60 days: Ford Mustang R-Spec sold out despite $100,000 price
2020 Audi TTS coupe review


text:
Shock as Putin fires chief of staff
The Telegraph • 13 August 2016 2:01PM • 0 comments
MOSCOW - President Vladimir Putin has demoted one of his closest allies in a rare and dramatic shake-up of Russia's top leadership.
Sergei Ivanov, Mr Putin's chief of staff, was relieved of his duties in a televised meeting in the Kremlin on Friday.
He will retain his seat on the Security Council, a consultative body of military and intelligence chiefs that advises Mr Putin.
"We have worked for many years together with great success," Mr Putin told his long-serving ally. "I understand your wish to take on work in other areas. I very much hope that you use your knowledge and experience for effective work in your new role," he said.
"Thank you for your high assessment of my work over the past 17 years," Mr Ivanov replied, referring to his service in government since Mr Putin came to power in 1999.
Mr Ivanov added that his four years and eight months as head of the presidential administration made him the longest serving Kremlin chief of staff since the break-up of the Soviet Union.
Mr Putin appointed Anton Vaino, a little known deputy chief of the presidential administration, as Mr Ivanov's successor. He said that Mr Ivanov had personally recommended Mr Vaino as a replacement.
Mr Ivanov has known Putin since the two served together in the KGB and he has served in a succession of top Kremlin posts.
He was defence minister between 2001 and 2007 and was a first deputy prime minister during Dmitry Medvedev's presidency from 2008 to 2012. Mr Putin at the time was prime minister.
Mr Putin appointed him chief of staff on his return to the Kremlin in 2012.
His new role as Mr Putin's special envoy on conservation, environment and transport will be seen by Kremlinologists as an unequivocal demotion.
A career intelligence officer who speaks fluent English and Swedish, Mr Ivanov was considered one of the most powerful individuals in the country after Mr Putin and has frequently been identified as a likely successor.
He was widely seen by Kremlinologists as a leader of a hawkish, anti-Western camp of former intelligence officers who have come to dominate Kremlin policy making in recent years.
Mr Ivanov is believed to be one of a small clique, including Mr Putin, Nikolai Patrushev, the secretary of the security council, and Alexander Bortnikov, the director of the FSB, the modern-day successor to the KGB, who made the decision to annex Crimea in 2014.
He also has a reputation of being an environmental activist and is widely credited with helping to create a national park in the Russian far east which has played a key role in saving the critically endangered Amur leopard.
In December last year, he cleared his schedule to discuss conservation issues with former Baywatch star Pamela Anderson.
Sergei-Ivanov


text:
Okotoks-based Mullen Group acquires two companies
By Troy Media on July 3, 2019 No Comment
Argus Carriers Ltd. and Inter-Urban Delivery Service Ltd. provide transportation and logistics services in the Lower Mainland of B.C.
Okotoks-based Mullen Group Ltd. has acquired Argus Carriers Ltd. and Inter-Urban Delivery Service Ltd., which provide transportation and logistics services in the Lower Mainland of Vancouver.
Murray Mullen
"I am extremely pleased that Argus and Inter-Urban will now be part of our organization," said Murray Mullen, chairman and chief executive officer, in a news release. "They are another perfect example of the type of investments we make on behalf of our shareholders – profitable, well managed with a strong regional presence. These businesses have a long standing history of providing a quality trucking/logistics service in the province of British Columbia, a tradition we intend to continue to build upon. I would also like to thank Jamil Murji and the ownership group for entrusting the future of these businesses to Mullen Group. We intend to further invest in both companies to capitalize on new opportunities."
Argus was founded in 1948 and has about 95 employees, operating a fleet of 57 trucks and 46 trailers providing general freight services including: local pickup and delivery, warehousing, regional less-than-truckload (LTL), dedicated and line haul trucking from four British Columbia operating terminals – Burnaby, Kelowna, Victoria, and Nanaimo. Also, Argus provides daily LTL service to the Pacific Northwest of the United States.
Inter-Urban was founded in 1974 and has about 70 employees, operating 43 trucks and 26 trailers focusing on critical same day delivery service for the health-care sector including: cross border line haul, cross-border LTL cartage, dedicated and local pickup and delivery. Inter-Urban operates from one terminal based in Abbotsford, B.C.
Mullen said the acquisitions of Argus and Inter-Urban align with its strategy of acquiring transportation and logistics companies that have a strong regional LTL presence centrally located to serve consumers in large urban centres. Collectively, these two business units have generated approximately $25 million in annual revenue, it said.
© Troy Media
Alberta, Alberta economy, Investor Insight, Transportation
Okotoks-based Mullen Group acquires two companies added by Troy Media on July 3, 2019
View all posts by Troy Media →
Contact Us – The Camrose Voice
© 2019, ↑ Camrose Voice


What is a Montana Month to Month Lease Agreement?
Montana Month to Month Lease Agreement: What Is It?
In Montana, a month to month lease agreement is a legal document used to officiate an at-will tenancy agreement between a landlord and a tenant. This means that the lease agreement will be open-ended, renewing automatically at the beginning of each month until the landlord or the tenant decides to terminate the agreement. Oftentimes, landlords prefer long term leases because they are essentially guaranteed that they don't have to go through the process of searching for an ideal tenant, however, these agreements can work well for both the landlord and the tenant. For landlords, these agreements mean that they have more flexibility with the rent prices. If the market changes, the landlord doesn't need to wait until the end of the traditional yearlong lease to change the rent on the apartment, he or she may do so with a month's notice. Furthermore, if the landlord is having problems with the tenant, he or she doesn't have to wait until the end of a yearlong lease to terminate the agreement, a simple 30-day notice will suffice. For tenants, a month to month lease works well because they have the option of only renting the apartment for as long as they need it. Regardless of who terminates the lease first, the landlord or the tenant, it must be done with written notice at least 30 days in advance.
According to Montana law, anyone who wishes to terminate a month to month lease agreement must do so in writing at least 30 days before the termination effective date. In Montana, the tenancy is terminated on the date specified and not contingent on when the rent is paid.


Make sure your journals match your fun personality! Floral & Dots Three-Sized Journals feature three journals with matching themed covers in three different sizes. The smallest of journals features black text on the front with a white background and green dots. The medium features a matching white background with smaller black dots and pink paint marks, and the largest journal has a pink and green floral design with gold embellishments, white text, and a white background. All three notebooks feature white-blank pages inside. Fill one up with your sketches and ideas, then move onto the next, or use each notebook for a different talent or hobby!


text:
Take That hold top album chart spot
Take That retain their number one album position with their latest effort The Flood.
By Alex Goldberg
Take That have spent their second week at the top of the Official UK Top 40 Albums Chart with The Flood.
The latest album, featuring the return of Robbie Williams, sold an additional 208,000 copies this week, adding to last week's record sales of 520,000.
This achievement, record sales within one week, had not been seen in the UK charts for thirteen years.
In second place were boyband rivals JLS, who sold 152,000 copies in their first week of release, which would have reached number one by most weeks' standards throughout 2010.
Overall, the album that sold the most copies came from the compilation category, with Now That's What I Call Music: Volume 77 selling 334,000.
Westlife claim the third spot with their newest album Gravity, selling 95,000 copies in its debut week.
Susan Boyle's The Gift drops one place to number four, while Rihanna's Loud also plummets three places to five. André Rieu & Johann Strauss Orchestra are at number six with their version of Moonlight Sonata, with Bon Jovi's Greatest Hits down one at seven.
Finally, towards the bottom of the top ten, Kings of Leon's Come Around Sundown climbs four places to eight, while Pink's Greatest Hits... So Far!!! and Michael Bublé's Crazy Love land at nine and ten respectively.
The top ten in full:
1. (1) Take That: 'Progress'
2. (-) JLS: 'Outta This World'
3. (-) Westlife: 'Gravity'
4. (3) Susan Boyle: 'The Gift'
5. (2) Rihanna: 'Loud'
6. (4) André Rieu & Johann Strauss Orchestra: 'Moonlight Sonata'
7. (6) Bon Jovi: 'Greatest Hits'
8. (12) Kings of Leon: 'Come Around Sundown'
9. (5) Pink: 'Greatest Hits... So Far!!!'
10. (9) Michael Bublé: 'Crazy Love'
Source: Official Charts Company
> Click here for this week's singles chart
More From UK Album Chart
Ed Sheeran's chart records give Calvin Harris feelings
Ed Sheeran has SIXTEEN songs in the singles top 20
Now La La Land is taking over the UK album chart too
Little Mix now share chart record with Destiny's Child
Little Mix finish 2016 with the UK's No.1 album
Ball and Boe claim the No.1 Christmas album together
Michael Ball and Alfie Boe have this week's No.1 album
Rolling Stones score their first No.1 in over 20 years
They've done it again! Little Mix top the albums chart
Little Mix claim glory with first UK No.1 album
UK Album Chart
Take That hold on to album chart No. 1
Leona holds top spot in UK album chart
New entries take top spots in album chart
Bruno Mars takes album chart top spot
Take That top Christmas albums chart
Westlife LP keeps hold of Irish top spot


text:
Q: Работа с масками Есть ли в Python 3.4 обозначение всех расширений, то есть:
mask = input('Росширение файла: ')

введя сюда символ всех расширений, получить список файлов со всеми расширениями в каталоге.
Интересует реализация поиска по всем расширениям кроме exe.
import os
import fnmatch

path = input('Директория: ')
mask = input('Росширение файла: ')
pattern = input('Сигнатура: ')

for dirpath, dirs, files in os.walk(path):
    for file_name in files:
        if fnmatch.fnmatch(file_name, mask):
            inp = open(os.path.join(dirpath, file_name), 'r')
            for line in inp:
                if pattern in line:
                    print(inp)

A: Символа всех расширений нет, но вашу задачу легко можно решить с помощью функции splitext из модуля os.path, которая разбивает имя файла на основную часть и расширение с точкой:
$ python
>>> from os.path import splitext
>>> splitext('file.txt')
('file', '.txt')
>>> splitext('file.')
('file', '.')
>>> splitext('file')
('file', '')

Ваш пример будет выглядеть так:
import os
from os.path import splitext

path = input('Директория: ')
pattern = input('Сигнатура: ')

for dirpath, dirs, files in os.walk(path):
    for file_name in files:
        fn, fext = splitext(file_name)
        if fext != '.exe':
            inp = open(os.path.join(dirpath, file_name), 'r')
            for line in inp:
                if pattern in line:
                    print(inp)

Можно немного обобщить код, вынеся список расширений-исключений в отдельную переменную:
EXCL_EXTS = ('.exe', )

...

for dirpath, dirs, files in os.walk(path):
    for file_name in files:
        fn, fext = splitext(file_name)
        if fext not in EXCL_EXTS:
            ...

redpajama_set_name: RedPajamaStackExchange


This chapter contains the Jamaica Today, History, Jamaican Way of Life, Jamaican Arts, Landscapes & Wildlife, Directory A–Z, and Transportation chapters from Lonely Planet's Jamaica guidebook.
All the info you need on everything from history, arts and wildlife to flights, public transport, climate, money, the internet... you name it. Get tips for women travellers, gay and lesbian travellers, travellers with disabilities, and travellers with kids. And get the most out of your conversations with a handy language guide and glossary.


Parliamentary Committee on Commissions, Statutory Authorities and State Enterprises (Cosase) has started meeting the former owners of the seven defunct commercial banks that were closed and sold by Bank of Uganda between 1993 and 2017.
The affected banks were Teefe Bank in 1993, International Credit Bank Ltd in 1998, Greenland Bank in 1999, The Co-operative Bank in 1999, National Bank of Commerce(NBC) in 2012, Global Trust Bank in 2014 and the sale of Crane Bank Ltd to DFCU in 2017.
On Monday, the former stakeholders of NBC including Prime Minister Amama Mbabazi, businessman Amos Nzeyi, Mathew Rukikaire and Prof George Kanyeihamba among others appeared before the committee to testify how BoU closed their bank.
Abdu Katuntu, the committee chairperson revealed that within one week, they would have met all stakeholders for the seven banks.
He also noted that by February 22, the committee will have finished its report and hand over to parliament.
NBC was closed in 2012 by the Central Bank citing undercapitalization and later, it was sold to Crane Bank Limited.
Since November, 2018, the committee has been probing top BoU officials over their role in the alleged irregular closure and sale of the seven commercial banks as raised by the Auditor General (AG) John Muwanga's 2017 forensic audit report.


text:
Titus Gheorghe Ionescu () a fost un pilot român de aviație, as al Aviației Române din cel de-al Doilea Război Mondial.

Sublocotenentul av. Titus Gheorghe Ionescu a fost decorat cu Ordinul "Virtutea Aeronautică" de Război cu spade, clasa Crucea de Aur cu 1 baretă (28 noiembrie 1941) pentru că "a executat 72 misiuni la inamic, dovedindu-se a fi un pilot cu calități excepționale și foarte bun șef de patrulă. A condus patrula în atacurile A. c. A. inamic și a trupelor terestre, obținând rezultate frumoase".

Decorații
  Ordinul "Virtutea Aeronautică" de Război cu spade, clasa Crucea de Aur cu 1 baretă (28 noiembrie 1941)

Note

Nașteri în secolul al XX-lea
Decese în secolul al XX-lea
Ași ai aviației române din cel de-al Doilea Război Mondial
Decorați cu Ordinul Virtutea Aeronautică

redpajama_set_name: RedPajamaWikipedia


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Usnea perplectans Stirt.

### Remarks
null


Search your Church Community Builder public groups. Choose which values are available to filter by. Turn on/off individual filters. Easily embedded on any page via the Customizer or a shortcode.
Initiate a pre-defined group search from any page on your site.
All price options are billed yearly. You may cancel your subscription at any time. Add-ons subject to yearly license for support and updates.


text:
Biografia
Dopo aver conseguito la laurea all'Università di Bologna con 110 e lode, un Master of Arts in scienze politiche alla Johns Hopkins University e aver conseguito il titolo di Philosophy Doctor, Pelizzo inizia a insegnare alla Johns Hopkins University, a Baltimora.

Già Assistant professor al la Singapore Management University, fellow del Centre of governance and public policy, membro accademico del Griffith Asia Institute, investigatore associato del Centre of Excellence in Policing and Security, consulente della Banca Mondiale, è professore associato e vice decano per la ricerca alla Graduate School of Public Policy della Nazarbayev University dove è stato anche vice decano per gli affari accademici dal 2015 al 2017. Dal 2004 al 2010 ha fatto parte del comitato scientifico di Politics and Policy, di cui è attualmente Direttore Associato. Il suo saggio Tools for Legislative Oversight è stato discusso nel Parlamento delle Filippine. Il suo The role of parliament in curbing corruption ha stimolato alcune iniziative legislative in Tanzania. Ha partecipato al dibattito sulle riforme costituzionali in Kazakistan e sul disegno di legge sul controllo parlamentare in Bosnia-Herzegovina.

Autore di numerosi studi apparsi su riviste scientifiche internazionali, tra le quali Party Politics, Political Studies, Governance, West European Politics e Journal of democracy. Alcuni dei quali sono stati tradotti in arabo, cinese, inglese, italiano, francese, tedesco, russo, spagnolo, vietnamita, indonesiano e kazako. Pelizzo è inoltre autore di 14 libri. Nel 2004 ha vinto il Wright Memorial Award e ha ricevuto lHonorable mention per la tesi dottorale, e nel 2014 ha vinto il Distinguished Reviewer Award di Politics and Policy. È fra i più attivi peer reviewers dell'Asia Centrale.

Pubblicazioni
The culture of accountability, Routledge, 2022 (con G.Pasquino), ISBN 978-1032319100
How to write a thesis, Calibano editore, 2022 (con A. Kinyondo), ISBN 979-1280224712
Exploring Africa's Labyrinth , Lambert Academic Publishing, 2020, ISBN 978-6200562456
Metodo e contro-metodo, Roma, Armando Edtore, 2019 (con A. Napoli), ISBN 978-88-6081-379-4
Africa Today, Novate Milanese, Prospero Editore, 2018, ISBN 978-8885491403
 Making Tourism Work for Tanzania, Lambert Academic Publishing, 2018 (con A. Kinyondo), ISBN 978-6137420843
 Governance in Africa, Lambert Academic Publishing, 2017 (curatore con Abel Kinyondo), ISBN 978-6202021715
 Tourism in Africa. Development and Inequality, Novate Milanese, Prospero Editore, 2017 (con Abel Kinyondo), ISBN 978-8885491168
 Africa at the Crossroads, Novate Milanese, Prospero Editore, 2017, ISBN 978-8885491175
Understanding good governance, Saarbruecken, Lambert Academic Publishing, 2017 (curatore), ISBN 3-330-04914-6.
 Il Dottor Bolt e altri racconti, Piacenza, Ellade, 2016 (con Antonio Napoli e Danilo Carabotta).
 Corruption and Legislatures, New York, Routledge, 2014 (con F. Stapenhurst), ISBN 0-415-73010-4.
 Following the money: comparing parliamentary public accounts committees, London, Routledge, 2014 (con F.Stapenhurst e K. Jacobs), ISBN 0-7453-3436-9
 Government Accountability and Legislative Oversight, London, Routledge, 2014 (con F. Stapenhurst), ISBN 0-415-73006-6
 Parliamentary Oversight Tools, London, Routledge, 2012 (con F. Stapenhurst), ISBN 0-415-61571-2
 Le strategie della crescita, Napoli, Guida, 2012, ISBN 88-6666-176-7
 Allo Zenit di Nessun Nadir, Napoli, Guida, 2011 (con A. Napoli), ISBN 88-6042-905-6
 The War on Terror and the Growth of Executive Power, London, Routledge, 2010 (curatore, con John E.Owens), ISBN 0-415-50405-8
 Ludica, Singapore, Logic Mills, 2010, ISBN 981-08-5941-4
 Fiscalizacion legislativa y presupuestos, Barcelona, mayol ediciones, 2009 (curatore con R. Stapenhurst), ISBN 958-8307-66-X
 Legislative Oversight and Budgeting, Washington, World Bank, 2008 (curatore con F. Stapenhurst, D. Olson and L. von Trapp), ISBN 0-8213-7611-X
 Cartel Parties and Cartel Party Systems, Saarbrücken, VDN, 2008 (autore), ISBN 3-639-08930-8
 The role of parliament in curbing corruption, Washington, World Bank, 2006 (curatore con F. Stapenhurst e N. Johnston), ISBN 0-8213-6723-4
 Parlamenti democratici, Bologna, il Mulino, 2006 (con Gianfranco Pasquino)
 Tre e mezzo, Verona, Vita Nova, 2004.

Premi
 Vincent Wright Memorial Award, West European Politics, 2004
 Honorable Mention in the competition for the best dissertation, European Politics and Society Section of the American Political Science Association, 2004
 Artinian Award, Southern Political Science Association, 2006
 Medal for the 15th Anniversary of the Academy of Financial Police, Kazakistan, 2014
 Distinguished Reviewer Award, Politics and Policy, 2014
 Medaglia per il grande contributo allo sviluppo della scienza, Ministero dell'Educazione e della Scienza, Repubblica del Kazakistan, 2015.
 Albert Nelson Marquis Lifetime Achievement Award, 2018.

Note

Collegamenti esterni
 Scheda su Library of Congress
 Scheda su Worldcat
 Scheda su ResearchGate
 Scheda su Works.bePress
 Scheda su Researcher ID
 Scheda su SSRN
 Scheda su Scopus
 Scheda su Publons


This certainly sounds funny at first, but it is nothing short of delicious! Imagine the savory, juicy flavor of a fried, breaded chicken paired with the soft, delicate sweetness of a waffle drizzled with just the perfect amount of maple syrup. This is a multi-dimensional e-juice that could be vaped all day!


A lot of folks need to lose some weight primarily that excess 20 or so lbs . which has been carried all over for awhile. When making an attempt to get rid of that excess weight, a lot of people transform to eating plan capsules for aid. The thought of having a capsule to phen375 coupon shed fat would seem easier than several on the other additional difficult alternate options. Do these pills truly do the job?
When you speculate when they get the job done, you can find definitely two methods of checking out it. Most are questioning when you usually takes a tablet and lose weight doing anything you are typically carrying out. There may be not a tablet that should bring about you to shed pounds whilst you carry on the approach to life which has caused you to attain extra bodyweight. If there was a tablet such as this, all people would purchase it and become skinny.
The food plan products that declare to operate have been tested. When a food plan nutritional supplement is analyzed, you'll find two teams of individuals who ended up on food plan and exercise strategies. One team adds the food plan dietary supplement for their routine and the other just carries on with diet program and exercising on your own. Those people while in the group that ate very well and did physical exercises within the tablet generally had far more share body weight reduction compared to other team who were not using the tablet. Any diet plan pill or help is one thing that goes together with the traditional healthy diet and work out prepare. It does not swap these very good behaviors.
In advance of buying a capsule, be sure to study what is in it. It is crucial that you know simply because you can find a historical past of these drugs owning what continues to be found to be unsafe components in them. Be skeptical. When there is nearly anything in it that's questionable, think about not taking the capsule. Be wary of any diet dietary supplement which contains ephedrine. Ephedrine has long been demonstrated to bring about irregular coronary heart rhythms and can trigger heart issues and in some cases dying.
A number of the most effective products have components which will be found in fruits together with other super foodstuff. Even though using this in capsule type can have some benefit, take into account purchasing the actual foodstuff and having it into your whole body as character supposed.
No matter what you choose to try and do, it can be time and energy to halt looking for alternatives to the healthy diet and workout. These two behavior on your own will let you get to your bodyweight reduction plans and will not be averted. No magic capsule will do the work for you. It really is all about building a balanced life-style change.


text:
Home » WDW Planning » Top 5 Smartphone Apps for Your Next Walt Disney World Vacation
Top 5 Smartphone Apps for Your Next Walt Disney World Vacation
POSTED: Mon, 01/18/2016 - 12:00 | POSTED BY: Traci C.
There are certain must-have items that I always have to pack for a Walt Disney World vacation including comfortable shoes, rain ponchos, sunscreen, hand sanitizer, and my handy travel guides full of notes and dog-eared pages. In addition to the non-technical "stuff" I have also discovered a few must-have apps for my smartphone that make vacation life much easier.
What are your must-have smarthphone apps?
There are a lot of great travel- and Disney-related apps out there but these five are my must-haves. We'd love to hear your favorite apps for travel and Disney so be sure to leave us a comment.
1. My Disney Experience: This is pretty much the most important app to have for your Walt Disney World vacation. All of your travel information including hotel reservations, dining reservations, and FastPass+ reservations are in My Disney Experience. On our last visit to Disney World I used this app every single day, at least 10 times a day. We changed FastPass+ times practically every day and sometimes even changed the entire attraction for the FastPass+. We checked wait time for attractions that we didn't FastPass. We checked out menus. And we even looked for the closest restroom. Yeah, the app does that too.
You can also use the app to find Disney PhotoPass photographers, check out times for entertainment options in the theme parks, and locate the nearest Guest Services options including Baby Care Centers, FastPass+ kiosks, and more. Disney will even send you notifications via the app. On our last visit we received notification that one of our FastPass+ attractions was down at the time of our FastPass+ and we had the option to visit a different attraction.
My Disney Experience is a must!
2. Shop Disney Parks: When Disney announced the Shop Disney Parks app I was a bit skeptical about its usefulness. Sure it's fun to sit at home and browse all the fun Disney Parks products but I didn't think it would come in handy at the parks when all the merchandise was at my fingertips. However, on my last trip my nephew saw a Stitch Yoda plush at Disney Springs but we didn't purchase it. This led to many tears until I remembered you can use the app to search for products IN the parks! Sure enough we typed in the product and the app found two locations at Disney's Hollywood Studios where we could buy it. (The app was wrong in that it was only available at ONE store, but it was still useful).
So the next time you're kicking yourself for not buying that must-have item, just check the Shop Disney Parks app. And yes, it's still a great app to browse from the comfort of your own home when you're feeling "homesick" for Disney.
3. AllergyEats Disney World: This is a great app for anyone traveling with food allergies or intolerances! As great at Walt Disney World restaurants are when it comes to food allergies, it's nice to have this app at your fingertips. You can search restaurants at the theme parks, hotels, and the greater Orlando area. Simple select your allergies or intolerances from the list that includes peanuts, tree nuts, dairy, eggs, wheat, gluten, fish, shellfish, sesame, and soy, and the app shows you the ranking of each location along with reviews from AllergyEats members.
If you have a good, great, or not-so-great experience or dining tip you can also share that on the app. And if you discover that a particular restaurant isn't yet on the app you can alert AllergyEats and request that it be added.
AllergyEats: Disney World is great for guests with food allergies
4. Fly Delta: We only fly Delta if and when we fly to Orlando (or anywhere else) so the Fly Delta app is part of my smartphone travel arsenal. It's a good app for booking flights, changing flights, checking flight status, tracking your bags, or just finding information about what airport you're flying to or from. If you fly another airline of course I'd recommend using that airline's app instead of Fly Delta, but you get the idea. It's always a good plan to have your airline's app on your phone.
5. Waze: The Waze app is one of my new favorite apps when it comes to travel. I'll be the first to admit that I'm an old fashioned paper maps gal, but maps aren't going to tell you why I-75 suddenly turned into a parking lot just south of the Florida-Georiga state line. But the Waze app will tell you that! I discovered this app on a road trip to the Outer Banks and it was a miracle of technology. When traffic stops and all you can see are cars for miles and miles you can check Waze and odds are there's another Wazer up ahead who has reported what is going on. When reporting traffic issues you can report accidents, traffic jams, cars on the side of the road, and more.
The app even shows you how many Wazers are on the road around you, which is kind of cool yet equally creepy too. The app also shows you a map of the road you're on and how fast the traffic around you is traveling. A total must-have for any road trip to Disney World (or anywhere else.)
Are you a Wazer?
And there you have it, five must-have travel apps for your smartphone when you're traveling to Walt Disney World. What are your must-have apps? Let us know in the comments.
AllergyEats
Baby Care Centers
FASTPASS
FastPass+ reservations
Claire T wrote on Mon, 01/18/2016 - 15:47:
Shop disney app is very spotty. I tried using it my last two trips and it did not work. An email to tech support informed me that not all items are loaded into the app. So good luck.
daybreak1012 wrote on Mon, 01/18/2016 - 18:29:
If it makes you feel a little less creeped out, there is a delay on the Wazers you're seeing in the app on your route. I believe it's two minutes and that the rate of speed isn't exact, so that your privacy is protected, and other users aren't peering into your car, figuring out who you are. ;-)
daydreamer wrote on Tue, 01/19/2016 - 10:31:
I'd also add a navigational app Spyglass into this list. It won't let you get lost, it marks locations for tracking (e.g. your car location) and allows to share you location with friends so that they can easily find you. https://itunes.apple.com/app/spyglass/id332639548?mt=8&at=11lLc7&ct=c
2017 Free Dining Offer Announced for Walt Disney World Resort
Free Dining Announced for Select Dates this Fall at Walt Disney World
Free Dining Announced for Select Travel Dates this Fall at Walt Disney World