== protein, chain on the same strand
chain: t=chrSrc:100-400 q=chrRef:100-400 qStrand=+ blocks 100-400/100-400
before   100	0	0	0	0	0	0	0	++	prot	100	0	100	chrSrc	1000	100	400	1	100,	0,	100,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0
lifted   100	0	0	0	0	0	0	0	++	prot	100	0	100	chrRef	1000	100	400	1	100,	0,	100,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0

== protein, chain on the opposite strand
chain: t=chrSrc:600-900 q=chrRef:600-900 qStrand=- blocks 600-900/600-900
before   100	0	0	0	0	0	0	0	++	prot	100	0	100	chrSrc	1000	600	900	1	100,	0,	600,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0
lifted   100	0	0	0	0	0	0	0	+-	prot	100	0	100	chrRef	1000	100	400	1	100,	0,	600,
         strand='+-' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0

== protein, chain gaps the reference
chain: t=chrSrc:100-400 q=chrRef:100-401 qStrand=+ blocks 100-250/100-250 250-400/251-401
before   100	0	0	0	0	0	0	0	++	prot	100	0	100	chrSrc	1000	100	400	1	100,	0,	100,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0
lifted   100	0	0	0	0	0	1	1	++	prot	100	0	100	chrRef	1000	100	401	2	50,50,	0,50,	100,251,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=50 pslCheck errors=0

== protein, lift splits a codon
chain: t=chrSrc:100-401 q=chrRef:100-400 qStrand=+ blocks 100-250/100-250 251-401/250-400
before   100	0	0	0	0	0	0	0	++	prot	100	0	100	chrSrc	1000	100	400	1	100,	0,	100,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0
lifted   299	0	0	0	1	1	0	0	+	prot	300	0	300	chrRef	1000	100	399	2	150,149,	0,151,	100,250,
         strand='+' isProtein=0 qSize=300 blockSizes[0]=150 pslCheck errors=0

== mRNA, chain on the same strand
chain: t=chrSrc:100-400 q=chrRef:100-400 qStrand=+ blocks 100-400/100-400
before   300	0	0	0	0	0	0	0	+	mrna	300	0	300	chrSrc	1000	100	400	1	300,	0,	100,
         strand='+' isProtein=0 qSize=300 blockSizes[0]=300 pslCheck errors=0
lifted   300	0	0	0	0	0	0	0	+	mrna	300	0	300	chrRef	1000	100	400	1	300,	0,	100,
         strand='+' isProtein=0 qSize=300 blockSizes[0]=300 pslCheck errors=0

== mRNA, chain on the opposite strand
chain: t=chrSrc:600-900 q=chrRef:600-900 qStrand=- blocks 600-900/600-900
before   300	0	0	0	0	0	0	0	+	mrna	300	0	300	chrSrc	1000	600	900	1	300,	0,	600,
         strand='+' isProtein=0 qSize=300 blockSizes[0]=300 pslCheck errors=0
lifted   300	0	0	0	0	0	0	0	-	mrna	300	0	300	chrRef	1000	100	400	1	300,	0,	100,
         strand='-' isProtein=0 qSize=300 blockSizes[0]=300 pslCheck errors=0

== protein, a block shorter than a codon
chain: t=chrSrc:100-700 q=chrRef:100-700 qStrand=+ blocks 100-700/100-700
before   90	0	0	0	0	0	0	0	-+	prot	100	0	100	chrSrc	1000	100	400	2	0,90,	0,10,	100,130,
Error: invalid PSL: prot:0-100 chrSrc:100-400 -+ before
	prot query block 0 start 100 >= qEnd 100
         strand='-+' isProtein=1 qSize=100 blockSizes[0]=0 pslCheck errors=1
lifted   90	0	0	0	0	0	0	0	+-	prot	100	0	90	chrRef	1000	130	400	1	90,	0,	600,
         strand='+-' isProtein=1 qSize=100 blockSizes[0]=90 pslCheck errors=0

== no chain over the alignment
chain: t=chrSrc:100-400 q=chrRef:100-400 qStrand=+ blocks 100-400/100-400
before   100	0	0	0	0	0	0	0	++	prot	100	0	100	chrSrc	1000	700	1000	1	100,	0,	700,
         strand='++' isProtein=1 qSize=100 blockSizes[0]=100 pslCheck errors=0
lifted   did not lift

== source runs: a 5 kb source gap is read across, window chrRef:0-1000
  chrSrc:100-5400

== source runs: a source gap of exactly 10000 is read across, window chrRef:0-1000
  chrSrc:100-10300

== source runs: a source gap of 10001 splits the range, window chrRef:0-1000
  chrSrc:100-200
  chrSrc:10201-10301

== source runs: a minus-strand chain, split, on the plus strand, window chrRef:0-1000
  chrSrc:99800-99900
  chrSrc:79700-79800

== source runs: the window clips both blocks, window chrRef:150-350
  chrSrc:150-5350

== source runs: the window misses every block, window chrRef:500-1000
  (none)

== query ranges: one range per chain (perChain=0 split=0)
  chrSrc:1000-31000 chain=1
  chrSrc:1000-2000 chain=2
  chrSrc2:0-500 chain=3
  chrSrc:2000-2500 chain=5

== query ranges: one range per chain, multi-chain (perChain=1 split=0)
  chrSrc:1000-31000 chain=1
  chrSrc:1000-2000 chain=2
  chrSrc2:0-500 chain=3
  chrSrc:2000-2500 chain=5

== query ranges: split and merged across chains (perChain=0 split=1)
  chrSrc:1000-2500 chain=0
  chrSrc:30000-31000 chain=0
  chrSrc2:0-500 chain=0

== query ranges: split and merged within each chain (perChain=1 split=1)
  chrSrc:1000-2000 chain=1
  chrSrc:30000-31000 chain=1
  chrSrc:1000-2000 chain=2
  chrSrc2:0-500 chain=3
  chrSrc:2000-2500 chain=5

== quickLiftRangeWhere
  no start field         NOSQLINJ score > 100  [the caller's own]
  no extraWhere          NOSQLINJ chromStart >= 500
  a condition            NOSQLINJ (score > 100) and chromStart >= 500
  an order clause        NOSQLINJ txStart >= 500 order by score
  a limit clause         NOSQLINJ txStart >= 500 limit 10

== map to reference: two blocks, chrSrc:150-5350
  chrRef:150-200
  chrRef:300-350

== map to reference: the last block only, chrSrc:9050-9200
  chrRef:550-600

== map to reference: only the gap, chrSrc:250-5300
  (none)

== map to reference: minus-strand chain, chrSrc:99850-99900
  chrRef:100-150

== one-chain hash
  no chain hash:           NULL
  an item never assigned:  the whole hash
  both added:              chains=1,2
  chain 1 removed:         chains=2
  chain 1 removed again:   chains=2

passed
