andyglow / scala-jsonschema

Scala JSON Schema
Other
123 stars 38 forks source link

README examples either don't compile or produce vastly different results #135

Open phdoerfler opened 3 years ago

phdoerfler commented 3 years ago

Describe the bug None of the examples in the README that I tried to actually work as documented. Most don't even compile and the ones that do produce a different output.

To Reproduce build.sbt:

scalaVersion := "2.13.4"

lazy val jsonSchemaVersion = "0.7.1"

libraryDependencies ++= Seq(
  "com.github.andyglow" %% "scala-jsonschema" % jsonSchemaVersion
)

libraryDependencies ++= Seq(
  "com.github.andyglow" %% "scala-jsonschema-core" % jsonSchemaVersion,              // <-- transitive
  "com.github.andyglow" %% "scala-jsonschema-macros" % jsonSchemaVersion % Provided, // <-- transitive
  // json bridge. pick one
  "com.github.andyglow" %% "scala-jsonschema-circe-json" % jsonSchemaVersion,        // <-- optional
  // joda-time support
  "com.github.andyglow" %% "scala-jsonschema-joda-time" % jsonSchemaVersion,         // <-- optional
  // cats support
  "com.github.andyglow" %% "scala-jsonschema-cats" % jsonSchemaVersion,              // <-- optional
  // refined support
  "com.github.andyglow" %% "scala-jsonschema-refined" % jsonSchemaVersion,           // <-- optional
  // enumeratum support
  "com.github.andyglow" %% "scala-jsonschema-enumeratum" % jsonSchemaVersion,        // <-- optional
  // zero-dependency json and jsonschema parser
  "com.github.andyglow" %% "scala-jsonschema-parser" % jsonSchemaVersion             // <-- optional
)

turbo := true
useSuperShell := false
scalacOptions ++= Seq(
  "-deprecation",
  "-encoding", "UTF-8",
  "-feature",
  "-unchecked"
)

Expected behavior The examples in the README should be correct

Actual results Examples don't compile or produce different output.

For instance, the first, inlined example actually produces:

personSchema: Schema[Person] = object(
  fields = HashSet(
    Field(
      name = "middleName",
      tpe = string(format = None),
      required = false,
      default = None,
      description = None,
      rwMode = ReadWrite
    ),
    Field(
      name = "cars",
      tpe = array(
        componentType = object(
          fields = Set(
            Field(
              name = "name",
              tpe = string(format = None),
              required = true,
              default = None,
              description = None,
              rwMode = ReadWrite
            ),
            Field(
              name = "manufacturer",
              tpe = object(
                fields = Set(
                  Field(
                    name = "name",
                    tpe = string(format = None),
                    required = true,
                    default = None,
                    description = None,
                    rwMode = ReadWrite
                  )
                )
              ),
              required = true,
              default = None,
              description = None,
              rwMode = ReadWrite
            )
          )
        ),
        unique = false
      ),
      required = true,
      default = None,
      description = None,
...
private val personSchema: Schema[Person]

whereas the README says it produces:

As result you will receive this:

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "middleName": {
      "type": "string"
    },
    "cars": {
      "type": "array",
...

Ditto for the regular example.

Moving on to the Definitions/References example the code doesn't even compile:

main.scala:30:62: schema for String is not supported,
implicit val someStrSchema: json.Schema[String] = Json.schema[String]
                                                             ^
main.scala:34:44: not enough arguments for method schema: (x: json.Schema[_], v: V)(implicit asValue: com.github.andyglow.jsonschema.AsValueBuilder[V]): com.github.andyglow.json.Value.obj.
Unspecified value parameter v.
println(JsonFormatter.format(AsValue.schema(someArrSchema)))
                                           ^
two errors found
(Compile / compileIncremental) Compilation failed
Total time: 1 s, completed 29.01.2021, 12:28:47

I also looked at the tests for help but to no avail.

This makes it very hard for someone to get started with this library which is unfortunate because there does not seem to be any alternative other than the ancient autoschema from Coursera.

phdoerfler commented 3 years ago

I found one way to actually get a schema out based on the circe example:

import com.github.andyglow.jsonschema.AsCirce._
import json.schema.Version._
import io.circe._

case class Foo(name: String)

val fooSchema: Json = json.Json.schema[Foo].asCirce(Draft04())
fooSchema.spaces2SortKeys

but even this required modifications because the original example does not compile:

main.scala:34:28: value schema is not a member of object io.circe.Json
val fooSchema: Json = Json.schema[Foo].asCirce(Draft04())
                           ^
one error found
(Compile / compileIncremental) Compilation failed
Total time: 1 s, completed 29.01.2021, 12:43:05  
phdoerfler commented 3 years ago

If I may suggest: Consider using mdoc to create typechecked markdown. It will ensure that the examples in the README do actually compile and run when used in, e.g., your CI build.

You might also want to consider improving the expressiveness of your tests as they, too, can serve as source of up-to-date documentation. E.g., the specs2 User Guide is completely generated from the tests themselves.

This being said, I'm glad this library exists, thanks for pouring in the work! 👍

andyglow commented 3 years ago

Hi, Philipp! Thanks for checking this. Yeah, read me is somewhat outdated, true.

As for mdoc - it's really a great idea. I have already started working on new documentation using mdoc. Hope it will be ready soon.

Sorry for the inconvenience with readme. That might be really annoying.

phdoerfler commented 3 years ago

Awesome, I'm looking forward to the new and improved docs :)