================================================================================
api/listing
================================================================================

amends "../snippetTest.pkl"

local class Person { name: String }

local empty = new Listing {}

local empty2 = (empty) {}

local base: Listing<Person> = new {
  new { name = "Pigeon" }
  new { name = "Barn Owl" }
  new { name = "Parrot" }
}

local derived: Listing<Person> = (base) {
  new { name = "Albatross" }
  new { name = "Elf Owl" }
}

local duplicate: Listing<Person> = (base) {
  new { name = "Albatross" }
  new { name = "Parrot" }
  new { name = "Elf Owl" }
}

facts {
  ["isEmpty"] {
    empty.isEmpty
    empty2.isEmpty
    !base.isEmpty
    !derived.isEmpty
  }

  ["isDistinct"] {
    empty.isDistinct
    empty2.isDistinct
    base.isDistinct
    derived.isDistinct
    !duplicate.isDistinct
  }

  ["isDistinctBy()"] {
    empty.isDistinctBy((it) -> it)
    empty2.isDistinctBy((it) -> it)
    base.isDistinctBy((it) -> it)
    derived.isDistinctBy((it) -> it)
    !duplicate.isDistinctBy((it) -> it)

    empty.isDistinctBy((it) -> it.name)
    empty2.isDistinctBy((it) -> it.name)
    base.isDistinctBy((it) -> it.name)
    derived.isDistinctBy((it) -> it.name)
    !duplicate.isDistinctBy((it) -> it.name)

    empty.isDistinctBy((it) -> it.getClass())
    empty2.isDistinctBy((it) -> it.getClass())
    !base.isDistinctBy((it) -> it.getClass())
    !derived.isDistinctBy((it) -> it.getClass())
    !duplicate.isDistinctBy((it) -> it.getClass())
  }
}

examples {
  ["length"] {
    empty.length
    empty2.length
    base.length
    derived.length
  }

  ["toList()"] {
    empty.toList()
    empty2.toList()
    base.toList()
    derived.toList()
    duplicate.toList()
  }

  ["toSet()"] {
    empty.toSet()
    empty2.toSet()
    base.toSet()
    derived.toSet()
    duplicate.toSet()
  }

  ["distinct"] {
    empty.distinct
    empty2.distinct
    base.distinct
    derived.distinct
    duplicate.distinct
  }

  ["distinctBy()"] {
    empty.distinctBy((it) -> it)
    empty2.distinctBy((it) -> it)
    base.distinctBy((it) -> it)
    derived.distinctBy((it) -> it)
    duplicate.distinctBy((it) -> it)

    empty.distinctBy((it) -> it.name)
    empty2.distinctBy((it) -> it.name)
    base.distinctBy((it) -> it.name)
    derived.distinctBy((it) -> it.name)
    duplicate.distinctBy((it) -> it.name)

    empty.distinctBy((it) -> it.getClass())
    empty2.distinctBy((it) -> it.getClass())
    base.distinctBy((it) -> it.getClass())
    derived.distinctBy((it) -> it.getClass())
    duplicate.distinctBy((it) -> it.getClass())
  }

  ["fold"] {
    empty.fold(List(), (l, e) -> l.add(e))
    base.fold(List(), (l, e) -> l.add(e))
    derived.fold(List(), (l, e) -> l.add(e))
  }

  ["foldIndexed"] {
    empty.foldIndexed(List(), (i, l, e) -> l.add(Pair(i, e)))
    base.foldIndexed(List(), (i, l, e) -> l.add(Pair(i, e)))
    derived.foldIndexed(List(), (i, l, e) -> l.add(Pair(i, e)))
  }


  local baseNum = new Listing { 1; 2; 3 }
  local baseString = new Listing { "Pigeon"; "Barn Owl"; "Parrot" }
  local derivedString = (baseString) { "Albatross"; "Elf Owl" }

  ["join"] {
    empty.join("")
    baseNum.join("")
    baseNum.join(", ")
    baseString.join("")
    baseString.join("---")
    derivedString.join("")
    derivedString.join("\n")
  }
}

--------------------------------------------------------------------------------

(module
  (moduleHeader
    (extendsOrAmendsClause
      (stringConstant)))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody)))
  (classProperty
    (modifier)
    (identifier)
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody)))
  (classProperty
    (modifier)
    (identifier)
    (typeAnnotation
      (type
        (qualifiedIdentifier
          (identifier))
        (typeArgumentList
          (type
            (qualifiedIdentifier
              (identifier))))))
    (newExpr
      (objectBody
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral)))))
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral)))))
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral))))))))
  (classProperty
    (modifier)
    (identifier)
    (typeAnnotation
      (type
        (qualifiedIdentifier
          (identifier))
        (typeArgumentList
          (type
            (qualifiedIdentifier
              (identifier))))))
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral)))))
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral))))))))
  (classProperty
    (modifier)
    (identifier)
    (typeAnnotation
      (type
        (qualifiedIdentifier
          (identifier))
        (typeArgumentList
          (type
            (qualifiedIdentifier
              (identifier))))))
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral)))))
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral)))))
        (objectElement
          (newExpr
            (objectBody
              (objectProperty
                (identifier)
                (slStringLiteral))))))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (propertyCallExpr
                    (variableExpr
                      (identifier))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (methodCallExpr
                  (identifier)
                  (argumentList))
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (methodCallExpr
                  (identifier)
                  (argumentList))
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (methodCallExpr
                  (identifier)
                  (argumentList))
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (methodCallExpr
                  (identifier)
                  (argumentList))
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (variableExpr
                            (identifier))
                          (variableExpr
                            (identifier))))))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (methodCallExpr
                  (identifier)
                  (argumentList))
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (variableExpr
                            (identifier))
                          (variableExpr
                            (identifier))))))))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (methodCallExpr
                  (identifier)
                  (argumentList))
                (functionLiteral
                  (parameterList
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier))
                    (typedIdentifier
                      (identifier)))
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (variableExpr
                            (identifier))
                          (variableExpr
                            (identifier))))))))))))
      (objectProperty
        (modifier)
        (identifier)
        (newExpr
          (type
            (qualifiedIdentifier
              (identifier)))
          (objectBody
            (objectElement
              (intLiteral))
            (objectElement
              (intLiteral))
            (objectElement
              (intLiteral)))))
      (objectProperty
        (modifier)
        (identifier)
        (newExpr
          (type
            (qualifiedIdentifier
              (identifier)))
          (objectBody
            (objectElement
              (slStringLiteral))
            (objectElement
              (slStringLiteral))
            (objectElement
              (slStringLiteral)))))
      (objectProperty
        (modifier)
        (identifier)
        (objectLiteral
          (parenthesizedExpr
            (variableExpr
              (identifier)))
          (objectBody
            (objectElement
              (slStringLiteral))
            (objectElement
              (slStringLiteral)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral
                  (escapeSequence))))))))))
