================================================================================
api/dynamic
================================================================================

amends "../snippetTest.pkl"

facts {
  ["length()"] {
    obj.length() == 2
    ((obj) { "three"; "four" } { x = 1 } { "five" } {}).length() == 5
    obj2.length() == 2
    new Dynamic {}.length() == 0
    new Dynamic { name = "Pigeon" }.length() == 0
    new Dynamic { ["name"] = "Pigeon" }.length() == 0
  }
}

examples {
  ["getProperty()"] {
    pigeon.getProperty("name")
    pigeon.getProperty("na" + "me")
    pigeon.getProperty("age")
    module.catch(() -> pigeon.getProperty("other"))
  }

  ["getPropertyOrNull()"] {
    pigeon.getPropertyOrNull("name")
    pigeon.getPropertyOrNull("na" + "me")
    pigeon.getPropertyOrNull("age")
    pigeon.getPropertyOrNull("other")
  }

  ["hasProperty()"] {
    pigeon.hasProperty("name")
    pigeon.hasProperty("na" + "me")
    pigeon.hasProperty("age")
    pigeon.hasProperty("other")

    futurePigeon.hasProperty("name")
    pigeon.hasProperty("nostalgia")
    futurePigeon.hasProperty("nostalgia")
  }

  ["toMap()"] {
    pigeon.toMap()
    obj.toMap()
    obj2.toMap()
  }

  ["toList()"] {
    pigeon.toList()
    obj.toList()
    obj2.toList()
  }

  ["toTyped()"] {
    pigeon.toTyped(Person)
    futurePigeon.toTyped(Person)
    new Dynamic { age = 42 }.toTyped(Person)
    new Dynamic { name = "Pigeon" }.toTyped(Person).name
    module.catch(() -> new Dynamic { name = "Pigeon" }.toTyped(Person).age)
    module.catch(() -> obj.toTyped(Pair)) // Pair is not a Typed
    module.catch(() -> obj.toTyped(ValueRenderer)) // ValueRenderer is abstract
  }
}

local obj = new Dynamic {
  prop1 = "prop1"
  prop2 = "prop2"
  ["name"] = "Pigeon"
  ["age"] = 42
  "one"
  "two"
}

local obj2 = (obj) {
  [0] = "one one"
  [1] = "two two"
}

local pigeon = new Dynamic {
  local n = "Pigeon"
  name = n
  age = 42
}

local futurePigeon = (pigeon) {
  age = 43
  nostalgia = true
}

local class Person {
  name: String = "Default"
  age: UInt
}

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

(module
  (moduleHeader
    (extendsOrAmendsClause
      (stringConstant)))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (binaryExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (methodCallExpr
                (parenthesizedExpr
                  (objectLiteral
                    (objectLiteral
                      (objectLiteral
                        (objectLiteral
                          (parenthesizedExpr
                            (variableExpr
                              (identifier)))
                          (objectBody
                            (objectElement
                              (slStringLiteral))
                            (objectElement
                              (slStringLiteral))))
                        (objectBody
                          (objectProperty
                            (identifier)
                            (intLiteral))))
                      (objectBody
                        (objectElement
                          (slStringLiteral))))
                    (objectBody)))
                (identifier)
                (argumentList))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (methodCallExpr
                (variableExpr
                  (identifier))
                (identifier)
                (argumentList))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (methodCallExpr
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody))
                (identifier)
                (argumentList))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (methodCallExpr
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (slStringLiteral))))
                (identifier)
                (argumentList))
              (intLiteral)))
          (objectElement
            (binaryExpr
              (methodCallExpr
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectEntry
                      (slStringLiteral)
                      (slStringLiteral))))
                (identifier)
                (argumentList))
              (intLiteral)))))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (binaryExpr
                  (slStringLiteral)
                  (slStringLiteral)))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (slStringLiteral)))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (binaryExpr
                  (slStringLiteral)
                  (slStringLiteral)))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (slStringLiteral))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (binaryExpr
                  (slStringLiteral)
                  (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)))
          (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)))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (variableExpr
                  (identifier)))))
          (objectElement
            (methodCallExpr
              (variableExpr
                (identifier))
              (identifier)
              (argumentList
                (variableExpr
                  (identifier)))))
          (objectElement
            (methodCallExpr
              (newExpr
                (type
                  (qualifiedIdentifier
                    (identifier)))
                (objectBody
                  (objectProperty
                    (identifier)
                    (intLiteral))))
              (identifier)
              (argumentList
                (variableExpr
                  (identifier)))))
          (objectElement
            (propertyCallExpr
              (methodCallExpr
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (slStringLiteral))))
                (identifier)
                (argumentList
                  (variableExpr
                    (identifier))))
              (identifier)))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (propertyCallExpr
                    (methodCallExpr
                      (newExpr
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (objectBody
                          (objectProperty
                            (identifier)
                            (slStringLiteral))))
                      (identifier)
                      (argumentList
                        (variableExpr
                          (identifier))))
                    (identifier))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (variableExpr
                      (identifier))
                    (identifier)
                    (argumentList
                      (variableExpr
                        (identifier))))))))
          (lineComment)
          (objectElement
            (propertyCallExpr
              (moduleExpr)
              (identifier)))
          (objectElement
            (parenthesizedExpr
              (functionLiteral
                (parameterList)
                (methodCallExpr
                  (variableExpr
                    (identifier))
                  (identifier)
                  (argumentList
                    (variableExpr
                      (identifier)))))))
          (lineComment)))))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody
        (objectProperty
          (identifier)
          (slStringLiteral))
        (objectProperty
          (identifier)
          (slStringLiteral))
        (objectEntry
          (slStringLiteral)
          (slStringLiteral))
        (objectEntry
          (slStringLiteral)
          (intLiteral))
        (objectElement
          (slStringLiteral))
        (objectElement
          (slStringLiteral)))))
  (classProperty
    (modifier)
    (identifier)
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody
        (objectEntry
          (intLiteral)
          (slStringLiteral))
        (objectEntry
          (intLiteral)
          (slStringLiteral)))))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)))
      (objectBody
        (objectProperty
          (modifier)
          (identifier)
          (slStringLiteral))
        (objectProperty
          (identifier)
          (variableExpr
            (identifier)))
        (objectProperty
          (identifier)
          (intLiteral)))))
  (classProperty
    (modifier)
    (identifier)
    (objectLiteral
      (parenthesizedExpr
        (variableExpr
          (identifier)))
      (objectBody
        (objectProperty
          (identifier)
          (intLiteral))
        (objectProperty
          (identifier)
          (trueLiteral)))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))
        (slStringLiteral))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))))))
