@@ -230,28 +230,38 @@ describe("Plurals", function() {
230230 } ) ;
231231
232232 it ( "should support quoting" , function ( ) {
233- expect ( parse ( "{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] . type ) . to . eql ( 'function' ) ;
234- expect ( parse ( "{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] . arg ) . to . eql ( 'x' ) ;
235- expect ( parse ( "{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] . key ) . to . eql ( 'date' ) ;
236- // Octothorpe is not special here regardless of strict number sign
237- expect ( parse ( "{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] . param ) . to . eql ( "y-M-dd # '#'" ) ;
233+ expect ( parse ( "{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens ) . to . eql ( [ {
234+ type : 'function' , arg : 'x' , key : 'date' ,
235+ param : {
236+ tokens : [ 'y-M-dd ' , { type : 'octothorpe' } , ' #' ]
237+ }
238+ } ] ) ;
239+ expect ( parse ( "{NUM, plural, one{# '' #} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens ) . to . eql ( [
240+ { type : 'octothorpe' } , " ' " , { type : 'octothorpe' }
241+ ] ) ;
242+ expect ( parse ( "{NUM, plural, one{# '#'} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens ) . to . eql ( [
243+ { type : 'octothorpe' } , ' #'
244+ ] ) ;
245+ expect ( parse ( "{NUM, plural, one{one#} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens ) . to . eql ( [
246+ 'one' , { type : 'octothorpe' }
247+ ] ) ;
248+ } )
238249
239- expect ( parse ( "{NUM, plural, one{# '' #} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] . type ) . to . eql ( 'octothorpe' ) ;
240- expect ( parse ( "{NUM, plural, one{# '' #} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 1 ] ) . to . eql ( " ' " ) ;
241- expect ( parse ( "{NUM, plural, one{# '' #} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . type ) . to . eql ( 'octothorpe' ) ;
242- expect ( parse ( "{NUM, plural, one{# '#'} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] . type ) . to . eql ( 'octothorpe' ) ;
243- expect ( parse ( "{NUM, plural, one{# '#'} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 1 ] ) . to . eql ( " #" ) ;
250+ describe ( 'options.strict' , function ( ) {
251+ var src = "{NUM, plural, one{# {VAR,select,key{# '#' one#}}} two{two}}" ;
244252
245- expect ( parse ( "{NUM, plural, one{one#} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 0 ] ) . to . eql ( 'one' ) ;
246- expect ( parse ( "{NUM, plural, one{one#} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 1 ] . type ) . to . eql ( 'octothorpe' ) ;
253+ it ( 'should parse # correctly without strict option' , function ( ) {
254+ expect ( parse ( src ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . cases [ 0 ] . tokens ) . to . eql ( [
255+ { type : 'octothorpe' } , ' # one' , { type : 'octothorpe' }
256+ ] ) ;
257+ } )
247258
248- // without strict number sign
249- expect ( parse ( "{NUM, plural, one{# {VAR,select,key{# '#' one#}}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . cases [ 0 ] . tokens [ 0 ] . type ) . to . eql ( 'octothorpe' )
250- expect ( parse ( "{NUM, plural, one{# {VAR,select,key{# '#' one#}}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . cases [ 0 ] . tokens [ 1 ] ) . to . eql ( ' # one' )
251- expect ( parse ( "{NUM, plural, one{# {VAR,select,key{# '#' one#}}} two{two}}" ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . cases [ 0 ] . tokens [ 2 ] . type ) . to . eql ( 'octothorpe' )
252- // with strict number sign
253- expect ( parse ( "{NUM, plural, one{# {VAR,select,key{# '#' one#}}} two{two}}" , { strictNumberSign : true } ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . cases [ 0 ] . tokens [ 0 ] ) . to . eql ( '# \'#\' one#' )
254- } ) ;
259+ it ( 'should parse # correctly with strict option' , function ( ) {
260+ expect ( parse ( src , { strict : true } ) [ 0 ] . cases [ 0 ] . tokens [ 2 ] . cases [ 0 ] . tokens ) . to . eql ( [
261+ "# '#' one#"
262+ ] ) ;
263+ } )
264+ } )
255265
256266} ) ;
257267describe ( "Ordinals" , function ( ) {
@@ -277,43 +287,105 @@ describe("Ordinals", function() {
277287
278288} ) ;
279289describe ( "Functions" , function ( ) {
280- it ( "should accept no parameters" , function ( ) {
281- expect ( parse ( '{var,date}' ) [ 0 ] . type ) . to . eql ( 'function' ) ;
282- expect ( parse ( '{var,date}' ) [ 0 ] . key ) . to . eql ( 'date' ) ;
283- expect ( parse ( '{var,date}' ) [ 0 ] . param ) . to . be . null ;
290+ it ( "should require lower-case type" , function ( ) {
291+ expect ( function ( ) { parse ( '{var,date}' ) ; } ) . to . not . throwError ( ) ;
292+ expect ( function ( ) { parse ( '{var,Date}' ) ; } ) . to . throwError ( ) ;
293+ expect ( function ( ) { parse ( '{var,daTe}' ) ; } ) . to . throwError ( ) ;
294+ expect ( function ( ) { parse ( '{var,9ate}' ) ; } ) . to . throwError ( ) ;
295+ } )
296+
297+ it ( 'should be gracious with whitespace around arg and key' , function ( ) {
298+ var expected = { type : 'function' , arg : 'var' , key : 'date' , param : null }
299+ expect ( parse ( '{var,date}' ) [ 0 ] ) . to . eql ( expected ) ;
300+ expect ( parse ( '{var, date}' ) [ 0 ] ) . to . eql ( expected ) ;
301+ expect ( parse ( '{ var, date }' ) [ 0 ] ) . to . eql ( expected ) ;
302+ expect ( parse ( '{\nvar, \ndate\n}' ) [ 0 ] ) . to . eql ( expected ) ;
284303 } )
285304
286305 it ( "should accept parameters" , function ( ) {
287- expect ( parse ( '{var,date,long}' ) [ 0 ] . type ) . to . eql ( 'function' ) ;
288- expect ( parse ( '{ var, date,long}' ) [ 0 ] . key ) . to . eql ( 'date' ) ;
289- expect ( parse ( '{var,date,long}' ) [ 0 ] . param ) . to . eql ( 'long' ) ;
290- expect ( parse ( '{var,date,long,short}' ) [ 0 ] . param ) . to . eql ( 'long,short' ) ;
306+ expect ( parse ( '{var,date,long}' ) [ 0 ] ) . to . eql ( {
307+ type : 'function' , arg : ' var' , key : ' date' , param : { tokens : [ 'long' ] }
308+ } ) ;
309+ expect ( parse ( '{var,date,long,short}' ) [ 0 ] . param . tokens ) . to . eql ( [ 'long,short' ] ) ;
291310 } )
292311
293312 it ( "should accept parameters with whitespace" , function ( ) {
294- expect ( parse ( '{var,date,y-M-d HH:mm:ss zzzz}' ) [ 0 ] . type ) . to . eql ( 'function' ) ;
295- expect ( parse ( '{ var, date, y-M-d HH:mm:ss zzzz}' ) [ 0 ] . key ) . to . eql ( 'date' ) ;
296- expect ( parse ( '{var,date,y-M-d HH:mm:ss zzzz}' ) [ 0 ] . param ) . to . eql ( 'y-M-d HH:mm:ss zzzz' ) ;
297- expect ( parse ( '{var,date, y-M-d HH:mm:ss zzzz }' ) [ 0 ] . param ) . to . eql ( ' y-M-d HH:mm:ss zzzz ' ) ;
313+ expect ( parse ( '{var,date,y-M-d HH:mm:ss zzzz}' ) [ 0 ] ) . to . eql ( {
314+ type : 'function' , arg : ' var' , key : ' date' , param : { tokens : [ ' y-M-d HH:mm:ss zzzz' ] }
315+ } ) ;
316+ expect ( parse ( '{var,date, y-M-d HH:mm:ss zzzz }' ) [ 0 ] . param . tokens ) . to . eql ( [ ' y-M-d HH:mm:ss zzzz ' ] ) ;
298317 } )
299318
300319 it ( "should accept parameters with special characters" , function ( ) {
301- expect ( parse ( "{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}" ) [ 0 ] . type ) . to . eql ( 'function' ) ;
302- expect ( parse ( "{ var, date, y-M-d ' {,}' '' HH:mm:ss zzzz}" ) [ 0 ] . key ) . to . eql ( 'date' ) ;
303- expect ( parse ( "{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}" ) [ 0 ] . param ) . to . eql ( "y-M-d {,} ' HH:mm:ss zzzz" ) ;
304- expect ( parse ( "{var,date,y-M-d '{,}' '' HH:mm:ss zzzz'}'}" ) [ 0 ] . param ) . to . eql ( "y-M-d {,} ' HH:mm:ss zzzz}" ) ;
305- expect ( parse ( "{var,date,y-M-d # HH:mm:ss zzzz}" ) [ 0 ] . param ) . to . eql ( "y-M-d # HH:mm:ss zzzz" ) ;
306- expect ( parse ( "{var,date,y-M-d '#' HH:mm:ss zzzz}" ) [ 0 ] . param ) . to . eql ( "y-M-d '#' HH:mm:ss zzzz" ) ;
307- expect ( parse ( "{var,date,y-M-d, HH:mm:ss zzzz}" ) [ 0 ] . param ) . to . eql ( "y-M-d, HH:mm:ss zzzz" ) ;
320+ expect ( parse ( "{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}" ) [ 0 ] ) . to . eql ( {
321+ type : 'function' , arg : ' var' , key : ' date' , param : { tokens : [ ' y-M-d {,} \' HH:mm:ss zzzz' ] }
322+ } ) ;
323+ expect ( parse ( "{var,date,y-M-d '{,}' '' HH:mm:ss zzzz'}'}" ) [ 0 ] . param . tokens ) . to . eql ( [ "y-M-d {,} ' HH:mm:ss zzzz}" ] ) ;
324+ expect ( parse ( "{var,date,y-M-d # HH:mm:ss zzzz}" ) [ 0 ] . param . tokens ) . to . eql ( [ "y-M-d # HH:mm:ss zzzz" ] ) ;
325+ expect ( parse ( "{var,date,y-M-d '#' HH:mm:ss zzzz}" ) [ 0 ] . param . tokens ) . to . eql ( [ "y-M-d '#' HH:mm:ss zzzz" ] ) ;
326+ expect ( parse ( "{var,date,y-M-d, HH:mm:ss zzzz}" ) [ 0 ] . param . tokens ) . to . eql ( [ "y-M-d, HH:mm:ss zzzz" ] ) ;
308327 } )
309328
310- it ( "should be gracious with whitespace around arg and key" , function ( ) {
311- var firstRes = JSON . stringify ( parse ( '{var, date}' ) ) ;
312- expect ( JSON . stringify ( parse ( '{ var, date }' ) ) ) . to . eql ( firstRes ) ;
313- expect ( JSON . stringify ( parse ( '{var,date}' ) ) ) . to . eql ( firstRes ) ;
314- expect ( JSON . stringify ( parse ( '{\nvar, \ndate\n}' ) ) ) . to . eql ( firstRes ) ;
315- } ) ;
329+ it ( 'should accept parameters containing a basic variable' , function ( ) {
330+ expect ( parse ( '{foo, date, {bar}}' ) [ 0 ] ) . to . eql ( {
331+ type : 'function' ,
332+ arg : 'foo' ,
333+ key : 'date' ,
334+ param : { tokens : [ ' ' , { arg : 'bar' , type : 'argument' } ] }
335+ } )
336+ } )
337+
338+ it ( 'should accept parameters containing a select' , function ( ) {
339+ expect ( parse ( '{foo, date, {bar, select, other{baz}}}' ) [ 0 ] ) . to . eql ( {
340+ type : 'function' ,
341+ arg : 'foo' ,
342+ key : 'date' ,
343+ param : { tokens : [ ' ' , {
344+ arg : 'bar' ,
345+ type : 'select' ,
346+ cases : [ { key : 'other' , tokens : [ 'baz' ] } ]
347+ } ] }
348+ } )
349+ } )
350+
351+ it ( 'should accept parameters containing a plural' , function ( ) {
352+ expect ( parse ( '{foo, date, {bar, plural, other{#}}}' ) [ 0 ] ) . to . eql ( {
353+ type : 'function' ,
354+ arg : 'foo' ,
355+ key : 'date' ,
356+ param : { tokens : [ ' ' , {
357+ arg : 'bar' ,
358+ type : 'plural' ,
359+ offset : 0 ,
360+ cases : [ { key : 'other' , tokens : [ { type : 'octothorpe' } ] } ]
361+ } ] }
362+ } )
363+ } )
364+
365+ describe ( 'options.strict' , function ( ) {
366+ it ( 'should require known function key with strict option' , function ( ) {
367+ expect ( function ( ) { parse ( '{foo, bar}' ) } ) . to . not . throwError ( )
368+ expect ( function ( ) { parse ( '{foo, bar}' , { strict : true } ) } ) . to . throwError ( )
369+ expect ( function ( ) { parse ( '{foo, date}' , { strict : true } ) } ) . to . not . throwError ( )
370+ } )
371+
372+ it ( 'parameter parsing should obey strict option' , function ( ) {
373+ expect ( parse ( "{foo, date, {bar'}', quote'', other{#}}}" , { strict : true } ) [ 0 ] ) . to . eql ( {
374+ type : 'function' ,
375+ arg : 'foo' ,
376+ key : 'date' ,
377+ param : { tokens : [ " {bar}, quote', other{#}}" ] }
378+ } )
379+ } )
380+
381+ it ( 'should require matched braces in parameter if strict option is set' , function ( ) {
382+ expect ( function ( ) {
383+ parse ( "{foo, date, {bar{}}" , { strict : true } )
384+ } ) . to . throwError ( ) ;
385+ } )
386+ } )
316387} ) ;
388+
317389describe ( "Nested/Recursive blocks" , function ( ) {
318390
319391 it ( "should allow a select statement inside of a select statement" , function ( ) {
0 commit comments