aboutsummaryrefslogtreecommitdiff
path: root/src/test/scala/firrtl/JsonProtocolSpec.scala
blob: 3e07542bb3dd8889748f1e80684b812baa1a0b5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-License-Identifier: Apache-2.0

package firrtlTests

import org.json4s._

import firrtl.annotations.{
  Annotation,
  HasSerializationHints,
  InvalidAnnotationJSONException,
  JsonProtocol,
  NoTargetAnnotation
}
import org.scalatest.flatspec.AnyFlatSpec

object JsonProtocolTestClasses {
  trait Parent

  case class ChildA(foo: Int) extends Parent
  case class ChildB(bar: String) extends Parent
  case class PolymorphicParameterAnnotation(param: Parent) extends NoTargetAnnotation
  case class PolymorphicParameterAnnotationWithTypeHints(param: Parent)
      extends NoTargetAnnotation
      with HasSerializationHints {
    def typeHints = Seq(param.getClass)
  }

  case class TypeParameterizedAnnotation[T](param: T) extends NoTargetAnnotation
  case class TypeParameterizedAnnotationWithTypeHints[T](param: T)
      extends NoTargetAnnotation
      with HasSerializationHints {
    def typeHints = Seq(param.getClass)
  }

  case class SimpleAnnotation(alpha: String) extends NoTargetAnnotation
}

import JsonProtocolTestClasses._

class JsonProtocolSpec extends AnyFlatSpec {
  def serializeAndDeserialize(anno: Annotation): Annotation = {
    val serializedAnno = JsonProtocol.serialize(Seq(anno))
    JsonProtocol.deserialize(serializedAnno).head
  }

  "Annotations with polymorphic parameters" should "not serialize and deserialize without type hints" in {
    val anno = PolymorphicParameterAnnotation(ChildA(1))
    assertThrows[InvalidAnnotationJSONException] {
      serializeAndDeserialize(anno)
    }
  }

  it should "serialize and deserialize with type hints" in {
    val anno = PolymorphicParameterAnnotationWithTypeHints(ChildA(1))
    val deserAnno = serializeAndDeserialize(anno)
    assert(anno == deserAnno)

    val anno2 = PolymorphicParameterAnnotationWithTypeHints(ChildB("Test"))
    val deserAnno2 = serializeAndDeserialize(anno2)
    assert(anno2 == deserAnno2)
  }

  "Annotations with non-primitive type parameters" should "not serialize and deserialize without type hints" in {
    val anno = TypeParameterizedAnnotation(ChildA(1))
    val deserAnno = serializeAndDeserialize(anno)
    assert(anno != deserAnno)
  }
  it should "serialize and deserialize with type hints" in {
    val anno = TypeParameterizedAnnotationWithTypeHints(ChildA(1))
    val deserAnno = serializeAndDeserialize(anno)
    assert(anno == deserAnno)
  }

  "JSON object order" should "not affect deserialization" in {
    val anno = SimpleAnnotation("hello")
    val serializedAnno = """[{
      "alpha": "hello",
      "class": "firrtlTests.JsonProtocolTestClasses$SimpleAnnotation"
    }]"""
    val deserAnno = JsonProtocol.deserialize(serializedAnno).head
    assert(anno == deserAnno)
  }
}