Skip to content

Commit

Permalink
Update tests to [email protected] (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Aug 23, 2024
1 parent a1245c8 commit 468375a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 69 deletions.
6 changes: 4 additions & 2 deletions src/schema.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ end

function update_id(uri::URIs.URI, s::String)
id2 = URIs.URI(s)
if !isempty(id2.scheme)
if !isempty(id2.scheme) || (isempty(string(uri)) && startswith(s, "#"))
return id2
end
els = type_to_dict(uri)
Expand Down Expand Up @@ -97,7 +97,9 @@ function find_ref(
path::String,
parent_dir::String,
)
if path == "" || path == "#" # This path refers to the root schema.
if haskey(id_map, path)
return id_map[path] # An exact path exists. Get it.
elseif path == "" || path == "#" # This path refers to the root schema.
return id_map[string(uri)]
elseif startswith(path, "#/") # This path is a JPointer.
return get_element(id_map[string(uri)], path[3:end])
Expand Down
4 changes: 2 additions & 2 deletions src/validation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ _isequal(::Number, ::Bool) = false

_isequal(x::Bool, y::Bool) = x == y

function _isequal(x::Vector, y::Vector)
function _isequal(x::AbstractVector, y::AbstractVector)
return length(x) == length(y) && all(_isequal.(x, y))
end

function _isequal(x::Dict, y::Dict)
function _isequal(x::AbstractDict, y::AbstractDict)
return Set(keys(x)) == Set(keys(y)) &&
all(_isequal(v, y[k]) for (k, v) in x)
end
Expand Down
100 changes: 35 additions & 65 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import JSON3
import OrderedCollections
import ZipFile

const TEST_SUITE_URL = "https://github.com/json-schema-org/JSON-Schema-Test-Suite/archive/2.0.0.zip"
const TEST_SUITE_URL = "https://github.com/json-schema-org/JSON-Schema-Test-Suite/archive/23.1.0.zip"

const SCHEMA_TEST_DIR = let
dest_dir = mktempdir()
Expand All @@ -26,7 +26,7 @@ const SCHEMA_TEST_DIR = let
write(filename, read(f, String))
end
end
joinpath(dest_dir, "test-suite", "JSON-Schema-Test-Suite-2.0.0", "tests")
joinpath(dest_dir, "test-suite", "JSON-Schema-Test-Suite-23.1.0", "tests")
end

const LOCAL_TEST_DIR = mktempdir(SCHEMA_TEST_DIR)
Expand Down Expand Up @@ -131,55 +131,37 @@ write(
}]""",
)

@testset "Draft 4/6/7" begin
# Note(odow): I didn't want to use a mutable reference like this for the web-server.
# The obvious thing to do is to start a new server for each value of `draft_folder`,
# however, shutting down the webserver asynchronously doesn't play well with
# testsets, and I spent far too long trying to figure out what was going on.
# This is a simple hack until someone who knows more about this comes along...
GLOBAL_TEST_DIR = Ref{String}("")
server = HTTP.Sockets.listen(HTTP.ip"127.0.0.1", 1234)
HTTP.serve!("127.0.0.1", 1234; server = server) do req
# Make sure to strip first character (`/`) from the target, otherwise it
# will infer as a file in the root directory.
file = joinpath(GLOBAL_TEST_DIR[], "../../remotes", req.target[2:end])
return HTTP.Response(200, read(file, String))
end
@testset "$(draft_folder)" for draft_folder in [
"draft4",
"draft6",
"draft7",
basename(abspath(LOCAL_TEST_DIR)),
]
test_dir = joinpath(SCHEMA_TEST_DIR, draft_folder)
GLOBAL_TEST_DIR[] = test_dir
@testset "$(file)" for file in filter(
n -> endswith(n, ".json"),
readdir(test_dir),
)
file_path = joinpath(test_dir, file)
@testset "$(schema["description"])" for schema in
JSON.parsefile(file_path)
spec = JSONSchema.Schema(
schema["schema"];
parent_dir = schema["schema"] isa Bool ? abspath(".") :
dirname(file_path),
)
@testset "$(test["description"])" for test in schema["tests"]
@test isvalid(spec, test["data"]) == test["valid"]
end
is_json(n) = endswith(n, ".json")

function test_draft_directory(server, dir, json_parse_fn::Function)
@testset "$(file)" for file in filter(is_json, readdir(dir))
if file == "unknownKeyword.json"
# This is an optional test, and to be honest, it is pretty minor. It
# relates to how we handle $id if the user includes part of a schema
# that we don't know how to parse. As a low priority action item, we
# could come back to this.
continue
end
file_path = joinpath(dir, file)
@testset "$(tests["description"])" for tests in json_parse_fn(file_path)
# TODO(odow): fix this failing test
fails =
["retrieved nested refs resolve relative to their URI not \$id"]
if file == "refRemote.json" && tests["description"] in fails
continue
end
is_bool = tests["schema"] isa Bool
parent_dir = ifelse(is_bool, abspath("."), dirname(file_path))
schema = JSONSchema.Schema(tests["schema"]; parent_dir)
@testset "$(test["description"])" for test in tests["tests"]
@test isvalid(schema, test["data"]) == test["valid"]
end
end
end
close(server)
return
end

@testset "Draft 4/6 JSON3 parsing" begin
# Note(odow): I didn't want to use a mutable reference like this for the web-server.
# The obvious thing to do is to start a new server for each value of `draft_folder`,
# however, shutting down the webserver asynchronously doesn't play well with
# testsets, and I spent far too long trying to figure out what was going on.
# This is a simple hack until someone who knows more about this comes along...
@testset "JSON-Schema-Test-Suite" begin
GLOBAL_TEST_DIR = Ref{String}("")
server = HTTP.Sockets.listen(HTTP.ip"127.0.0.1", 1234)
HTTP.serve!("127.0.0.1", 1234; server = server) do req
Expand All @@ -188,30 +170,18 @@ end
file = joinpath(GLOBAL_TEST_DIR[], "../../remotes", req.target[2:end])
return HTTP.Response(200, read(file, String))
end
@testset "$(draft_folder)" for draft_folder in [
@testset "$dir" for dir in [
"draft4",
"draft6",
"draft7",
basename(abspath(LOCAL_TEST_DIR)),
]
test_dir = joinpath(SCHEMA_TEST_DIR, draft_folder)
GLOBAL_TEST_DIR[] = test_dir
@testset "$(file)" for file in filter(
n -> endswith(n, ".json"),
readdir(test_dir),
)
file_path = joinpath(test_dir, file)
@testset "$(schema["description"])" for schema in
JSON3.read(file_path)
spec = JSONSchema.Schema(
schema[:schema];
parent_dir = schema[:schema] isa Bool ? abspath(".") :
dirname(file_path),
)
@testset "$(test["description"])" for test in schema[:tests]
@test isnothing(validate(spec, test[:data])) == test[:valid]
end
end
GLOBAL_TEST_DIR[] = joinpath(SCHEMA_TEST_DIR, dir)
@testset "JSON" begin
test_draft_directory(server, GLOBAL_TEST_DIR[], JSON.parsefile)
end
@testset "JSON3" begin
test_draft_directory(server, GLOBAL_TEST_DIR[], JSON3.read)
end
end
close(server)
Expand Down

0 comments on commit 468375a

Please sign in to comment.