Skip to content

Add json_expectations gem

Adam Cohen requested to merge add-json-expectations-gem into main

What does this MR do?

This MR adds the Rspec-json-expectations gem

The reason for adding this gem is to improve readability in expectation results. For example, to assert JSON equality, we currently use the eql comparison operator:

it "creates CycloneDX reports that match expectations" do
  actual_report = JSON.parse(File.read(actual_cyclonedx_report_path))
  expected_report = JSON.parse(File.read(expected_cyclonedx_report_path))

  expect(actual_report).to eql(expected_report)
end

If there's a mismatch in one of the elements, we receive the following rspec failure:

Failure/Error: expect(actual_report.to eql(expected_report)

  expected: {"bomFormat"=>"CycloneDX", "components"=>[{"bom-ref"=>"pkg:go/github.com/evanphx/json-patch@v4.2.0", ..."name"=>"gemnasium", "vendor"=>"GItLab", "version"=>"2.33.0"}]}, "specVersion"=>"1.3", "version"=>1}
       got: {"bomFormat"=>"CycloneDX", "components"=>[{"bom-ref"=>"pkg:go/github.com/evanphx/json-patch@v4.2.0", ..."name"=>"gemnasium", "vendor"=>"GitLab", "version"=>"2.33.0"}]}, "specVersion"=>"1.3", "version"=>1}

  (compared using eql?)

  Diff:
  @@ -1,6 +1,6 @@
   "bomFormat" => "CycloneDX",
   "components" => [{"bom-ref"=>"pkg:go/github.com/evanphx/json-patch@v4.2.0", "description"=>"description", "name"=>"github.com/evanphx/json-patch", "purl"=>"pkg:go/github.com/evanphx/json-patch@v4.2.0", "type"=>"library", "version"=>"v4.2.0"}],
  -"metadata" => {"authors"=>[{"email"=>"gitlab@gitlab.com", "name"=>"GitLab"}], "properties"=>[{"name"=>"lock_file", "value"=>"go-project/go.sum"}, {"name"=>"package_manager", "value"=>"go"}], "tools"=>[{"name"=>"gemnasium", "vendor"=>"GItLab", "version"=>"2.33.0"}]},
  +"metadata" => {"authors"=>[{"email"=>"gitlab@gitlab.com", "name"=>"GitLab"}], "properties"=>[{"name"=>"lock_file", "value"=>"go-project/go.sum"}, {"name"=>"package_manager", "value"=>"go"}], "tools"=>[{"name"=>"gemnasium", "vendor"=>"GitLab", "version"=>"2.33.0"}]},
   "specVersion" => "1.3",
   "version" => 1,

If instead we use the json-expectations gem and rewrite the assertion as follows:

it "creates CycloneDX reports that match expectations" do
  actual_report = JSON.parse(File.read(actual_cyclonedx_report_path))
  expected_report = JSON.parse(File.read(expected_cyclonedx_report_path))

  expect(actual_report).to include_json(expected_report)
end

Then we receive the following much easier to understand rspec failure:

Failure/Error: expect(clean_cyclonedx_report(parsed_actual)).to include_json(clean_cyclonedx_report(parsed_expected))

            json atom at path "metadata/tools/0/vendor" is not equal to expected value:

              expected: "GItLab"
                   got: "GitLab"

The above error message shows the exact path in the JSON that generated the error, as well as the element that caused the failure. This makes it much easier to debug and maintain tests.

What are the relevant issue numbers?

N/A

Edited by Adam Cohen

Merge request reports