tests/testthat/test-read.R

test_that("can't read empty input", {
  ct <- jsonvalidate_js()
  expect_error(read_schema(NULL, ct),
               "zero length input")
  expect_error(read_schema(character(0), ct),
               "zero length input")
})


test_that("must read character input", {
  ct <- jsonvalidate_js()
  expect_error(read_schema(1, ct),
               "Expected a character vector")
})


test_that("sensible error on missing files", {
  ct <- jsonvalidate_js()
  a <- c(
    '{',
    '"$ref": "b.json"',
    '}')
  b <- c(
    '{',
    '"$ref": "c.json"',
    '}')
  c <- c(
    '{',
    '    "type": "string"',
    '}')
  path <- tempfile()
  dir.create(path)
  writeLines(a, file.path(path, "a.json"))
  writeLines(b, file.path(path, "b.json"))
  expect_error(
    read_schema(file.path(path, "b.json"), ct),
    "While reading 'b.json' > 'c.json'\nDid not find schema file 'c.json'",
    class = "jsonvalidate_read_error")
  expect_error(
    read_schema(file.path(path, "a.json"), ct),
    paste0("While reading 'a.json' > 'b.json' > 'c.json'\n",
           "Did not find schema file 'c.json'"),
    class = "jsonvalidate_read_error")
})


test_that("Read recursive schema", {
  ct <- jsonvalidate_js()
  sexpression <- c(
    '{',
    '  "oneOf": [',
    '  {"type": "string"},',
    '  {"type": "number"},',
    '  {"type": "array", "items": {"$ref": "sexpression.json"}}',
    ']}')

  path <- tempfile()
  dir.create(path)
  p <- file.path(path, "sexpression.json")
  writeLines(sexpression, p)
  dat <- read_schema(p, ct)
  expect_equal(length(dat$dependencies), 1)
  expect_equal(jsonlite::fromJSON(dat$dependencies)$id, "sexpression.json")

  v <- json_validator(p, engine = "ajv")
  expect_false(v("{}"))
  expect_true(v('["a"]'))
  expect_true(v('["a", ["b", "c", 3]]'))
})


test_that("can't read external schemas", {
  ct <- jsonvalidate_js()
  a <- c(
    '{',
    '"$ref": "https://example.com/schema.json"',
    '}')
  expect_error(read_schema(a, ct),
               "Don't yet support protocol-based sub schemas")
})


test_that("Conflicting schema versions", {
  ct <- jsonvalidate_js()
  a <- c(
    '{',
    '  "$schema": "http://json-schema.org/draft-07/schema#",',
    '  "$ref": "b.json"',
    '}')
  b <- c(
    '{',
    '  "$schema": "http://json-schema.org/draft-04/schema#",',
    '  "type": "string"',
    '}')
  path <- tempfile()
  dir.create(path)
  writeLines(a, file.path(path, "a.json"))
  writeLines(b, file.path(path, "b.json"))
  expect_error(
    read_schema(file.path(path, "a.json"), ct),
    "Conflicting subschema versions used:\n  - draft-04: b.json")
  expect_error(
    with_dir(path, read_schema(a, ct)),
    "Conflicting subschema versions used:\n.+- draft-07: \\(input string\\)")
  writeLines(sub("-04", "-07", b), file.path(path, "b.json"))
  x <- read_schema(file.path(path, "a.json"), ct)
  expect_equal(x$meta_schema_version, "draft-07")
})


test_that("Sensible reporting on syntax error", {
  ct <- jsonvalidate_js()
  parent <- c(
    '{',
    '    "type": "object",',
    '    "properties": {',
    '        "hello": {',
    '            "$ref": "child.json"',
    '        }',
    '    },',
    '    "required": ["hello"],',
    '    "additionalProperties": false',
    '}')
  child <- c(
    '{',
    '    "id": "child"',
    '    "type": "string"',
    '}')
  path <- tempfile()
  dir.create(path)
  writeLines(parent, file.path(path, "parent.json"))
  writeLines(child, file.path(path, "child.json"))
  expect_error(
    read_schema(file.path(path, "parent.json"), ct),
    "While reading 'parent.json' > 'child.json'",
    class = "jsonvalidate_read_error")
})


test_that("schema string vs filename detection", {
  expect_false(read_schema_is_filename("''"))
  expect_false(read_schema_is_filename('""'))
  expect_false(read_schema_is_filename('{}'))
  expect_true(read_schema_is_filename('/foo/bar.json'))
  expect_true(read_schema_is_filename('bar.json'))
  expect_true(read_schema_is_filename('bar'))

  expect_false(read_schema_is_filename(character()))
  expect_false(read_schema_is_filename(c("a", "b")))
  expect_false(read_schema_is_filename(I('/foo/bar.json')))
})


test_that("sensible error if reading missing schema", {
  expect_error(
    read_schema("/file/that/does/not/exist.json"),
    "Schema '/file/that/does/not/exist.json' looks like a filename but")
})

test_that("can reference subsets of other schema", {
  ct <- jsonvalidate_js()
  a <- c(
    '{',
    '"$ref": "b.json#/definitions/b"',
    '}')
  b <- c(
    '{',
    '    "definitions": {',
    '        "b": {',
    '            "type": "string"',
    '        }',
    '    }',
    '}')
  path <- tempfile()
  dir.create(path)
  writeLines(a, file.path(path, "a.json"))
  writeLines(b, file.path(path, "b.json"))
  schema <- read_schema(file.path(path, "a.json"), ct)
  expect_equal(length(schema$dependencies), 1)
  expect_equal(jsonlite::fromJSON(schema$dependencies)$id, "b.json")
})
ropensci/jsonvalidate documentation built on March 29, 2024, 7:42 a.m.