/// <reference path="../typings/tsd.d.ts" />
'use strict'

import * as chai from 'chai';
import * as helpers from './helpers';
import {Query} from '../src/blow-query';

const expect = chai.expect;

describe('Query', () => {
  let query: Query; 
  helpers.checkClassExport(Query);
 
  beforeEach(() => {
    query = new Query();
  });
 
  it('constructor', () => {
      query = new Query({limit: 10});
      expect(query.toJSON().limit).to.be.equal(10);
      query.limit(20);
      query = new Query(query);
      expect(query.toJSON().limit).to.be.equal(20);
  });
 
  describe('operators', () => {
    it('equal', () => {
      expect(query.equal('name', 'First').toJSON()).to.be.deep.equal({where: {name: 'First'}});
    });
    it('not equal', () => {
      expect(query.equal('name', 'First').toJSON()).to.be.deep.equal({where: {name: 'First'}});
      expect(query.notEqual('name', 'First').toJSON()).to.be.deep.equal({where: {name: {$neq: 'First'}}});
    });
    it('lessThan', () => {
      expect(query.lessThan('price', 200).toJSON()).to.be.deep.equal({where: {price: {$lt: 200}}});
    });
    it('lessThanOrEqual', () => {
      expect(query.lessThanOrEqual('price', 200).toJSON()).to.be.deep.equal({where: {price: {$lte: 200}}});
    });
    it('greaterThan', () => {
      expect(query.greaterThan('price', 200).toJSON()).to.be.deep.equal({where: {price: {$gt: 200}}});
    });
    it('greaterThanOrEqual', () => {
      expect(query.greaterThanOrEqual('price', 200).toJSON()).to.be.deep.equal({where: {price: {$gte: 200}}});
    });
    it('containedIn', () => {
      expect(query.containedIn('price', [1, 0]).toJSON()).to.be.deep.equal({where: {price: {$in: [1, 0]}}});
    });
    it('notContainedIn', () => {
      expect(query.notContainedIn('price', [1, 0]).toJSON()).to.be.deep.equal({where: {price: {$nin: [1, 0]}}});
    });    
    it('regex', () => {
      expect(query.regex('price', /dd/).toJSON()).to.be.deep.equal({where: {price: {$regex: /dd/}}});
    });
    it('contains', () => {
      expect(query.contains('price', 'dd').toJSON()).to.be.deep.equal({where: {price: {$regex: 'dd'}}});
    });
    it('startsWith', () => {
      expect(query.startsWith('price', 'dd').toJSON()).to.be.deep.equal({where: {price: {$regex: '^dd'}}});
    });
    it('endsWith', () => {
      expect(query.endsWith('price', 'dd').toJSON()).to.be.deep.equal({where: {price: {$regex: 'dd$'}}});
    });    
    it('ascending', () => {
      expect(query.ascending('price').toJSON()).to.be.deep.equal({sort: {price: 1}});
    });
    it('descending', () => {
      expect(query.descending('price').toJSON()).to.be.deep.equal({sort: {price: -1}});
    });
    it('skip', () => {
      expect(query.skip(3).toJSON()).to.be.deep.equal({skip: 3});
    });
    it('limit', () => {
      expect(query.limit(10).toJSON()).to.be.deep.equal({limit: 10});
    });
    it('select', () => {
      expect(query.select('name').toJSON()).to.be.deep.equal({select: ['name']});
      expect(query.select('age').toJSON()).to.be.deep.equal({select: ['name', 'age']});
    });
    it('or', () => {
      const q = new Query();
      q.equal('age', 10);
      query.equal('name', 'Tom');
      expect(query.or(q).toJSON()).to.be.deep.equal({where: {$or: [{'name': 'Tom'}, {age: 10}]}});
    });
  });
});