diff --git a/Gemfile b/Gemfile index 221286d..3889803 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,8 @@ group :development, :test do gem "minitest" gem "railties" # test/rails boots an application on it gem "rake" + gem "rspec-core" # test/testing_test.rb runs Gamba's matchers in RSpec + gem "rspec-expectations" gem "rubocop-performance", require: false gem "standard", require: false gem "vernier" diff --git a/README.md b/README.md index 8fab19e..953a5e0 100644 --- a/README.md +++ b/README.md @@ -192,15 +192,38 @@ To report a vulnerability, see [SECURITY.md](SECURITY.md). ## Checking your app's PDFs +Tests that check a PDF's bytes break on every harmless change. Gamba's own checks, those its oracle compares it with +Prawn by, come as assertions for Minitest and matchers for RSpec, loaded only on request. They need `mutool`, and +`pdftoppm` and `qpdf` for pages and validity; a missing tool fails with its install command, or skips the check +with `Gamba::Testing.missing_tools = :skip`. + +```ruby +require "gamba/minitest" # in test_helper.rb + +assert_pdf_text pdf, "Invoice INV-2026-0001", page: 1 # bytes or a path; a Regexp works too +assert_same_pages expected_pdf, pdf # text, positions and pixels in MuPDF and Poppler +assert_valid_pdf pdf # qpdf and Poppler +assert_pdf_a pdf # veraPDF +``` + +```ruby +require "gamba/rspec" # in spec_helper.rb + +expect(pdf).to have_pdf_text("Invoice INV-2026-0001", page: 1) +expect(pdf).to have_same_pages_as(expected_pdf) +expect(pdf).to be_a_valid_pdf +``` + Before switching, you can compare what your app produces under both libraries. `script/capture_pdfs.rb` saves -every PDF your test suite renders, named after the test. Run the suite once with Prawn and once with Gamba: +every PDF your test suite renders, named after the test. Run the suite once with Prawn and once with Gamba, then +compare the two directories with the same checks: ```sh GAMBA_CAPTURE_DIRECTORY=tmp/prawn RUBYOPT=-r/path/to/gamba/script/capture_pdfs.rb bin/rails test +GAMBA_CAPTURE_DIRECTORY=tmp/gamba RUBYOPT=-r/path/to/gamba/script/capture_pdfs.rb bin/rails test +ruby /path/to/gamba/script/capture_pdfs.rb tmp/prawn tmp/gamba ``` -Then compare the two directories with `Oracle.pdf_differences`, from Gamba's test support. - ## Performance `bundle exec rake bench` renders each document in `bench/documents` with Prawn 2.5 and with Gamba, in 7 fresh diff --git a/docs/guide.html b/docs/guide.html index c54a427..abee7b6 100644 --- a/docs/guide.html +++ b/docs/guide.html @@ -307,8 +307,16 @@
script/capture_pdfs.rb writes every PDF an app’s test suite renders, named after its test. Run the suite under Prawn, then under Gamba, and compare both directories with Oracle.pdf_differences:
GAMBA_CAPTURE_DIRECTORY=tmp/prawn RUBYOPT=-r/path/to/gamba/script/capture_pdfs.rb bin/rails test
+ The checks Gamba’s oracle compares it with Prawn by come as assertions for Minitest and matchers for RSpec, loaded only on request. A PDF is given as its bytes or a file’s path. A tool that is missing fails with its install command, or skips the check with Gamba::Testing.missing_tools = :skip; a check never passes unchecked.
require "gamba/minitest" # or "gamba/rspec": have_pdf_text, have_same_pages_as, be_a_valid_pdf, be_pdf_a
+
+assert_pdf_text pdf, "Invoice INV-2026-0001", page: 1, at: [36, 52] # at: a baseline, from the top left
+assert_same_pages expected_pdf, pdf
+assert_valid_pdf pdf
+assert_pdf_a pdf
+ A failure says what the page reads instead, or names the page and the glyph that moved, or the pixel rows that differ in MuPDF or Poppler. script/capture_pdfs.rb writes every PDF an app’s test suite renders, named after its test. Run the suite under Prawn, then under Gamba, and compare both directories with the same checks:
GAMBA_CAPTURE_DIRECTORY=tmp/prawn RUBYOPT=-r/path/to/gamba/script/capture_pdfs.rb bin/rails test
+ruby /path/to/gamba/script/capture_pdfs.rb tmp/prawn tmp/gamba