123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- package imagetype
- import (
- "bytes"
- "io"
- "reflect"
- "runtime"
- "strings"
- "testing"
- "github.com/imgproxy/imgproxy/v3/bufreader"
- "github.com/stretchr/testify/require"
- )
- func TestRegisterType(t *testing.T) {
- // Create a separate registry for testing to avoid conflicts with global registry
- testRegistry := NewRegistry()
- // Register a custom type
- customDesc := &TypeDesc{
- String: "custom",
- Ext: ".custom",
- Mime: "image/custom",
- IsVector: false,
- SupportsAlpha: true,
- SupportsColourProfile: true,
- }
- customType := testRegistry.RegisterType(customDesc)
- // Verify the type is now registered
- result := testRegistry.GetTypeDesc(customType)
- require.NotNil(t, result)
- require.Equal(t, customDesc.String, result.String)
- require.Equal(t, customDesc.Ext, result.Ext)
- require.Equal(t, customDesc.Mime, result.Mime)
- require.Equal(t, customDesc.IsVector, result.IsVector)
- require.Equal(t, customDesc.SupportsAlpha, result.SupportsAlpha)
- require.Equal(t, customDesc.SupportsColourProfile, result.SupportsColourProfile)
- }
- func TestTypeProperties(t *testing.T) {
- // Test that Type methods use TypeDesc fields correctly
- tests := []struct {
- name string
- typ Type
- expectVector bool
- expectAlpha bool
- expectColourProfile bool
- expectQuality bool
- expectAnimationLoad bool
- expectAnimationSave bool
- expectThumbnail bool
- }{
- {
- name: "JPEG",
- typ: JPEG,
- expectVector: false,
- expectAlpha: false,
- expectColourProfile: true,
- expectQuality: true,
- expectAnimationLoad: false,
- expectAnimationSave: false,
- expectThumbnail: false,
- },
- {
- name: "PNG",
- typ: PNG,
- expectVector: false,
- expectAlpha: true,
- expectColourProfile: true,
- expectQuality: false,
- expectAnimationLoad: false,
- expectAnimationSave: false,
- expectThumbnail: false,
- },
- {
- name: "WEBP",
- typ: WEBP,
- expectVector: false,
- expectAlpha: true,
- expectColourProfile: true,
- expectQuality: true,
- expectAnimationLoad: true,
- expectAnimationSave: true,
- expectThumbnail: false,
- },
- {
- name: "SVG",
- typ: SVG,
- expectVector: true,
- expectAlpha: true,
- expectColourProfile: false,
- expectQuality: false,
- expectAnimationLoad: false,
- expectAnimationSave: false,
- expectThumbnail: false,
- },
- {
- name: "GIF",
- typ: GIF,
- expectVector: false,
- expectAlpha: true,
- expectColourProfile: false,
- expectQuality: false,
- expectAnimationLoad: true,
- expectAnimationSave: true,
- expectThumbnail: false,
- },
- {
- name: "HEIC",
- typ: HEIC,
- expectVector: false,
- expectAlpha: true,
- expectColourProfile: true,
- expectQuality: true,
- expectAnimationLoad: false,
- expectAnimationSave: false,
- expectThumbnail: true,
- },
- {
- name: "AVIF",
- typ: AVIF,
- expectVector: false,
- expectAlpha: true,
- expectColourProfile: true,
- expectQuality: true,
- expectAnimationLoad: false,
- expectAnimationSave: false,
- expectThumbnail: true,
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- require.Equal(t, tt.expectVector, tt.typ.IsVector())
- require.Equal(t, tt.expectAlpha, tt.typ.SupportsAlpha())
- require.Equal(t, tt.expectColourProfile, tt.typ.SupportsColourProfile())
- require.Equal(t, tt.expectQuality, tt.typ.SupportsQuality())
- require.Equal(t, tt.expectAnimationLoad, tt.typ.SupportsAnimationLoad())
- require.Equal(t, tt.expectAnimationSave, tt.typ.SupportsAnimationSave())
- require.Equal(t, tt.expectThumbnail, tt.typ.SupportsThumbnail())
- })
- }
- }
- func TestRegisterDetector(t *testing.T) {
- // Create a test registry to avoid interfering with global state
- testRegistry := NewRegistry()
- functionsEqual := func(fn1, fn2 DetectFunc) {
- // Compare function names to check if they are the same
- fnName1 := runtime.FuncForPC(reflect.ValueOf(fn1).Pointer()).Name()
- fnName2 := runtime.FuncForPC(reflect.ValueOf(fn2).Pointer()).Name()
- require.Equal(t, fnName1, fnName2)
- }
- // Create a test detector functions
- testDetector1 := func(r bufreader.ReadPeeker) (Type, error) { return JPEG, nil }
- testDetector2 := func(r bufreader.ReadPeeker) (Type, error) { return PNG, nil }
- testDetector3 := func(r bufreader.ReadPeeker) (Type, error) { return GIF, nil }
- testDetector4 := func(r bufreader.ReadPeeker) (Type, error) { return SVG, nil }
- // Register the detectors using the method
- testRegistry.RegisterDetector(0, testDetector1)
- testRegistry.RegisterDetector(0, testDetector2)
- testRegistry.RegisterDetector(10, testDetector3)
- testRegistry.RegisterDetector(5, testDetector4)
- // Verify the detectors are registered
- require.Len(t, testRegistry.detectors, 4)
- // Verify the order of detectors based on priority
- require.Equal(t, 0, testRegistry.detectors[0].priority)
- functionsEqual(testDetector1, testRegistry.detectors[0].fn)
- require.Equal(t, 0, testRegistry.detectors[1].priority)
- functionsEqual(testDetector2, testRegistry.detectors[1].fn)
- require.Equal(t, 5, testRegistry.detectors[2].priority)
- functionsEqual(testDetector4, testRegistry.detectors[2].fn)
- require.Equal(t, 10, testRegistry.detectors[3].priority)
- functionsEqual(testDetector3, testRegistry.detectors[3].fn)
- }
- func TestRegisterMagicBytes(t *testing.T) {
- // Create a test registry to avoid interfering with global state
- testRegistry := NewRegistry()
- require.Empty(t, testRegistry.detectors)
- // Register magic bytes for JPEG using the method
- jpegMagic := []byte{0xFF, 0xD8}
- testRegistry.RegisterMagicBytes(JPEG, jpegMagic)
- // Verify the magic bytes are registered
- require.Len(t, testRegistry.detectors, 1)
- require.Equal(t, -1, testRegistry.detectors[0].priority)
- typ, err := testRegistry.Detect(bufreader.New(bytes.NewReader(jpegMagic)))
- require.NoError(t, err)
- require.Equal(t, JPEG, typ)
- }
- func TestDetectionErrorReturns(t *testing.T) {
- // Create a test registry to avoid interfering with global state
- testRegistry := NewRegistry()
- detErr := error(nil)
- // The first detector will fail with detErr
- testRegistry.RegisterDetector(0, func(r bufreader.ReadPeeker) (Type, error) {
- return Unknown, detErr
- })
- // The second detector will succeed
- testRegistry.RegisterDetector(1, func(r bufreader.ReadPeeker) (Type, error) {
- return JPEG, nil
- })
- // We don't actually need to read anything, just create a reader
- r := strings.NewReader("")
- // Should not fail with io.EOF
- detErr = io.EOF
- typ, err := testRegistry.Detect(r)
- require.Equal(t, JPEG, typ)
- require.NoError(t, err)
- // Should not fail with io.ErrUnexpectedEOF
- detErr = io.ErrUnexpectedEOF
- typ, err = testRegistry.Detect(r)
- require.Equal(t, JPEG, typ)
- require.NoError(t, err)
- // Should fail with other read errors
- detErr = io.ErrClosedPipe
- typ, err = testRegistry.Detect(r)
- require.Equal(t, Unknown, typ)
- require.Error(t, err)
- require.ErrorAs(t, err, &TypeDetectionError{})
- require.ErrorIs(t, err, io.ErrClosedPipe)
- }
|