12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457 |
- ###
- Copyright (c) 2014 Ramesh Nair (hiddentao.com)
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation
- files (the "Software"), to deal in the Software without
- restriction, including without limitation the rights to use,
- copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the
- Software is furnished to do so, subject to the following
- conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ###
- squel = require "../dist/squel-basic"
- {_, testCreator, assert, expect, should} = require './testbase'
- test = testCreator()
- test['Blocks'] =
- 'Block base class':
- beforeEach: ->
- @inst = new squel.cls.Block()
- 'instanceof of BaseBuilder': ->
- assert.instanceOf @inst, squel.cls.BaseBuilder
- 'options': ->
- expectedOptions = _.extend {}, squel.cls.DefaultQueryBuilderOptions,
- usingValuePlaceholders: true
- dummy: true
- @inst = new squel.cls.Block
- usingValuePlaceholders: true
- dummy: true
- assert.same expectedOptions, @inst.options
- '_toParamString()': ->
- assert.throws (=> @inst.toString()), 'Not yet implemented'
- 'exposedMethods()':
- 'returns methods': ->
- @inst['method1'] = -> return false
- @inst['method2'] = -> return false
- assert.ok ['method1', 'method2'], (name for name of @inst.exposedMethods())
- 'ignores methods prefixed with _': ->
- @inst['_method'] = -> return false
- assert.ok undefined is _.find (name for name of @inst.exposedMethods()), (name) ->
- return name is '_method'
- 'ignores toString()': ->
- assert.ok undefined is _.find (name for name of @inst.exposedMethods()), (name) ->
- return name is 'toString'
- 'cloning copies the options over': ->
- @inst.options.dummy = true;
- newinst = @inst.clone()
- @inst.options.dummy = false;
- assert.same true, newinst.options.dummy
- 'StringBlock':
- beforeEach: ->
- @cls = squel.cls.StringBlock
- @inst = new @cls
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- '_toParamString()':
- 'non-parameterized': ->
- @inst = new @cls {}, 'TAG'
- assert.same @inst._toParamString(), {
- text: 'TAG'
- values: []
- }
- 'parameterized': ->
- @inst = new @cls {}, 'TAG'
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'TAG'
- values: []
- }
- 'FunctionBlock':
- beforeEach: ->
- @cls = squel.cls.FunctionBlock
- @inst = new @cls
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'initial member values': ->
- assert.same [], @inst._values
- assert.same [], @inst._strings
- '_toParamString()':
- 'when not set': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'non-parameterized': ->
- @inst.function('bla')
- @inst.function('bla2')
- assert.same @inst._toParamString(), {
- text: 'bla bla2',
- values: []
- }
- 'parameterized': ->
- @inst.function('bla ?', 2)
- @inst.function('bla2 ?', 3)
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'bla ? bla2 ?',
- values: [2, 3]
- }
- 'AbstractTableBlock':
- beforeEach: ->
- @cls = squel.cls.AbstractTableBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'initial field values': ->
- assert.same [], @inst._tables
- 'has table':
- 'no': ->
- assert.same false, @inst._hasTable()
- 'yes': ->
- @inst._table('blah')
- assert.same true, @inst._hasTable()
- '_table()':
- 'saves inputs': ->
- @inst._table('table1')
- @inst._table('table2', 'alias2')
- @inst._table('table3')
- expectedFroms = [
- {
- table: 'table1',
- alias: null
- },
- {
- table: 'table2',
- alias: 'alias2'
- },
- {
- table: 'table3',
- alias: null
- }
- ]
- assert.same expectedFroms, @inst._tables
- 'sanitizes inputs': ->
- sanitizeTableSpy = test.mocker.stub @cls.prototype, '_sanitizeTable', -> return '_t'
- sanitizeAliasSpy = test.mocker.stub @cls.prototype, '_sanitizeTableAlias', -> return '_a'
- @inst._table('table', 'alias')
- assert.ok sanitizeTableSpy.calledWith 'table'
- assert.ok sanitizeAliasSpy.calledWithExactly 'alias'
- assert.same [ { table: '_t', alias: '_a' }], @inst._tables
- 'handles single-table mode': ->
- @inst.options.singleTable = true
- @inst._table('table1')
- @inst._table('table2')
- @inst._table('table3')
- expected = [
- {
- table: 'table3',
- alias: null
- }
- ]
- assert.same expected, @inst._tables
- 'builder as table': ->
- sanitizeTableSpy = test.mocker.spy @cls.prototype, '_sanitizeTable'
- innerTable1 = squel.select()
- innerTable2 = squel.select()
- @inst._table(innerTable1)
- @inst._table(innerTable2, 'Inner2')
- assert.ok sanitizeTableSpy.calledWithExactly innerTable1
- assert.ok sanitizeTableSpy.calledWithExactly innerTable2
- expected = [
- {
- alias: null
- table: innerTable1
- }
- {
- alias: 'Inner2'
- table: innerTable2
- }
- ]
- assert.same expected, @inst._tables
- '_toParamString()':
- beforeEach: ->
- @innerTable1 = squel.select().from('inner1').where('a = ?', 3)
- 'no table': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'prefix': ->
- @inst.options.prefix = 'TEST'
- @inst._table('table2', 'alias2')
- assert.same @inst._toParamString(), {
- text: 'TEST table2 `alias2`',
- values: []
- }
- 'non-parameterized': ->
- @inst._table(@innerTable1)
- @inst._table('table2', 'alias2')
- @inst._table('table3')
- assert.same @inst._toParamString(), {
- text: '(SELECT * FROM inner1 WHERE (a = 3)), table2 `alias2`, table3'
- values: []
- }
- 'parameterized': ->
- @inst._table(@innerTable1)
- @inst._table('table2', 'alias2')
- @inst._table('table3')
- assert.same @inst._toParamString(buildParameterized: true), {
- text: '(SELECT * FROM inner1 WHERE (a = ?)), table2 `alias2`, table3'
- values: [3]
- }
- 'FromTableBlock':
- beforeEach: ->
- @cls = squel.cls.FromTableBlock
- @inst = new @cls()
- 'check prefix': ->
- assert.same @inst.options.prefix, 'FROM'
- 'instanceof of AbstractTableBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractTableBlock
- 'from()':
- 'calls base class handler': ->
- baseMethodSpy = test.mocker.stub squel.cls.AbstractTableBlock.prototype, '_table'
- @inst.from('table1')
- @inst.from('table2', 'alias2')
- assert.same 2, baseMethodSpy.callCount
- assert.ok baseMethodSpy.calledWithExactly('table1', null)
- assert.ok baseMethodSpy.calledWithExactly('table2', 'alias2')
- 'UpdateTableBlock':
- beforeEach: ->
- @cls = squel.cls.UpdateTableBlock
- @inst = new @cls()
- 'instanceof of AbstractTableBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractTableBlock
- 'check prefix': ->
- assert.same @inst.options.prefix, undefined
- 'table()':
- 'calls base class handler': ->
- baseMethodSpy = test.mocker.stub squel.cls.AbstractTableBlock.prototype, '_table'
- @inst.table('table1')
- @inst.table('table2', 'alias2')
- assert.same 2, baseMethodSpy.callCount
- assert.ok baseMethodSpy.calledWithExactly('table1', null)
- assert.ok baseMethodSpy.calledWithExactly('table2', 'alias2')
- 'TargetTableBlock':
- beforeEach: ->
- @cls = squel.cls.TargetTableBlock
- @inst = new @cls()
- 'instanceof of AbstractTableBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractTableBlock
- 'check prefix': ->
- assert.same @inst.options.prefix, undefined
- 'table()':
- 'calls base class handler': ->
- baseMethodSpy = test.mocker.stub squel.cls.AbstractTableBlock.prototype, '_table'
- @inst.target('table1')
- @inst.target('table2')
- assert.same 2, baseMethodSpy.callCount
- assert.ok baseMethodSpy.calledWithExactly('table1')
- assert.ok baseMethodSpy.calledWithExactly('table2')
- 'IntoTableBlock':
- beforeEach: ->
- @cls = squel.cls.IntoTableBlock
- @inst = new @cls()
- 'instanceof of AbstractTableBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractTableBlock
- 'check prefix': ->
- assert.same @inst.options.prefix, 'INTO'
- 'single table': ->
- assert.ok @inst.options.singleTable
- 'into()':
- 'calls base class handler': ->
- baseMethodSpy = test.mocker.stub squel.cls.AbstractTableBlock.prototype, '_table'
- @inst.into('table1')
- @inst.into('table2')
- assert.same 2, baseMethodSpy.callCount
- assert.ok baseMethodSpy.calledWith('table1')
- assert.ok baseMethodSpy.calledWith('table2')
- '_toParamString()':
- 'requires table to have been provided': ->
- try
- @inst._toParamString()
- throw new Error 'should not reach here'
- catch err
- assert.same 'Error: into() needs to be called', err.toString()
- 'GetFieldBlock':
- beforeEach: ->
- @cls = squel.cls.GetFieldBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'fields() - object':
- 'saves inputs': ->
- fieldSpy = test.mocker.spy(@inst, 'field')
- @inst.fields({
- 'field1': null
- 'field2': 'alias2'
- 'field3': null
- }, { dummy: true})
- expected = [
- {
- name: 'field1',
- alias: null,
- options: {
- dummy: true
- }
- },
- {
- name: 'field2',
- alias: 'alias2'
- options: {
- dummy: true
- }
- },
- {
- name: 'field3',
- alias: null
- options: {
- dummy: true
- }
- }
- ]
- assert.ok fieldSpy.calledThrice
- assert.ok fieldSpy.calledWithExactly('field1', null, dummy: true)
- assert.ok fieldSpy.calledWithExactly('field2', 'alias2', dummy: true)
- assert.ok fieldSpy.calledWithExactly('field3', null, dummy: true)
- assert.same expected, @inst._fields
- 'fields() - array':
- 'saves inputs': ->
- fieldSpy = test.mocker.spy(@inst, 'field')
- @inst.fields([ 'field1', 'field2', 'field3' ], { dummy: true})
- expected = [
- {
- name: 'field1',
- alias: null
- options: {
- dummy: true
- }
- },
- {
- name: 'field2',
- alias: null
- options: {
- dummy: true
- }
- },
- {
- name: 'field3',
- alias: null
- options: {
- dummy: true
- }
- }
- ]
- assert.ok fieldSpy.calledThrice
- assert.ok fieldSpy.calledWithExactly('field1', null, dummy: true)
- assert.ok fieldSpy.calledWithExactly('field2', null, dummy: true)
- assert.ok fieldSpy.calledWithExactly('field3', null, dummy: true)
- assert.same expected, @inst._fields
- 'field()':
- 'saves inputs': ->
- @inst.field('field1')
- @inst.field('field2', 'alias2')
- @inst.field('field3')
- expected = [
- {
- name: 'field1',
- alias: null,
- options: {},
- },
- {
- name: 'field2',
- alias: 'alias2'
- options: {},
- },
- {
- name: 'field3',
- alias: null
- options: {},
- }
- ]
- assert.same expected, @inst._fields
- 'field() - discard duplicates':
- 'saves inputs': ->
- @inst.field('field1')
- @inst.field('field2', 'alias2')
- @inst.field('field2', 'alias2')
- @inst.field('field1', 'alias1')
- expected = [
- {
- name: 'field1',
- alias: null
- options: {},
- },
- {
- name: 'field2',
- alias: 'alias2'
- options: {},
- },
- {
- name: 'field1',
- alias: 'alias1'
- options: {},
- }
- ]
- assert.same expected, @inst._fields
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeField', -> return '_f'
- sanitizeAliasSpy = test.mocker.stub @cls.prototype, '_sanitizeFieldAlias', -> return '_a'
- @inst.field('field1', 'alias1', { dummy: true})
- assert.ok sanitizeFieldSpy.calledWithExactly 'field1'
- assert.ok sanitizeAliasSpy.calledWithExactly 'alias1'
- assert.same @inst._fields, [ {
- name: '_f',
- alias: '_a'
- options:
- dummy: true
- } ]
- '_toParamString()':
- beforeEach: ->
- @queryBuilder = squel.select()
- @fromTableBlock = @queryBuilder.getBlock(squel.cls.FromTableBlock)
- 'returns all fields when none provided and table is set': ->
- @fromTableBlock._hasTable = -> true
- assert.same @inst._toParamString(queryBuilder: @queryBuilder), {
- text: '*',
- values: []
- }
- 'but returns nothing if no table set': ->
- @fromTableBlock._hasTable = -> false
- assert.same @inst._toParamString(queryBuilder: @queryBuilder), {
- text: ''
- values: []
- }
- 'returns formatted query phrase': ->
- beforeEach: ->
- @fromTableBlock._hasTable = -> true
- @inst.field(squel.str('GETDATE(?)', 3), 'alias1')
- @inst.field('field2', 'alias2', { dummy: true })
- @inst.field('field3')
- 'non-parameterized': ->
- assert.same @inst._toParamString(queryBuilder: @queryBuilder), {
- text: '(GETDATE(3)) AS "alias1", field2 AS "alias2", field3'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(queryBuilder: @queryBuilder, buildParameterized: true), {
- text: '(GETDATE(?)) AS "alias1", field2 AS "alias2", field3'
- values: [3]
- }
- 'AbstractSetFieldBlock':
- beforeEach: ->
- @cls = squel.cls.AbstractSetFieldBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- '_set()':
- 'saves inputs': ->
- @inst._set('field1', 'value1', dummy: 1)
- @inst._set('field2', 'value2', dummy: 2)
- @inst._set('field3', 'value3', dummy: 3)
- @inst._set('field4')
- expectedFields = [ 'field1', 'field2', 'field3', 'field4' ]
- expectedValues = [ [ 'value1', 'value2', 'value3', undefined ] ]
- expectedFieldOptions = [ [ {dummy: 1}, {dummy: 2}, {dummy: 3}, {} ] ]
- assert.same expectedFields, @inst._fields
- assert.same expectedValues, @inst._values
- assert.same expectedFieldOptions, @inst._valueOptions
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeField', -> '_f'
- sanitizeValueSpy = test.mocker.stub @cls.prototype, '_sanitizeValue', -> '_v'
- @inst._set('field1', 'value1', dummy: true)
- assert.ok sanitizeFieldSpy.calledWithExactly 'field1'
- assert.ok sanitizeValueSpy.calledWithExactly 'value1'
- assert.same [ '_f' ], @inst._fields
- assert.same [ [ '_v' ] ], @inst._values
- '_setFields()':
- 'saves inputs': ->
- @inst._setFields
- 'field1': 'value1'
- 'field2': 'value2'
- 'field3': 'value3'
- expectedFields = [ 'field1', 'field2', 'field3' ]
- expectedValues = [ [ 'value1', 'value2', 'value3'] ]
- expectedFieldOptions = [ [ {}, {}, {} ] ]
- assert.same expectedFields, @inst._fields
- assert.same expectedValues, @inst._values
- assert.same expectedFieldOptions, @inst._valueOptions
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeField', -> '_f'
- sanitizeValueSpy = test.mocker.stub @cls.prototype, '_sanitizeValue', -> '_v'
- @inst._setFields({'field1': 'value1'}, {dummy: true})
- assert.ok sanitizeFieldSpy.calledWithExactly 'field1'
- assert.ok sanitizeValueSpy.calledWithExactly 'value1'
- assert.same [ '_f' ], @inst._fields
- assert.same [ [ '_v' ] ], @inst._values
- '_setFieldsRows()':
- 'saves inputs': ->
- @inst._setFieldsRows [
- {
- 'field1': 'value1'
- 'field2': 'value2'
- 'field3': 'value3'
- }
- {
- 'field1': 'value21'
- 'field2': 'value22'
- 'field3': 'value23'
- }
- ]
- expectedFields = [ 'field1', 'field2', 'field3' ]
- expectedValues = [ [ 'value1', 'value2', 'value3' ], [ 'value21', 'value22', 'value23' ] ]
- expectedFieldOptions = [ [ {}, {}, {} ], [ {}, {}, {} ] ]
- assert.same expectedFields, @inst._fields
- assert.same expectedValues, @inst._values
- assert.same expectedFieldOptions, @inst._valueOptions
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeField', -> return '_f'
- sanitizeValueSpy = test.mocker.stub @cls.prototype, '_sanitizeValue', -> return '_v'
- @inst._setFieldsRows [
- {
- 'field1': 'value1'
- },
- {
- 'field1': 'value21'
- }
- ], { dummy: true }
- assert.ok sanitizeFieldSpy.calledWithExactly 'field1'
- assert.ok sanitizeValueSpy.calledWithExactly 'value1'
- assert.ok sanitizeValueSpy.calledWithExactly 'value21'
- assert.same [ '_f' ], @inst._fields
- assert.same [ [ '_v' ], [ '_v' ] ], @inst._values
- '_toParamString()': ->
- assert.throws ( => @inst._toParamString()), 'Not yet implemented'
- 'SetFieldBlock':
- beforeEach: ->
- @cls = squel.cls.SetFieldBlock
- @inst = new @cls()
- 'instanceof of AbstractSetFieldBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractSetFieldBlock
- 'set()':
- 'calls to _set()': ->
- spy = test.mocker.stub @inst, '_set'
- @inst.set 'f', 'v', dummy: true
- assert.ok spy.calledWithExactly('f', 'v', dummy: true)
- 'setFields()':
- 'calls to _setFields()': ->
- spy = test.mocker.stub @inst, '_setFields'
- @inst.setFields 'f', dummy: true
- assert.ok spy.calledWithExactly('f', dummy: true)
- '_toParamString()':
- 'needs at least one field to have been provided': ->
- try
- @inst.toString()
- throw new Error 'should not reach here'
- catch err
- assert.same 'Error: set() needs to be called', err.toString()
- 'fields set':
- beforeEach: ->
- @inst.set('field0 = field0 + 1')
- @inst.set('field1', 'value1', { dummy: true })
- @inst.set('field2', 'value2')
- @inst.set('field3', squel.str('GETDATE(?)', 4))
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'SET field0 = field0 + 1, field1 = \'value1\', field2 = \'value2\', field3 = (GETDATE(4))',
- values: [],
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'SET field0 = field0 + 1, field1 = ?, field2 = ?, field3 = (GETDATE(?))',
- values: ['value1', 'value2', 4],
- }
- 'InsertFieldValueBlock':
- beforeEach: ->
- @cls = squel.cls.InsertFieldValueBlock
- @inst = new @cls()
- 'instanceof of AbstractSetFieldBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractSetFieldBlock
- 'set()':
- 'calls to _set()': ->
- spy = test.mocker.stub @inst, '_set'
- @inst.set 'f', 'v', dummy: true
- assert.ok spy.calledWithExactly('f', 'v', dummy: true)
- 'setFields()':
- 'calls to _setFields()': ->
- spy = test.mocker.stub @inst, '_setFields'
- @inst.setFields 'f', dummy: true
- assert.ok spy.calledWithExactly('f', dummy: true)
- 'setFieldsRows()':
- 'calls to _setFieldsRows()': ->
- spy = test.mocker.stub @inst, '_setFieldsRows'
- @inst.setFieldsRows 'f', dummy: true
- assert.ok spy.calledWithExactly('f', dummy: true)
- '_toParamString()':
- 'needs at least one field to have been provided': ->
- assert.same '', @inst.toString()
- 'got fields':
- beforeEach: ->
- @inst.setFieldsRows([
- { field1: 9, field2: 'value2', field3: squel.str('GETDATE(?)', 5) }
- { field1: 8, field2: true, field3: null }
- ])
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: '(field1, field2, field3) VALUES (9, \'value2\', (GETDATE(5))), (8, TRUE, NULL)'
- values: [],
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: '(field1, field2, field3) VALUES (?, ?, (GETDATE(?))), (?, ?, ?)'
- values: [9, 'value2', 5, 8, true, null],
- }
- 'InsertFieldsFromQueryBlock':
- beforeEach: ->
- @cls = squel.cls.InsertFieldsFromQueryBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'fromQuery()':
- 'sanitizes field names': ->
- spy = test.mocker.stub @inst, '_sanitizeField', -> 1
- qry = squel.select()
- @inst.fromQuery(['test', 'one', 'two'], qry)
- assert.ok spy.calledThrice
- assert.ok spy.calledWithExactly 'test'
- assert.ok spy.calledWithExactly 'one'
- assert.ok spy.calledWithExactly 'two'
- 'sanitizes query': ->
- spy = test.mocker.stub @inst, '_sanitizeBaseBuilder', -> 1
- qry = 123
- @inst.fromQuery(['test', 'one', 'two'], qry)
- assert.ok spy.calledOnce
- assert.ok spy.calledWithExactly qry
- 'overwrites existing values': ->
- @inst._fields = 1
- @inst._query = 2
- qry = squel.select()
- @inst.fromQuery(['test', 'one', 'two'], qry)
- assert.same qry, @inst._query
- assert.same ['test', 'one', 'two'], @inst._fields
- '_toParamString()':
- 'needs fromQuery() to have been called': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'default':
- beforeEach: ->
- @qry = squel.select().from('mega').where('a = ?', 5)
- @inst.fromQuery ['test', 'one', 'two'], @qry
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: "(test, one, two) (SELECT * FROM mega WHERE (a = 5))"
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: "(test, one, two) (SELECT * FROM mega WHERE (a = ?))"
- values: [5]
- }
- 'DistinctBlock':
- beforeEach: ->
- @cls = squel.cls.DistinctBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- '_toParamString()':
- 'output nothing if not set': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'output DISTINCT if set': ->
- @inst.distinct()
- assert.same @inst._toParamString(), {
- text: 'DISTINCT'
- values: []
- }
- 'GroupByBlock':
- beforeEach: ->
- @cls = squel.cls.GroupByBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'group()':
- 'adds to list': ->
- @inst.group('field1')
- @inst.group('field2')
- assert.same ['field1', 'field2'], @inst._groups
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeField', -> return '_f'
- @inst.group('field1')
- assert.ok sanitizeFieldSpy.calledWithExactly 'field1'
- assert.same ['_f'], @inst._groups
- 'toString()':
- 'output nothing if no fields set': ->
- @inst._groups = []
- assert.same '', @inst.toString()
- 'output GROUP BY': ->
- @inst.group('field1')
- @inst.group('field2')
- assert.same 'GROUP BY field1, field2', @inst.toString()
- 'OffsetBlock':
- beforeEach: ->
- @cls = squel.cls.OffsetBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'offset()':
- 'set value': ->
- @inst.offset(1)
- assert.same 1, @inst._offsets
- @inst.offset(22)
- assert.same 22, @inst._offsets
- 'sanitizes inputs': ->
- sanitizeSpy = test.mocker.stub @cls.prototype, '_sanitizeLimitOffset', -> return 234
- @inst.offset(23)
- assert.ok sanitizeSpy.calledWithExactly 23
- assert.same 234, @inst._offsets
- 'toString()':
- 'output nothing if not set': ->
- @inst._offsets = null
- assert.same '', @inst.toString()
- 'output OFFSET': ->
- @inst.offset(12)
- assert.same 'OFFSET 12', @inst.toString()
- 'AbstractConditionBlock':
- beforeEach: ->
- @cls = squel.cls.AbstractConditionBlock
- @inst = new @cls {
- verb: 'ACB'
- }
- class squel.cls.MockConditionBlock extends squel.cls.AbstractConditionBlock
- constructor: (options) ->
- super _.extend({}, options, {verb: 'MOCKVERB'})
- mockCondition: (condition, values...) ->
- @_condition condition, values...
- class squel.cls.MockSelectWithCondition extends squel.cls.Select
- constructor: (options, blocks = null) ->
- blocks = [
- new squel.cls.StringBlock(options, 'SELECT'),
- new squel.cls.GetFieldBlock(options),
- new squel.cls.FromTableBlock(options),
- new squel.cls.MockConditionBlock(options)
- ]
- super options, blocks
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- '_condition()':
- 'adds to list': ->
- @inst._condition('a = 1')
- @inst._condition('b = 2 OR c = 3')
- assert.same [
- {
- expr: 'a = 1'
- values: []
- }
- {
- expr: 'b = 2 OR c = 3'
- values: []
- }
- ], @inst._conditions
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeExpression', -> return '_c'
- @inst._condition('a = 1')
- assert.ok sanitizeFieldSpy.calledWithExactly 'a = 1'
- assert.same [{
- expr: '_c'
- values: []
- }], @inst._conditions
- '_toParamString()':
- 'output nothing if no conditions set': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'output QueryBuilder ':
- beforeEach: ->
- subquery = new squel.cls.MockSelectWithCondition()
- subquery.field('col1').from('table1').mockCondition('field1 = ?', 10)
- @inst._condition('a in ?', subquery)
- @inst._condition('b = ? OR c = ?', 2, 3)
- @inst._condition('d in ?', [4, 5, 6])
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'ACB (a in (SELECT col1 FROM table1 MOCKVERB (field1 = 10))) AND (b = 2 OR c = 3) AND (d in (4, 5, 6))'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'ACB (a in (SELECT col1 FROM table1 MOCKVERB (field1 = ?))) AND (b = ? OR c = ?) AND (d in (?, ?, ?))'
- values: [10, 2, 3, 4, 5, 6]
- }
- 'Fix for #64 - toString() does not change object':
- beforeEach: ->
- @inst._condition('a = ?', 1)
- @inst._condition('b = ? OR c = ?', 2, 3)
- @inst._condition('d in ?', [4, 5, 6])
- @inst._toParamString()
- @inst._toParamString()
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'ACB (a = 1) AND (b = 2 OR c = 3) AND (d in (4, 5, 6))'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'ACB (a = ?) AND (b = ? OR c = ?) AND (d in (?, ?, ?))'
- values: [1, 2, 3, 4, 5, 6]
- }
- 'Fix for #226 - empty expressions':
- beforeEach: ->
- @inst._condition('a = ?', 1)
- @inst._condition(squel.expr())
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'ACB (a = 1)'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'ACB (a = ?)'
- values: [1]
- }
- 'WhereBlock':
- beforeEach: ->
- @cls = squel.cls.WhereBlock
- @inst = new @cls()
- 'instanceof of AbstractConditionBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractConditionBlock
- 'sets verb to WHERE': ->
- @inst = new @cls
- assert.same 'WHERE', @inst.options.verb
- '_toParamString()':
- 'output nothing if no conditions set': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'output':
- beforeEach: ->
- subquery = new squel.cls.Select()
- subquery.field('col1').from('table1').where('field1 = ?', 10)
- @inst.where('a in ?', subquery)
- @inst.where('b = ? OR c = ?', 2, 3)
- @inst.where('d in ?', [4, 5, 6])
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'WHERE (a in (SELECT col1 FROM table1 WHERE (field1 = 10))) AND (b = 2 OR c = 3) AND (d in (4, 5, 6))'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'WHERE (a in (SELECT col1 FROM table1 WHERE (field1 = ?))) AND (b = ? OR c = ?) AND (d in (?, ?, ?))'
- values: [10, 2, 3, 4, 5, 6]
- }
- 'HavingBlock':
- beforeEach: ->
- @cls = squel.cls.HavingBlock
- @inst = new @cls()
- 'instanceof of AbstractConditionBlock': ->
- assert.instanceOf @inst, squel.cls.AbstractConditionBlock
- 'sets verb': ->
- @inst = new @cls
- assert.same 'HAVING', @inst.options.verb
- '_toParamString()':
- 'output nothing if no conditions set': ->
- assert.same @inst._toParamString(), {
- text: ''
- values: []
- }
- 'output':
- beforeEach: ->
- subquery = new squel.cls.Select()
- subquery.field('col1').from('table1').where('field1 = ?', 10)
- @inst.having('a in ?', subquery)
- @inst.having('b = ? OR c = ?', 2, 3)
- @inst.having('d in ?', [4, 5, 6])
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'HAVING (a in (SELECT col1 FROM table1 WHERE (field1 = 10))) AND (b = 2 OR c = 3) AND (d in (4, 5, 6))'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'HAVING (a in (SELECT col1 FROM table1 WHERE (field1 = ?))) AND (b = ? OR c = ?) AND (d in (?, ?, ?))'
- values: [10, 2, 3, 4, 5, 6]
- }
- 'OrderByBlock':
- beforeEach: ->
- @cls = squel.cls.OrderByBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'order()':
- 'adds to list': ->
- @inst.order('field1')
- @inst.order('field2', false)
- @inst.order('field3', true)
- expected = [
- {
- field: 'field1',
- dir: true
- values: []
- },
- {
- field: 'field2',
- dir: false
- values: []
- },
- {
- field: 'field3',
- dir: true
- values: []
- }
- ]
- assert.same @inst._orders, expected
- 'sanitizes inputs': ->
- sanitizeFieldSpy = test.mocker.stub @cls.prototype, '_sanitizeField', -> return '_f'
- @inst.order('field1')
- assert.ok sanitizeFieldSpy.calledWithExactly 'field1'
- assert.same @inst._orders, [ { field: '_f', dir: true, values: [] } ]
- 'saves additional values': ->
- @inst.order('field1', false, 1.2, 4)
- assert.same @inst._orders, [ { field: 'field1', dir: false, values: [1.2, 4] } ]
- '_toParamString()':
- 'empty': ->
- assert.same @inst._toParamString(), {
- text: '', values: []
- }
- 'default': ->
- beforeEach: ->
- @inst.order('field1')
- @inst.order('field2', false)
- @inst.order('GET(?, ?)', true, 2.5 ,5)
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'ORDER BY field1 ASC, field2 DESC, GET(2.5, 5) ASC',
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'ORDER BY field1 ASC, field2 DESC, GET(?, ?) ASC',
- values: [2.5, 5]
- }
- 'LimitBlock':
- beforeEach: ->
- @cls = squel.cls.LimitBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'limit()':
- 'set value': ->
- @inst.limit(1)
- assert.same 1, @inst._limit
- @inst.limit(22)
- assert.same 22, @inst._limit
- 'sanitizes inputs': ->
- sanitizeSpy = test.mocker.stub @cls.prototype, '_sanitizeLimitOffset', -> return 234
- @inst.limit(23)
- assert.ok sanitizeSpy.calledWithExactly 23
- assert.same 234, @inst._limit
- '_toParamString()':
- 'output nothing if not set': ->
- assert.same @inst._toParamString(), {
- text: '',
- values: []
- }
- 'default':
- beforeEach: ->
- @inst.limit(10)
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'LIMIT 10'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'LIMIT 10'
- values: []
- }
- 'JoinBlock':
- beforeEach: ->
- @cls = squel.cls.JoinBlock
- @inst = new @cls()
- 'instanceof of Block': ->
- assert.instanceOf @inst, squel.cls.Block
- 'join()':
- 'adds to list': ->
- @inst.join('table1')
- @inst.join('table2', null, 'b = 1', 'LEFT')
- @inst.join('table3', 'alias3', 'c = 1', 'RIGHT')
- @inst.join('table4', 'alias4', 'd = 1', 'OUTER')
- @inst.join('table5', 'alias5', null, 'CROSS')
- expected = [
- {
- type: 'INNER',
- table: 'table1',
- alias: null,
- condition: null
- },
- {
- type: 'LEFT',
- table: 'table2',
- alias: null,
- condition: 'b = 1'
- },
- {
- type: 'RIGHT',
- table: 'table3',
- alias: 'alias3',
- condition: 'c = 1'
- },
- {
- type: 'OUTER',
- table: 'table4',
- alias: 'alias4',
- condition: 'd = 1'
- },
- {
- type: 'CROSS',
- table: 'table5',
- alias: 'alias5',
- condition: null
- }
- ]
- assert.same @inst._joins, expected
- 'sanitizes inputs': ->
- sanitizeTableSpy = test.mocker.stub @cls.prototype, '_sanitizeTable', -> return '_t'
- sanitizeAliasSpy = test.mocker.stub @cls.prototype, '_sanitizeTableAlias', -> return '_a'
- sanitizeConditionSpy = test.mocker.stub @cls.prototype, '_sanitizeExpression', -> return '_c'
- @inst.join('table1', 'alias1', 'a = 1')
- assert.ok sanitizeTableSpy.calledWithExactly 'table1', true
- assert.ok sanitizeAliasSpy.calledWithExactly 'alias1'
- assert.ok sanitizeConditionSpy.calledWithExactly 'a = 1'
- expected = [
- {
- type: 'INNER',
- table: '_t',
- alias: '_a',
- condition: '_c'
- }
- ]
- assert.same @inst._joins, expected
- 'nested queries': ->
- inner1 = squel.select()
- inner2 = squel.select()
- inner3 = squel.select()
- inner4 = squel.select()
- inner5 = squel.select()
- inner6 = squel.select()
- @inst.join(inner1)
- @inst.join(inner2, null, 'b = 1', 'LEFT')
- @inst.join(inner3, 'alias3', 'c = 1', 'RIGHT')
- @inst.join(inner4, 'alias4', 'd = 1', 'OUTER')
- @inst.join(inner5, 'alias5', 'e = 1', 'FULL')
- @inst.join(inner6, 'alias6', null, 'CROSS')
- expected = [
- {
- type: 'INNER',
- table: inner1,
- alias: null,
- condition: null
- },
- {
- type: 'LEFT',
- table: inner2,
- alias: null,
- condition: 'b = 1'
- },
- {
- type: 'RIGHT',
- table: inner3,
- alias: 'alias3',
- condition: 'c = 1'
- },
- {
- type: 'OUTER',
- table: inner4,
- alias: 'alias4',
- condition: 'd = 1'
- },
- {
- type: 'FULL',
- table: inner5,
- alias: 'alias5',
- condition: 'e = 1'
- },
- {
- type: 'CROSS',
- table: inner6,
- alias: 'alias6',
- condition: null
- }
- ]
- assert.same @inst._joins, expected
- 'left_join()':
- 'calls join()': ->
- joinSpy = test.mocker.stub(@inst, 'join')
- @inst.left_join('t', 'a', 'c')
- assert.ok joinSpy.calledOnce
- assert.ok joinSpy.calledWithExactly('t', 'a', 'c', 'LEFT')
- '_toParamString()':
- 'output nothing if nothing set': ->
- assert.same @inst._toParamString(), {
- text: '',
- values: []
- }
- 'output JOINs with nested queries':
- beforeEach: ->
- inner2 = squel.select().function('GETDATE(?)', 2)
- inner3 = squel.select().from('3')
- inner4 = squel.select().from('4')
- inner5 = squel.select().from('5')
- expr = squel.expr().and('field1 = ?', 99)
- @inst.join('table')
- @inst.join(inner2, null, 'b = 1', 'LEFT')
- @inst.join(inner3, 'alias3', 'c = 1', 'RIGHT')
- @inst.join(inner4, 'alias4', 'e = 1', 'FULL')
- @inst.join(inner5, 'alias5', expr, 'CROSS')
- 'non-parameterized': ->
- assert.same @inst._toParamString(), {
- text: 'INNER JOIN table LEFT JOIN (SELECT GETDATE(2)) ON (b = 1) RIGHT JOIN (SELECT * FROM 3) `alias3` ON (c = 1) FULL JOIN (SELECT * FROM 4) `alias4` ON (e = 1) CROSS JOIN (SELECT * FROM 5) `alias5` ON (field1 = 99)'
- values: []
- }
- 'parameterized': ->
- assert.same @inst._toParamString(buildParameterized: true), {
- text: 'INNER JOIN table LEFT JOIN (SELECT GETDATE(?)) ON (b = 1) RIGHT JOIN (SELECT * FROM 3) `alias3` ON (c = 1) FULL JOIN (SELECT * FROM 4) `alias4` ON (e = 1) CROSS JOIN (SELECT * FROM 5) `alias5` ON (field1 = ?)'
- values: [2, 99]
- }
- module?.exports[require('path').basename(__filename)] = test
|