================================================================================
api/mapping
================================================================================

amends "../snippetTest.pkl"

local base = new Mapping {
  default {
    name = Undefined()
    age = 42
  }
  ["Pigeon"] {
    name = "Pigeon"
  }
  ["Parrot"] {
    name = "Parrot"
    age = 24
  }
}

local derived = (base) {
  ["Pigeon"] {
    name = "Piggy"
  }
  ["Barn Owl"] {
    name = "Barn Owl"
    age = 84
  }
}

local empty = new Mapping {
  default = (_) -> 1
}

local empty2 = (empty) {
  default = (name) -> name.length + 2
  local `_` = 42
  local function `_`() = 42
}

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

  ["containsKey()"] {
    base.containsKey("Pigeon")
    base.containsKey("Parrot")
    !base.containsKey("Barn Owl")
    !base.containsKey("Other")

    derived.containsKey("Pigeon")
    derived.containsKey("Parrot")
    derived.containsKey("Barn Owl")
    !derived.containsKey("Other")

    !empty.containsKey("Pigeon")
    !empty.containsKey("default")
    !empty2.containsKey("Pigeon")
  }
  
  ["length"] {
    empty.length == 0
    base.length == 2
    derived.length == 3
  }
  
  ["keys (of type string)"] {
    empty.keys == Set()
    derived.keys == Set("Pigeon", "Parrot", "Barn Owl")
    base.keys == Set("Pigeon", "Parrot")
  }
  
  ["keys (of type object)"] {
    local base2 = new Mapping {
      [empty] = "one"
      [base] = "two"
    }
    local derived2 = (base2) {
      [derived] = "three"
    }

    base2.keys == Set(empty, base)
    derived2.keys == Set(empty, base, derived)
  }
}

examples {
  ["getOrNull()"] {
    base.getOrNull("Pigeon")
    base.getOrNull("Parrot")
    base.getOrNull("Barn Owl")
    base.getOrNull("Other")

    derived.getOrNull("Pigeon")
    derived.getOrNull("Parrot")
    derived.getOrNull("Barn Owl")
    derived.getOrNull("Other")

    empty.getOrNull("Pigeon")
    empty2.getOrNull("Pigeon")
  }

  ["fold()"] {
    base.fold(List(), (l, k, v) -> l.add(Pair(k, v)))
    derived.fold(List(), (l, k, v) -> l.add(Pair(k, v)))
    empty.fold(List(), (l, k, v) -> l.add(Pair(k, v)))
    empty2.fold(List(), (l, k, v) -> l.add(Pair(k, v)))
  }

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

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

(module
  (moduleHeader
    (extendsOrAmendsClause
      (stringConstant)))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody
        (objectProperty
          (identifier)
          (objectBody
            (objectProperty
              (identifier)
              (methodCallExpr
                (identifier)
                (argumentList)))
            (objectProperty
              (identifier)
              (intLiteral))))
        (objectEntry
          (slStringLiteral)
          (objectBody
            (objectProperty
              (identifier)
              (slStringLiteral))))
        (objectEntry
          (slStringLiteral)
          (objectBody
            (objectProperty
              (identifier)
              (slStringLiteral))
            (objectProperty
              (identifier)
              (intLiteral)))))))
  (classProperty
    (modifier)
    (identifier)
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody
        (objectEntry
          (slStringLiteral)
          (objectBody
            (objectProperty
              (identifier)
              (slStringLiteral))))
        (objectEntry
          (slStringLiteral)
          (objectBody
            (objectProperty
              (identifier)
              (slStringLiteral))
            (objectProperty
              (identifier)
              (intLiteral)))))))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody
        (objectProperty
          (identifier)
          (functionLiteral
            (parameterList
              (typedIdentifier
                (identifier)))
            (intLiteral))))))
  (classProperty
    (modifier)
    (identifier)
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody
        (objectProperty
          (identifier)
          (functionLiteral
            (parameterList
              (typedIdentifier
                (identifier)))
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (intLiteral))))
        (objectProperty
          (modifier)
          (identifier)
          (intLiteral))
        (objectMethod
          (methodHeader
            (modifier)
            (identifier)
            (parameterList))
          (intLiteral)))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (propertyCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))
          (objectElement
            (propertyCallExpr
              (variableExpr
                (identifier))
              (identifier)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (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
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (unaryExpr
                (variableExpr
                  (identifier)))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (intLiteral)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (methodCallExpr
                (identifier)
                (argumentList))))
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (methodCallExpr
                (identifier)
                (argumentList
                  (slStringLiteral)
                  (slStringLiteral)
                  (slStringLiteral)))))
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (methodCallExpr
                (identifier)
                (argumentList
                  (slStringLiteral)
                  (slStringLiteral)))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectProperty
            (modifier)
            (identifier)
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectEntry
                  (variableExpr
                    (identifier))
                  (slStringLiteral))
                (objectEntry
                  (variableExpr
                    (identifier))
                  (slStringLiteral)))))
          (objectProperty
            (modifier)
            (identifier)
            (objectLiteral
              (parenthesizedExpr
                (variableExpr
                  (identifier)))
              (objectBody
                (objectEntry
                  (variableExpr
                    (identifier))
                  (slStringLiteral)))))
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (methodCallExpr
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))
                  (variableExpr
                    (identifier))))))
          (objectElement
            (binaryExpr
              (propertyCallExpr
                (variableExpr
                  (identifier))
                (identifier))
              (methodCallExpr
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))
                  (variableExpr
                    (identifier))
                  (variableExpr
                    (identifier))))))))))
  (classProperty
    (identifier)
    (objectBody
      (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))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (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))))))))))
          (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))))))))))))
      (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))))))))
