text: const should = require('chai').should();
  const expect = require('chai').expect;
  const qb = require('../../drivers/mysql/query_builder.js').QueryBuilder();
  
  describe('join()', () => {
  	it('should exist', () => {
  		should.exist(qb.join);
  	});
  	it('should be a function', () => {
  		qb.join.should.be.a('function');
  	});
  	it('should have an array to put fields into', () => {
  		qb.should.have.property('join_array');
  	});
  	it('should have an empty array to put fields into at the beginning', () => {
  		qb.join_array.should.be.empty;
  	});
  	it('should require a string to be passed as first parameter', () => {
  		const invalid_match = /must provide a table/;
  		expect(() => qb.join(), 'nothing provided').to.throw(Error, invalid_match);
  		expect(() => qb.join(true), 'true provided').to.throw(Error, invalid_match);
  		expect(() => qb.join(null), 'null provided').to.throw(Error, invalid_match);
  		expect(() => qb.join(false), 'false provided').to.throw(Error, invalid_match);
  		expect(() => qb.join({}), 'object provided').to.throw(Error, invalid_match);
  		expect(() => qb.join([]), 'empty array provided').to.throw(Error, invalid_match);
  		expect(() => qb.join(''), 'empty string provided').to.throw(Error, invalid_match);
  		expect(() => qb.join('  '), 'string of spaces provided').to.throw(Error, invalid_match);
  		expect(() => qb.join('foo'), 'valid string provided').to.not.throw(Error);
  		expect(() => qb.join('foo'), 'valid string provided').to.not.throw(Error);
  	});
  	it('should except single item and add it to join array as basic join and escape item', () => {
  		qb.reset_query();
  		qb.join('universe');
  		qb.join_array.should.eql(['JOIN `universe` ']);
  	});
  	it('should except single item with alias and add it to join array as basic join and escape each part', () => {
  		qb.reset_query();
  		qb.join('universe u');
  		qb.join_array.should.eql(['JOIN `universe` `u` ']);
  	});
  	it('should allow a string (and only a string) to be passed as second parameter but only if a valid (or no) third parameter is provided', () => {
  		const invalid_2nd_param = /You must provide a valid condition to join on when providing a join direction/;
  		const invalid_direction = /Invalid join direction provided as third parameter/;
  
  		expect(() => qb.join('universe',null,'left'), 'null 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe',false,'left'), 'false 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe','','left'), 'empty string 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe','   ','left'), 'just spaces 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe',5,'left'), 'integer 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe',5.6,'left'), 'float 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe',[],'left'), 'array 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe',{},'left'), 'object 2nd param').to.throw(Error,invalid_2nd_param);
  		expect(() => qb.join('universe','foo = bar','fake'), 'invalid 3rd param').to.throw(Error,invalid_direction);
  		expect(() => qb.join('universe','foo = bar'), 'no 3rd param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','left'), '3 valid params').to.not.throw(Error);
  	});
  	it('should allow valid join direction to be passed in third parameter', () => {
  		// NOTE: A lot of this functionality was already tested when testing second param
  		const invalid_direction = /Invalid join direction provided as third parameter/;
  
  		expect(() => qb.join('universe','foo = bar','fake'), 'invalid 3rd param').to.throw(Error,invalid_direction);
  		expect(() => qb.join('universe',null,null), 'invalid 2nd and 3rd params').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',''), 'empty third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','   '), 'just spaces').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',null), 'null third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',false), 'false third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',5), 'integer third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',5.5), 'float third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',{}), 'object third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',[]), 'array third param').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','left  '), 'trailing space').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar',' left '), 'leading and trailing space').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','  left'), 'leading space').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','left'), 'lowercase direction').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','LEFT'), 'uppercase direction').to.not.throw(Error);
  		expect(() => qb.join('universe','foo = bar','LEFT OUTER'), 'two word direction').to.not.throw(Error);
  	});
  	it('should except a valid second parameter as a join condition and escape it properly', () => {
  		qb.reset_query();
  		qb.join('universe u','u.type_id = ut.id');
  		qb.join_array.should.eql(['JOIN `universe` `u` ON `u`.`type_id` = `ut`.`id`']);
  	});
  	it('should escape compound objects properly', () => {
  		qb.reset_query();
  		qb.join('universe.galaxy.star_system s','s.type_id = st.id');
  		qb.join_array.should.eql(['JOIN `universe`.`galaxy`.`star_system` `s` ON `s`.`type_id` = `st`.`id`']);
  	});
  	it('should add aliases to alias-tracking array', () => {
  		qb.reset_query();
  		qb.join('universe.galaxy.star_system s');
  		qb.aliased_tables.should.eql(['s']);
  	});
  	it('should properly place join direction into join clause', () => {
  		qb.reset_query();
  		qb.join('universe.galaxy.star_system s', 's.type_id = st.id', 'left outer');
  		qb.join_array.should.eql(['LEFT OUTER JOIN `universe`.`galaxy`.`star_system` `s` ON `s`.`type_id` = `st`.`id`']);
  	});
  	it('should be chainable to allow for multiple join clauses', () => {
  		qb.reset_query();
  		qb.join('star_system s', 's.type_id = st.id', 'left outer').join('planets p','p.star_system_id = s.id','left');
  		qb.join_array.should.eql(['LEFT OUTER JOIN `star_system` `s` ON `s`.`type_id` = `st`.`id`', 'LEFT JOIN `planets` `p` ON `p`.`star_system_id` = `s`.`id`']);
  	});
  	it('should escape complex join conditions', () => {
  		qb.reset_query();
  		qb.join('star_system s', "s.type_id = st.id AND st.active = 1 AND st.created_on > '2014-01-01'", 'left');
  		qb.join_array.should.eql(["LEFT JOIN `star_system` `s` ON `s`.`type_id` = `st`.`id` AND `st`.`active` = 1 AND `st`.`created_on` > '2014-01-01'"]);
  	});
      it('should NOT escape any part of join query when asked not to', () => {
  		qb.reset_query();
  		qb.join('star_system s', "s.type_id = st.id AND st.active = 1 AND st.created_on > '2014-01-01'", 'left', false);
  		qb.join_array.should.eql(["LEFT JOIN star_system s ON s.type_id = st.id AND st.active = 1 AND st.created_on > '2014-01-01'"]);
  	});
  });
  