Repository: square/kotlinpoet
Issue: Empty primary constructor not generated properly

Hello! 

I am using Kotlinpoet v1.8.0 and I am trying to generate an empty primary constructor for a class `TypeSpec`.

```kotlin
builderSpec.primaryConstructor(FunSpec.constructorBuilder().build())
```

The expected result here would be something like:

```kotlin
class Foo() { ... }
```

whereas the actual result is:

```kotlin
class Foo { ... }
```

This breaks the functionality when we are trying to add a second constructor that uses `callThisConstructor()` since there is no primary empty constructor to delegate to.


Changed files:
kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt
interop/kotlinx-metadata/specs-tests/src/test/kotlin/com/squareup/kotlinpoet/metadata/specs/test/KotlinPoetMetadataSpecsTest.kt
kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt
kotlinpoet/src/test/java/com/squareup/kotlinpoet/TypeSpecTest.kt
kotlinpoet/src/test/java/com/squareup/kotlinpoet/DelegatedConstructorCallTest.kt

diff --git a/interop/kotlinx-metadata/specs-tests/src/test/kotlin/com/squareup/kotlinpoet/metadata/specs/test/KotlinPoetMetadataSpecsTest.kt b/interop/kotlinx-metadata/specs-tests/src/test/kotlin/com/squareup/kotlinpoet/metadata/specs/test/KotlinPoetMetadataSpecsTest.kt
index 65102789..9d9f7e8e 100644
--- a/interop/kotlinx-metadata/specs-tests/src/test/kotlin/com/squareup/kotlinpoet/metadata/specs/test/KotlinPoetMetadataSpecsTest.kt
+++ b/interop/kotlinx-metadata/specs-tests/src/test/kotlin/com/squareup/kotlinpoet/metadata/specs/test/KotlinPoetMetadataSpecsTest.kt
@@ -73,7 +73,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class Supertype : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.BaseType(), com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.BaseInterface
+      public class Supertype() : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.BaseType(), com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.BaseInterface
       """.trimIndent()
     )
   }
@@ -93,7 +93,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class Properties {
+      public class Properties() {
         public var aList: kotlin.collections.List<kotlin.Int> = throw NotImplementedError("Stub!")
 
         public val bar: kotlin.String? = null
@@ -117,7 +117,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class Properties {
+      public class Properties() {
         public var aList: kotlin.collections.List<kotlin.Int> = throw NotImplementedError("Stub!")
 
         public val bar: kotlin.String? = null
@@ -143,7 +143,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class CompanionObject {
+      public class CompanionObject() {
         public companion object
       }
       """.trimIndent()
@@ -160,7 +160,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class NamedCompanionObject {
+      public class NamedCompanionObject() {
         public companion object Named
       }
       """.trimIndent()
@@ -251,7 +251,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class SuspendTypes {
+      public class SuspendTypes() {
         public val testProp: suspend (kotlin.Int, kotlin.Long) -> kotlin.String = throw NotImplementedError("Stub!")
 
         public suspend fun testComplexSuspendFun(body: suspend (kotlin.Int, suspend (kotlin.Long) -> kotlin.String) -> kotlin.String): kotlin.Unit {
@@ -286,7 +286,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class Parameters {
+      public class Parameters() {
         public inline fun hasDefault(param1: kotlin.String = throw NotImplementedError("Stub!")): kotlin.Unit {
         }
 
@@ -317,7 +317,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class LambdaReceiver {
+      public class LambdaReceiver() {
         public fun lambdaReceiver(block: kotlin.String.() -> kotlin.Unit): kotlin.Unit {
         }
 
@@ -347,7 +347,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class NestedTypeAliasTest {
+      public class NestedTypeAliasTest() {
         public val prop: com.squareup.kotlinpoet.metadata.specs.test.NestedTypeAlias = throw NotImplementedError("Stub!")
       }
       """.trimIndent()
@@ -395,7 +395,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class FunctionsReferencingTypeParameters<T> {
+      public class FunctionsReferencingTypeParameters<T>() {
         public fun test(`param`: T): kotlin.Unit {
         }
       }
@@ -415,7 +415,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public abstract class OverriddenThings : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.OverriddenThingsBase(), com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.OverriddenThingsInterface {
+      public abstract class OverriddenThings() : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.OverriddenThingsBase(), com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.OverriddenThingsInterface {
         public override var openProp: kotlin.String = throw NotImplementedError("Stub!")
 
         public override var openPropInterface: kotlin.String = throw NotImplementedError("Stub!")
@@ -460,7 +460,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class DelegatedProperties {
+      public class DelegatedProperties() {
         /**
          * Note: delegation is ABI stub only and not guaranteed to match source code.
          */
@@ -517,7 +517,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public enum class SimpleEnum {
+      public enum class SimpleEnum() {
         FOO,
         BAR,
         BAZ,
@@ -580,7 +580,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public enum class EnumWithAnnotation {
+      public enum class EnumWithAnnotation() {
         FOO,
         @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.FieldAnnotation
         BAR,
@@ -693,7 +693,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(implSpec.trimmedToString()).isEqualTo(
       """
-      public class TestSubInterfaceImpl : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.SubInterface {
+      public class TestSubInterfaceImpl() : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.SubInterface {
         public override fun noDefault(): kotlin.Unit {
         }
 
@@ -825,7 +825,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class GenericClass<T> {
+      public class GenericClass<T>() {
         public fun <T> functionAlsoWithT(`param`: T): kotlin.Unit {
         }
 
@@ -869,7 +869,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class ComplexCompanionObject {
+      public class ComplexCompanionObject() {
         public companion object ComplexObject : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.CompanionBase(), com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.CompanionInterface
       }
       """.trimIndent()
@@ -1185,7 +1185,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class JvmAnnotations {
+      public class JvmAnnotations() {
         @get:kotlin.jvm.Synchronized
         public val synchronizedGetProp: kotlin.String? = null
 
@@ -1246,10 +1246,10 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class NestedClasses {
-        public abstract class NestedClass<T> : kotlin.collections.List<T>
+      public class NestedClasses() {
+        public abstract class NestedClass<T>() : kotlin.collections.List<T>
 
-        public inner class NestedInnerClass
+        public inner class NestedInnerClass()
       }
       """.trimIndent()
     )
@@ -1799,10 +1799,10 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class ClassNesting {
-        public class NestedClass {
-          public class SuperNestedClass {
-            public inner class SuperDuperInnerClass
+      public class ClassNesting() {
+        public class NestedClass() {
+          public class SuperNestedClass() {
+            public inner class SuperDuperInnerClass()
           }
         }
       }
@@ -1822,10 +1822,10 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class `Fuzzy${'$'}ClassNesting` {
-        public class `-Nested` {
-          public class SuperNestedClass {
-            public inner class `-${'$'}Fuzzy${'$'}Super${'$'}Weird-Nested${'$'}Name`
+      public class `Fuzzy${'$'}ClassNesting`() {
+        public class `-Nested`() {
+          public class SuperNestedClass() {
+            public inner class `-${'$'}Fuzzy${'$'}Super${'$'}Weird-Nested${'$'}Name`()
           }
         }
       }
@@ -1903,7 +1903,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
       @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.RuntimeCustomClassAnnotation(name = "Runtime")
-      public class ClassAnnotations
+      public class ClassAnnotations()
       """.trimIndent()
     )
   }
@@ -1920,7 +1920,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
       """
       @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.BinaryCustomClassAnnotation(name = "Binary")
       @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.RuntimeCustomClassAnnotation(name = "Runtime")
-      public class ClassAnnotations
+      public class ClassAnnotations()
       """.trimIndent()
     )
   }
@@ -1945,7 +1945,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class TypeAnnotations {
+      public class TypeAnnotations() {
         public val foo: kotlin.collections.List<@com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.TypeAnnotation kotlin.String> = throw NotImplementedError("Stub!")
 
         public fun <T> bar(input: @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.TypeAnnotation kotlin.String, input2: @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.TypeAnnotation (@com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.TypeAnnotation kotlin.Int) -> @com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.TypeAnnotation kotlin.String): kotlin.Unit {
@@ -1978,13 +1978,13 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public class Asset<A : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset<A>> {
+      public class Asset<A : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset<A>>() {
         public fun <D : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset<D>, C : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset<A>> function(): kotlin.Unit {
         }
 
-        public class AssetIn<in C : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset.AssetIn<C>>
+        public class AssetIn<in C : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset.AssetIn<C>>()
 
-        public class AssetOut<out B : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset.AssetOut<B>>
+        public class AssetOut<out B : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.Asset.AssetOut<B>>()
       }
       """.trimIndent()
     )
@@ -2006,7 +2006,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public abstract class AbstractClass {
+      public abstract class AbstractClass() {
         public val baz: kotlin.String? = null
 
         public abstract val foo: kotlin.String
@@ -2044,7 +2044,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(typeSpec.trimmedToString()).isEqualTo(
       """
-      public abstract class InternalAbstractPropertyHolder {
+      public abstract class InternalAbstractPropertyHolder() {
         internal abstract val valProp: kotlin.String
 
         internal abstract var varProp: kotlin.String
@@ -2065,7 +2065,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(abstractModalities.trimmedToString()).isEqualTo(
       """
-      public abstract class AbstractModalities : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.ModalitiesInterface {
+      public abstract class AbstractModalities() : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.ModalitiesInterface {
         public val implicitFinalProp: kotlin.String? = null
 
         public override val interfaceProp: kotlin.String? = null
@@ -2089,7 +2089,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(finalAbstractModalities.trimmedToString()).isEqualTo(
       """
-      public abstract class FinalAbstractModalities : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.ModalitiesInterface {
+      public abstract class FinalAbstractModalities() : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.ModalitiesInterface {
         public final override val interfaceProp: kotlin.String? = null
 
         public final override fun interfaceFun(): kotlin.Unit {
@@ -2103,7 +2103,7 @@ class KotlinPoetMetadataSpecsTest : MultiClassInspectorTest() {
     //language=kotlin
     assertThat(modalities.trimmedToString()).isEqualTo(
       """
-      public class Modalities : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.AbstractModalities() {
+      public class Modalities() : com.squareup.kotlinpoet.metadata.specs.test.KotlinPoetMetadataSpecsTest.AbstractModalities() {
         public override val interfaceProp: kotlin.String? = null
 
         public override val openProp: kotlin.String? = null
diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt
index 9e8375ac..085e2774 100644
--- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt
+++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/ParameterSpec.kt
@@ -214,13 +214,10 @@ public class ParameterSpec private constructor(
 internal fun List<ParameterSpec>.emit(
   codeWriter: CodeWriter,
   forceNewLines: Boolean = false,
-  forceParensOnEmpty: Boolean = true,
   emitBlock: (ParameterSpec) -> Unit = { it.emit(codeWriter) }
 ) = with(codeWriter) {
-  val emitParens = isNotEmpty() || forceParensOnEmpty
-  if (emitParens) {
-    emit("(")
-  }
+  emit("(")
+
   if (size > 0) {
     val emitNewLines = size > 2 || forceNewLines
     if (emitNewLines) {
@@ -237,7 +234,5 @@ internal fun List<ParameterSpec>.emit(
       emit("\\n")
     }
   }
-  if (emitParens) {
-    emit(")")
-  }
+  emit(")")
 }
diff --git a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt
index 2a060f6a..42b5295a 100644
--- a/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt
+++ b/kotlinpoet/src/main/java/com/squareup/kotlinpoet/TypeSpec.kt
@@ -166,27 +166,24 @@ public class TypeSpec private constructor(
 
         primaryConstructor?.let {
           codeWriter.pushType(this) // avoid name collisions when emitting primary constructor
-          var useKeyword = false
-          var emittedAnnotations = false
+          val emittedAnnotations = it.annotations.isNotEmpty()
+          val useKeyword = it.annotations.isNotEmpty() || it.modifiers.isNotEmpty()
 
           if (it.annotations.isNotEmpty()) {
             codeWriter.emit(" ")
             codeWriter.emitAnnotations(it.annotations, true)
-            useKeyword = true
-            emittedAnnotations = true
           }
 
           if (it.modifiers.isNotEmpty()) {
             if (!emittedAnnotations) codeWriter.emit(" ")
             codeWriter.emitModifiers(it.modifiers)
-            useKeyword = true
           }
 
           if (useKeyword) {
             codeWriter.emit("constructor")
           }
 
-          it.parameters.emit(codeWriter, forceParensOnEmpty = useKeyword, forceNewLines = true) { param ->
+          it.parameters.emit(codeWriter, forceNewLines = true) { param ->
             val property = constructorProperties[param.name]
             if (property != null) {
               property.emit(
@@ -198,6 +195,7 @@ public class TypeSpec private constructor(
               param.emit(codeWriter, emitKdoc = true, inlineAnnotations = false)
             }
           }
+
           codeWriter.popType()
         }
 
diff --git a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/DelegatedConstructorCallTest.kt b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/DelegatedConstructorCallTest.kt
index 8dfcac41..c081f3f1 100644
--- a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/DelegatedConstructorCallTest.kt
+++ b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/DelegatedConstructorCallTest.kt
@@ -110,7 +110,7 @@ class DelegatedConstructorCallTest {
     builder.addFunction(secondaryConstructorBuilder.build())
     assertThat(builder.build().toString()).isEqualTo(
       """
-        |public class Test {
+        |public class Test() {
         |  public constructor(foo: kotlin.String) : this()
         |}
         |""".trimMargin()
diff --git a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/TypeSpecTest.kt b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/TypeSpecTest.kt
index ef0e7f41..75557424 100644
--- a/kotlinpoet/src/test/java/com/squareup/kotlinpoet/TypeSpecTest.kt
+++ b/kotlinpoet/src/test/java/com/squareup/kotlinpoet/TypeSpecTest.kt
@@ -956,8 +956,8 @@ class TypeSpecTest {
         |import kotlin.Comparable
         |import kotlin.Number
         |
-        |public class Location<P, Q> : Number(), Comparable where P : Number, P : Comparable, Q : Number, Q :
-        |    Comparable {
+        |public class Location<P, Q>() : Number(), Comparable where P : Number, P : Comparable, Q : Number, Q
+        |    : Comparable {
         |  public val x: P
         |
         |  public val y: @A Q
@@ -1362,7 +1362,7 @@ class TypeSpecTest {
         |
         |import java.lang.Deprecated
         |
-        |annotation class Bar {
+        |annotation class Bar() {
         |  fun value(): Deprecated default @Deprecated
         |}
         |""".trimMargin()
@@ -4138,8 +4138,8 @@ class TypeSpecTest {
         |import kotlin.Int
         |import kotlin.String
         |
-        |public class StringToInteger : Function<String, Int> by Function ({ text -> text.toIntOrNull() ?: 0
-        |    }), Runnable by Runnable ({ java.util.logging.Logger.debug("Hello world") })
+        |public class StringToInteger() : Function<String, Int> by Function ({ text -> text.toIntOrNull() ?:
+        |    0 }), Runnable by Runnable ({ java.util.logging.Logger.debug("Hello world") })
         |""".trimMargin()
 
     assertThat(toString(type)).isEqualTo(expect)
@@ -4974,6 +4974,23 @@ class TypeSpecTest {
     )
   }
 
+  @Test fun emptyConstructorGenerated() {
+    val taco = TypeSpec.classBuilder("Taco")
+      .primaryConstructor(FunSpec.constructorBuilder().build())
+      .build()
+    val file = FileSpec.builder("com.squareup.tacos", "Taco")
+      .addType(taco)
+      .build()
+    assertThat(file.toString()).isEqualTo(
+      """
+      package com.squareup.tacos
+
+      public class Taco()
+
+      """.trimIndent()
+    )
+  }
+
   companion object {
     private const val donutsPackage = "com.squareup.donuts"
   }