From 1f1031e03487181a1e20ad064d17856700bef689 Mon Sep 17 00:00:00 2001 From: Eirini Galati Date: Thu, 3 Sep 2026 11:08:37 +0200 Subject: [PATCH] feat: add Format constants for convert media types Adds a Format namespace of media-type string constants so the types accepted by convert() are discoverable via autocomplete, including JPEG XL (image/jxl), which the API already accepts. String constants rather than a language-level enum: the JSON body must carry the media type verbatim, and an enum would serialize as its name. Existing callers passing raw strings are unaffected. --- CHANGELOG.md | 4 +++ lib/tinify.rb | 1 + lib/tinify/format.rb | 36 ++++++++++++++++++++++++ test/tinify_format_test.rb | 56 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 lib/tinify/format.rb create mode 100644 test/tinify_format_test.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aef02f..a42ca96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Unreleased + +* Added `Tinify::Format` constants for the media types `convert` accepts, including JPEG XL (`image/jxl`). + ## 1.8.0 * Update development dependencies. diff --git a/lib/tinify.rb b/lib/tinify.rb index 9fbc4a4..f1e7b8f 100644 --- a/lib/tinify.rb +++ b/lib/tinify.rb @@ -1,5 +1,6 @@ require "tinify/version" require "tinify/error" +require "tinify/format" require "tinify/client" require "tinify/result_meta" diff --git a/lib/tinify/format.rb b/lib/tinify/format.rb new file mode 100644 index 0000000..047592a --- /dev/null +++ b/lib/tinify/format.rb @@ -0,0 +1,36 @@ +module Tinify + # Media types that images can be converted to. + # + # Use these constants with Source#convert: + # + # Tinify.from_file("input.png") + # .convert(type: Tinify::Format::JXL) + # .to_file("output.jxl") + # + # Multiple types may be supplied, in which case the API returns the smallest + # result: + # + # convert(type: [Tinify::Format::JXL, Tinify::Format::WEBP]) + module Format + # WebP. + WEBP = "image/webp".freeze + + # PNG. + PNG = "image/png".freeze + + # JPEG. + JPEG = "image/jpeg".freeze + + # JPEG, an alias of JPEG. + JPG = "image/jpg".freeze + + # AVIF. + AVIF = "image/avif".freeze + + # JPEG XL. + JXL = "image/jxl".freeze + + # Wildcard, returns the smallest of the supported types. + ANY = "*/*".freeze + end +end diff --git a/test/tinify_format_test.rb b/test/tinify_format_test.rb new file mode 100644 index 0000000..94420bf --- /dev/null +++ b/test/tinify_format_test.rb @@ -0,0 +1,56 @@ +require File.expand_path("../helper", __FILE__) + +describe Tinify::Format do + describe "constants" do + it "should expose the supported media types" do + assert_equal "image/webp", Tinify::Format::WEBP + assert_equal "image/png", Tinify::Format::PNG + assert_equal "image/jpeg", Tinify::Format::JPEG + assert_equal "image/jpg", Tinify::Format::JPG + assert_equal "image/avif", Tinify::Format::AVIF + assert_equal "image/jxl", Tinify::Format::JXL + assert_equal "*/*", Tinify::Format::ANY + end + end + + describe "convert" do + before do + Tinify.key = "valid" + + stub_request(:post, "https://api.tinify.com/shrink") + .with(basic_auth: ['api', 'valid']) + .to_return( + status: 201, + headers: { Location: "https://api.tinify.com/some/location" }, + body: '{}') + end + + it "should serialize a single format" do + stub_request(:post, "https://api.tinify.com/some/location") + .with( + basic_auth: ['api', 'valid'], + body: '{"convert":{"type":"image/jxl"}}') + .to_return( + status: 200, + body: "converted file") + + source = Tinify::Source.from_buffer("png file") + .convert(type: Tinify::Format::JXL) + assert_equal "converted file", source.to_buffer + end + + it "should serialize multiple formats" do + stub_request(:post, "https://api.tinify.com/some/location") + .with( + basic_auth: ['api', 'valid'], + body: '{"convert":{"type":["image/jxl","image/webp"]}}') + .to_return( + status: 200, + body: "converted file") + + source = Tinify::Source.from_buffer("png file") + .convert(type: [Tinify::Format::JXL, Tinify::Format::WEBP]) + assert_equal "converted file", source.to_buffer + end + end +end