PageRenderTime 90ms CodeModel.GetById 14ms app.highlight 70ms RepoModel.GetById 1ms app.codeStats 0ms

/test/objects.coffee

http://github.com/jashkenas/coffee-script
CoffeeScript | 932 lines | 735 code | 150 blank | 47 comment | 28 complexity | 9b7bbc9e23478543c04253f154bed6e6 MD5 | raw file
  1# Object Literals
  2# ---------------
  3
  4# TODO: refactor object literal tests
  5# TODO: add indexing and method invocation tests: {a}['a'] is a, {a}.a()
  6
  7trailingComma = {k1: "v1", k2: 4, k3: (-> true),}
  8ok trailingComma.k3() and (trailingComma.k2 is 4) and (trailingComma.k1 is "v1")
  9
 10ok {a: (num) -> num is 10 }.a 10
 11
 12moe = {
 13  name:  'Moe'
 14  greet: (salutation) ->
 15    salutation + " " + @name
 16  hello: ->
 17    @['greet'] "Hello"
 18  10: 'number'
 19}
 20ok moe.hello() is "Hello Moe"
 21ok moe[10] is 'number'
 22moe.hello = ->
 23  this['greet'] "Hello"
 24ok moe.hello() is 'Hello Moe'
 25
 26obj = {
 27  is:     -> yes,
 28  'not':  -> no,
 29}
 30ok obj.is()
 31ok not obj.not()
 32
 33### Top-level object literal... ###
 34obj: 1
 35### ...doesn't break things. ###
 36
 37# Object literals should be able to include keywords.
 38obj = {class: 'höt'}
 39obj.function = 'dog'
 40ok obj.class + obj.function is 'hötdog'
 41
 42# Implicit objects as part of chained calls.
 43pluck = (x) -> x.a
 44eq 100, pluck pluck pluck a: a: a: 100
 45
 46
 47test "YAML-style object literals", ->
 48  obj =
 49    a: 1
 50    b: 2
 51  eq 1, obj.a
 52  eq 2, obj.b
 53
 54  config =
 55    development:
 56      server: 'localhost'
 57      timeout: 10
 58
 59    production:
 60      server: 'dreamboat'
 61      timeout: 1000
 62
 63  ok config.development.server  is 'localhost'
 64  ok config.production.server   is 'dreamboat'
 65  ok config.development.timeout is 10
 66  ok config.production.timeout  is 1000
 67
 68obj =
 69  a: 1,
 70  b: 2,
 71ok obj.a is 1
 72ok obj.b is 2
 73
 74# Implicit objects nesting.
 75obj =
 76  options:
 77    value: yes
 78  fn: ->
 79    {}
 80    null
 81ok obj.options.value is yes
 82ok obj.fn() is null
 83
 84# Implicit objects with wacky indentation:
 85obj =
 86  'reverse': (obj) ->
 87    Array.prototype.reverse.call obj
 88  abc: ->
 89    @reverse(
 90      @reverse @reverse ['a', 'b', 'c'].reverse()
 91    )
 92  one: [1, 2,
 93    a: 'b'
 94  3, 4]
 95  red:
 96    orange:
 97          yellow:
 98                  green: 'blue'
 99    indigo: 'violet'
100  misdent: [[],
101  [],
102                  [],
103      []]
104ok obj.abc().join(' ') is 'a b c'
105ok obj.one.length is 5
106ok obj.one[4] is 4
107ok obj.one[2].a is 'b'
108ok (key for key of obj.red).length is 2
109ok obj.red.orange.yellow.green is 'blue'
110ok obj.red.indigo is 'violet'
111ok obj.misdent.toString() is ',,,'
112
113#542: Objects leading expression statement should be parenthesized.
114{f: -> ok yes }.f() + 1
115
116# String-keyed objects shouldn't suppress newlines.
117one =
118  '>!': 3
119six: -> 10
120ok not one.six
121
122# Shorthand objects with property references.
123obj =
124  ### comment one ###
125  ### comment two ###
126  one: 1
127  two: 2
128  object: -> {@one, @two}
129  list:   -> [@one, @two]
130result = obj.object()
131eq result.one, 1
132eq result.two, 2
133eq result.two, obj.list()[1]
134
135third = (a, b, c) -> c
136obj =
137  one: 'one'
138  two: third 'one', 'two', 'three'
139ok obj.one is 'one'
140ok obj.two is 'three'
141
142test "invoking functions with implicit object literals", ->
143  generateGetter = (prop) -> (obj) -> obj[prop]
144  getA = generateGetter 'a'
145  getArgs = -> arguments
146  a = b = 30
147
148  result = getA
149    a: 10
150  eq 10, result
151
152  result = getA
153    "a": 20
154  eq 20, result
155
156  result = getA a,
157    b:1
158  eq undefined, result
159
160  result = getA b:1,
161  a:43
162  eq 43, result
163
164  result = getA b:1,
165    a:62
166  eq undefined, result
167
168  result = getA
169    b:1
170    a
171  eq undefined, result
172
173  result = getA
174    a:
175      b:2
176    b:1
177  eq 2, result.b
178
179  result = getArgs
180    a:1
181    b
182    c:1
183  ok result.length is 3
184  ok result[2].c is 1
185
186  result = getA b: 13, a: 42, 2
187  eq 42, result
188
189  result = getArgs a:1, (1 + 1)
190  ok result[1] is 2
191
192  result = getArgs a:1, b
193  ok result.length is 2
194  ok result[1] is 30
195
196  result = getArgs a:1, b, b:1, a
197  ok result.length is 4
198  ok result[2].b is 1
199
200  throwsCompileError "a = b:1, c"
201
202test "some weird indentation in YAML-style object literals", ->
203  two = (a, b) -> b
204  obj = then two 1,
205    1: 1
206    a:
207      b: ->
208        fn c,
209          d: e
210    f: 1
211  eq 1, obj[1]
212
213test "#1274: `{} = a()` compiles to `false` instead of `a()`", ->
214  a = false
215  fn = -> a = true
216  {} = fn()
217  ok a
218
219test "#1436: `for` etc. work as normal property names", ->
220  obj = {}
221  eq no, obj.hasOwnProperty 'for'
222  obj.for = 'foo' of obj
223  eq yes, obj.hasOwnProperty 'for'
224
225test "#2706, Un-bracketed object as argument causes inconsistent behavior", ->
226  foo = (x, y) -> y
227  bar = baz: yes
228
229  eq yes, foo x: 1, bar.baz
230
231test "#2608, Allow inline objects in arguments to be followed by more arguments", ->
232  foo = (x, y) -> y
233
234  eq yes, foo x: 1, y: 2, yes
235
236test "#2308, a: b = c:1", ->
237  foo = a: b = c: yes
238  eq b.c, yes
239  eq foo.a.c, yes
240
241test "#2317, a: b c: 1", ->
242  foo = (x) -> x
243  bar = a: foo c: yes
244  eq bar.a.c, yes
245
246test "#1896, a: func b, {c: d}", ->
247  first = (x) -> x
248  second = (x, y) -> y
249  third = (x, y, z) -> z
250
251  one = 1
252  two = 2
253  three = 3
254  four = 4
255
256  foo = a: second one, {c: two}
257  eq foo.a.c, two
258
259  bar = a: second one, c: two
260  eq bar.a.c, two
261
262  baz = a: second one, {c: two}, e: first first h: three
263  eq baz.a.c, two
264
265  qux = a: third one, {c: two}, e: first first h: three
266  eq qux.a.e.h, three
267
268  quux = a: third one, {c: two}, e: first(three), h: four
269  eq quux.a.e, three
270  eq quux.a.h, four
271
272  corge = a: third one, {c: two}, e: second three, h: four
273  eq corge.a.e.h, four
274
275test "Implicit objects, functions and arrays", ->
276  first  = (x) -> x
277  second = (x, y) -> y
278
279  foo = [
280    1
281    one: 1
282    two: 2
283    three: 3
284    more:
285      four: 4
286      five: 5, six: 6
287    2, 3, 4
288    5]
289  eq foo[2], 2
290  eq foo[1].more.six, 6
291
292  bar = [
293    1
294    first first first second 1,
295      one: 1, twoandthree: twoandthree: two: 2, three: 3
296      2,
297    2
298    one: 1
299    two: 2
300    three: first second ->
301      no
302    , ->
303      3
304    3
305    4]
306  eq bar[2], 2
307  eq bar[1].twoandthree.twoandthree.two, 2
308  eq bar[3].three(), 3
309  eq bar[4], 3
310
311test "#2549, Brace-less Object Literal as a Second Operand on a New Line", ->
312  foo = no or
313    one: 1
314    two: 2
315    three: 3
316  eq foo.one, 1
317
318  bar = yes and one: 1
319  eq bar.one, 1
320
321  baz = null ?
322    one: 1
323    two: 2
324  eq baz.two, 2
325
326test "#2757, Nested", ->
327  foo =
328    bar:
329      one: 1,
330  eq foo.bar.one, 1
331
332  baz =
333    qux:
334      one: 1,
335    corge:
336      two: 2,
337      three: three: three: 3,
338    xyzzy:
339      thud:
340        four:
341          four: 4,
342      five: 5,
343
344  eq baz.qux.one, 1
345  eq baz.corge.three.three.three, 3
346  eq baz.xyzzy.thud.four.four, 4
347  eq baz.xyzzy.five, 5
348
349test "#1865, syntax regression 1.1.3", ->
350  foo = (x, y) -> y
351
352  bar = a: foo (->),
353    c: yes
354  eq bar.a.c, yes
355
356  baz = a: foo (->), c: yes
357  eq baz.a.c, yes
358
359
360test "#1322: implicit call against implicit object with block comments", ->
361  ((obj, arg) ->
362    eq obj.x * obj.y, 6
363    ok not arg
364  )
365    ###
366    x
367    ###
368    x: 2
369    ### y ###
370    y: 3
371
372test "#1513: Top level bare objs need to be wrapped in parens for unary and existence ops", ->
373  doesNotThrow -> CoffeeScript.run "{}?", bare: true
374  doesNotThrow -> CoffeeScript.run "{}.a++", bare: true
375
376test "#1871: Special case for IMPLICIT_END in the middle of an implicit object", ->
377  result = 'result'
378  ident = (x) -> x
379
380  result = ident one: 1 if false
381
382  eq result, 'result'
383
384  result = ident
385    one: 1
386    two: 2 for i in [1..3]
387
388  eq result.two.join(' '), '2 2 2'
389
390test "#1871: implicit object closed by IMPLICIT_END in implicit returns", ->
391  ob = do ->
392    a: 1 if no
393  eq ob, undefined
394
395  # instead these return an object
396  func = ->
397    key:
398      i for i in [1, 2, 3]
399
400  eq func().key.join(' '), '1 2 3'
401
402  func = ->
403    key: (i for i in [1, 2, 3])
404
405  eq func().key.join(' '), '1 2 3'
406
407test "#1961, #1974, regression with compound assigning to an implicit object", ->
408
409  obj = null
410
411  obj ?=
412    one: 1
413    two: 2
414
415  eq obj.two, 2
416
417  obj = null
418
419  obj or=
420    three: 3
421    four: 4
422
423  eq obj.four, 4
424
425test "#2207: Immediate implicit closes don't close implicit objects", ->
426  func = ->
427    key: for i in [1, 2, 3] then i
428
429  eq func().key.join(' '), '1 2 3'
430
431test "#3216: For loop declaration as a value of an implicit object", ->
432  test = [0..2]
433  ob =
434    a: for v, i in test then i
435    b: for v, i in test then i
436    c: for v in test by 1 then v
437    d: for v in test when true then v
438  arrayEq ob.a, test
439  arrayEq ob.b, test
440  arrayEq ob.c, test
441  arrayEq ob.d, test
442  byFirstKey =
443    a: for v in test by 1 then v
444  arrayEq byFirstKey.a, test
445  whenFirstKey =
446    a: for v in test when true then v
447  arrayEq whenFirstKey.a, test
448
449test 'inline implicit object literals within multiline implicit object literals', ->
450  x =
451    a: aa: 0
452    b: 0
453  eq 0, x.b
454  eq 0, x.a.aa
455
456test "object keys with interpolations: simple cases", ->
457  a = 'a'
458  obj = "#{a}": yes
459  eq obj.a, yes
460  obj = {"#{a}": yes}
461  eq obj.a, yes
462  obj = {"#{a}"}
463  eq obj.a, 'a'
464  obj = {"#{5}"}
465  eq obj[5], '5' # Note that the value is a string, just like the key.
466
467test "object keys with interpolations: commas in implicit object", ->
468  obj = "#{'a'}": 1, b: 2
469  deepEqual obj, {a: 1, b: 2}
470  obj = a: 1, "#{'b'}": 2
471  deepEqual obj, {a: 1, b: 2}
472  obj = "#{'a'}": 1, "#{'b'}": 2
473  deepEqual obj, {a: 1, b: 2}
474
475test "object keys with interpolations: commas in explicit object", ->
476  obj = {"#{'a'}": 1, b: 2}
477  deepEqual obj, {a: 1, b: 2}
478  obj = {a: 1, "#{'b'}": 2}
479  deepEqual obj, {a: 1, b: 2}
480  obj = {"#{'a'}": 1, "#{'b'}": 2}
481  deepEqual obj, {a: 1, b: 2}
482
483test "object keys with interpolations: commas after key with interpolation", ->
484  obj = {"#{'a'}": yes,}
485  eq obj.a, yes
486  obj = {
487    "#{'a'}": 1,
488    "#{'b'}": 2,
489    ### herecomment ###
490    "#{'c'}": 3,
491  }
492  deepEqual obj, {a: 1, b: 2, c: 3}
493  obj =
494    "#{'a'}": 1,
495    "#{'b'}": 2,
496    ### herecomment ###
497    "#{'c'}": 3,
498  deepEqual obj, {a: 1, b: 2, c: 3}
499  obj =
500    "#{'a'}": 1,
501    "#{'b'}": 2,
502    ### herecomment ###
503    "#{'c'}": 3, "#{'d'}": 4,
504  deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
505
506test "object keys with interpolations: key with interpolation mixed with `@prop`", ->
507  deepEqual (-> {@a, "#{'b'}": 2}).call(a: 1), {a: 1, b: 2}
508
509test "object keys with interpolations: evaluate only once", ->
510  count = 0
511  a = -> count++; 'a'
512  obj = {"#{a()}"}
513  eq obj.a, 'a'
514  eq count, 1
515
516test "object keys with interpolations: evaluation order", ->
517  arr = []
518  obj =
519    a: arr.push 1
520    b: arr.push 2
521    "#{'c'}": arr.push 3
522    "#{'d'}": arr.push 4
523    e: arr.push 5
524    "#{'f'}": arr.push 6
525    g: arr.push 7
526  arrayEq arr, [1..7]
527  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
528
529test "object keys with interpolations: object starting with dynamic key", ->
530  obj =
531    "#{'a'}": 1
532    b: 2
533  deepEqual obj, {a: 1, b: 2}
534
535test "object keys with interpolations: comments in implicit object", ->
536  obj =
537    ### leading comment ###
538    "#{'a'}": 1
539
540    ### middle ###
541
542    "#{'b'}": 2
543    # regular comment
544    'c': 3
545    ### foo ###
546    d: 4
547    "#{'e'}": 5
548  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
549
550  # Comments in explicit object.
551  obj = {
552    ### leading comment ###
553    "#{'a'}": 1
554
555    ### middle ###
556
557    "#{'b'}": 2
558    # regular comment
559    'c': 3
560    ### foo ###
561    d: 4
562    "#{'e'}": 5
563  }
564  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
565
566test "object keys with interpolations: more complicated case", ->
567  obj = {
568    "#{'interpolated'}":
569      """
570        #{ '''nested''' }
571      """: 123: 456
572  }
573  deepEqual obj,
574    interpolated:
575      nested:
576        123: 456
577
578test "#4324: Shorthand after interpolated key", ->
579  a = 2
580  obj = {"#{1}": 1, a}
581  eq 1, obj[1]
582  eq 2, obj.a
583
584test "computed property keys: simple cases", ->
585  a = 'a'
586  obj = [a]: yes
587  eq obj.a, yes
588  obj = {[a]: yes}
589  eq obj.a, yes
590  obj = {[a]}
591  eq obj.a, 'a'
592  obj = {[5]}
593  eq obj[5], 5
594  obj = {['5']}
595  eq obj['5'], '5'
596
597test "computed property keys: commas in implicit object", ->
598  obj = ['a']: 1, b: 2
599  deepEqual obj, {a: 1, b: 2}
600  obj = a: 1, ['b']: 2
601  deepEqual obj, {a: 1, b: 2}
602  obj = ['a']: 1, ['b']: 2
603  deepEqual obj, {a: 1, b: 2}
604
605test "computed property keys: commas in explicit object", ->
606  obj = {['a']: 1, b: 2}
607  deepEqual obj, {a: 1, b: 2}
608  obj = {a: 1, ['b']: 2}
609  deepEqual obj, {a: 1, b: 2}
610  obj = {['a']: 1, ['b']: 2}
611  deepEqual obj, {a: 1, b: 2}
612
613test "computed property keys: commas after key with interpolation", ->
614  obj = {['a']: yes,}
615  eq obj.a, yes
616  obj = {
617    ['a']: 1,
618    ['b']: 2,
619    ### herecomment ###
620    ['c']: 3,
621  }
622  deepEqual obj, {a: 1, b: 2, c: 3}
623  obj =
624    ['a']: 1,
625    ['b']: 2,
626    ### herecomment ###
627    ['c']: 3,
628  deepEqual obj, {a: 1, b: 2, c: 3}
629  obj =
630    ['a']: 1,
631    ['b']: 2,
632    ### herecomment ###
633    ['c']: 3, ['d']: 4,
634  deepEqual obj, {a: 1, b: 2, c: 3, d: 4}
635
636test "computed property keys: key with interpolation mixed with `@prop`", ->
637  deepEqual (-> {@a, ['b']: 2}).call(a: 1), {a: 1, b: 2}
638
639test "computed property keys: evaluate only once", ->
640  count = 0
641  a = -> count++; 'a'
642  obj = {[a()]}
643  eq obj.a, 'a'
644  eq count, 1
645
646test "computed property keys: evaluation order", ->
647  arr = []
648  obj =
649    a: arr.push 1
650    b: arr.push 2
651    ['c']: arr.push 3
652    ['d']: arr.push 4
653    e: arr.push 5
654    ['f']: arr.push 6
655    g: arr.push 7
656  arrayEq arr, [1..7]
657  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7}
658
659test "computed property keys: object starting with dynamic key", ->
660  obj =
661    ['a']: 1
662    b: 2
663  deepEqual obj, {a: 1, b: 2}
664
665test "computed property keys: comments in implicit object", ->
666  obj =
667    ### leading comment ###
668    ['a']: 1
669
670    ### middle ###
671
672    ['b']: 2
673    # regular comment
674    'c': 3
675    ### foo ###
676    d: 4
677    ['e']: 5
678  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
679
680  obj = {
681    ### leading comment ###
682    ['a']: 1
683
684    ### middle ###
685
686    ['b']: 2
687    # regular comment
688    'c': 3
689    ### foo ###
690    d: 4
691    ['e']: 5
692  }
693  deepEqual obj, {a: 1, b: 2, c: 3, d: 4, e: 5}
694
695test "computed property keys: more complicated case", ->
696  obj = {
697    ['interpolated']:
698       ['nested']:
699         123: 456
700  }
701  deepEqual obj,
702    interpolated:
703      nested:
704        123: 456
705
706test "computed property keys: empty array as key", ->
707  o1 = { [[]] }
708  deepEqual o1, { [[]]: [] }
709  arrayEq o1[[]], []
710  o2 = { [[]]: 1 }
711  deepEqual o2, { [[]]: 1 }
712  eq o2[[]], 1
713  o3 = [[]]: 1
714  deepEqual o3, { [[]]: 1 }
715  deepEqual o3, { [[]]: 1 }
716  eq o3[[]], 1
717  o4 = a: 1, [[]]: 2
718  deepEqual o4, { a: 1, [[]]: 2 }
719  eq o4.a, 1,
720  eq o4[[]], 2
721  o5 = { a: 1, [[]]: 2 }
722  deepEqual o5, { a: 1, [[]]: 2 }
723  eq o5.a, 1,
724  eq o5[[]], 2
725
726test "computed property keys: shorthand after computed property key", ->
727  a = 2
728  obj = {[1]: 1, a}
729  eq 1, obj[1]
730  eq 2, obj.a
731
732test "computed property keys: shorthand computed property key", ->
733  a = 'b'
734  o = {[a]}
735  p = {a}
736  r = {['a']}
737  eq o.b, 'b'
738  eq p.a, o.b
739  eq r.a, 'a'
740
741  foo = -> "a"
742  obj = { [foo()] }
743  eq obj.a, 'a'
744
745test "computed property keys: arrays", ->
746  b = 'b'
747  f = (c) -> "#{c}1"
748  obj =
749    ['a']: [1, 2, 3]
750    [b]: [4, 5, 6]
751    [f(b)]: [7, 8, 9]
752  arrayEq obj.a, [1, 2, 3]
753  arrayEq obj.b, [4, 5, 6]
754  arrayEq obj.b1, [7, 8, 9]
755
756test "computed property keys: examples from developer.mozilla.org (Object initializer)", ->
757  i = 0
758  obj =
759    ['foo' + ++i]: i
760    ['foo' + ++i]: i
761    ['foo' + ++i]: i
762  eq obj.foo1, 1
763  eq obj.foo2, 2
764  eq obj.foo3, 3
765
766  param = 'size'
767  config =
768    [param]: 12,
769    ['mobile' + param.charAt(0).toUpperCase() + param.slice(1)]: 4
770  deepEqual config, {size: 12,  mobileSize: 4}
771
772test "computed property keys: [Symbol.iterator]", ->
773  obj =
774    [Symbol.iterator]: ->
775      yield "hello"
776      yield "world"
777  arrayEq [obj...], ['hello', 'world']
778
779test "computed property keys: Class property", ->
780  increment_method = "increment"
781  decrement_method = "decrement"
782  class Obs
783    constructor: (@count) ->
784    [increment_method]: -> @count += 1
785    [decrement_method]: -> @count -= 1
786  ob = new Obs 2
787  eq ob.increment(), 3
788  eq ob.decrement(), 2
789
790test "#1263: Braceless object return", ->
791  fn = ->
792    return
793      a: 1
794      b: 2
795      c: -> 3
796
797  obj = fn()
798  eq 1, obj.a
799  eq 2, obj.b
800  eq 3, obj.c()
801
802test "#4564: indent should close implicit object", ->
803  f = (x) -> x
804
805  arrayEq ['a'],
806    for key of f a: 1
807      key
808
809  g = null
810  if f a: 1
811    g = 3
812  eq g, 3
813
814  h = null
815  if a: (i for i in [1, 2, 3])
816    h = 4
817  eq h, 4
818
819test "#4544: Postfix conditionals in first line of implicit object literals", ->
820  two =
821    foo:
822      bar: 42 if yes
823      baz: 1337
824  eq 42, two.foo.bar
825  eq 1337, two.foo.baz
826
827  f = (x) -> x
828
829  three =
830    foo: f
831      bar: 42 if yes
832      baz: 1337
833  eq 42, three.foo.bar
834  eq 1337, three.foo.baz
835
836  four =
837    f
838      foo:
839        bar: 42 if yes
840      baz: 1337
841  eq 42, four.foo.bar
842  eq 1337, four.baz
843
844  x = bar: 42 if no
845  baz: 1337
846  ok not x?
847
848  # Example from #2051
849  a = null
850  _alert = (arg) -> a = arg
851  _alert
852    val3: "works" if true
853    val: "hello"
854    val2: "all good"
855  eq a.val2, "all good"
856
857test "#4579: Postfix for/while/until in first line of implicit object literals", ->
858  two =
859    foo:
860      bar1: x for x in [1, 2, 3]
861      bar2: x + y for x, y in [1, 2, 3]
862      baz: 1337
863  arrayEq [1, 2, 3], two.foo.bar1
864  arrayEq [1, 3, 5], two.foo.bar2
865  eq 1337, two.foo.baz
866
867  f = (x) -> x
868
869  three =
870    foo: f
871      bar1: x + y for x, y of a: 'b', c: 'd'
872      bar2: x + 'c' for x of a: 1, b: 2
873      baz: 1337
874  arrayEq ['ab', 'cd'], three.foo.bar1
875  arrayEq ['ac', 'bc'], three.foo.bar2
876  eq 1337, three.foo.baz
877
878  four =
879    f
880      foo:
881        "bar_#{x}": x for x of a: 1, b: 2
882      baz: 1337
883  eq 'a', four.foo[0].bar_a
884  eq 'b', four.foo[1].bar_b
885  eq 1337, four.baz
886
887  x = bar: 42 for y in [1]
888  baz: 1337
889  eq x.bar, 42
890
891  i = 5
892  five =
893    foo:
894      bar: i while i-- > 0
895      baz: 1337
896  arrayEq [4, 3, 2, 1, 0], five.foo.bar
897  eq 1337, five.foo.baz
898
899  i = 5
900  six =
901    foo:
902      bar: i until i-- <= 0
903      baz: 1337
904  arrayEq [4, 3, 2, 1, 0], six.foo.bar
905  eq 1337, six.foo.baz
906
907test "#5204: not parsed as static property", ->
908  doesNotThrowCompileError "@ [b]: 2"
909
910test "#5292: implicit object after line continuer in implicit object property value", ->
911  a =
912    b: 0 or
913      c: 1
914  eq 1, a.b.c
915
916  # following object property
917  a =
918    b: null ?
919      c: 1
920    d: 2
921  eq 1, a.b.c
922  eq 2, a.d
923
924  # multiline nested object
925  a =
926    b: 0 or
927      c: 1
928      d: 2
929    e: 3
930  eq 1, a.b.c
931  eq 2, a.b.d
932  eq 3, a.e