diff --git a/lib/json_skooma/keywords/validation/required.rb b/lib/json_skooma/keywords/validation/required.rb index 65043cf..d708afa 100644 --- a/lib/json_skooma/keywords/validation/required.rb +++ b/lib/json_skooma/keywords/validation/required.rb @@ -8,9 +8,20 @@ class Required < Base self.instance_types = "object" def evaluate(instance, result) - return if json.value.all? { |val| instance.key?(val) } + missing = required_keys.reject { |key| instance.key?(key) } + return if missing.none? - result.failure("The object is missing required properties #{json.value.join(", ")}") + result.failure(missing_keys_message(missing)) + end + + private + + def required_keys + json.value + end + + def missing_keys_message(missing) + "The object requires the following keys: #{required_keys.join(", ")}. Missing keys: #{missing.join(", ")}" end end end diff --git a/spec/json_skooma/json_schema_spec.rb b/spec/json_skooma/json_schema_spec.rb index 888b4a0..bf7f67f 100644 --- a/spec/json_skooma/json_schema_spec.rb +++ b/spec/json_skooma/json_schema_spec.rb @@ -37,6 +37,29 @@ it { is_expected.to be_valid } + context "with required keys" do + before do + schema_data["required"] = %w[foo bar] + schema_data["properties"]["bar"] = {"type" => "integer"} + end + + it { is_expected.not_to be_valid } + + it "informs us which key is missing" do + errors = subject.output(:detailed)["errors"].map { |e| e["error"] } + + expect(errors).to contain_exactly( + "The object requires the following keys: foo, bar. Missing keys: bar" + ) + end + + context "with valid instance" do + let(:instance) { {foo: "baz", bar: 123} } + + it { is_expected.to be_valid } + end + end + context "with ref option" do let(:ref) { "#/$defs/FooBaz" }