1
0

registry_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. package imagetype
  2. import (
  3. "io"
  4. "strings"
  5. "testing"
  6. "github.com/imgproxy/imgproxy/v3/bufreader"
  7. "github.com/stretchr/testify/require"
  8. )
  9. func TestRegisterType(t *testing.T) {
  10. // Create a separate registry for testing to avoid conflicts with global registry
  11. testRegistry := NewRegistry()
  12. // Register a custom type
  13. customDesc := &TypeDesc{
  14. String: "custom",
  15. Ext: ".custom",
  16. Mime: "image/custom",
  17. IsVector: false,
  18. SupportsAlpha: true,
  19. SupportsColourProfile: true,
  20. }
  21. customType := testRegistry.RegisterType(customDesc)
  22. // Verify the type is now registered
  23. result := testRegistry.GetTypeDesc(customType)
  24. require.NotNil(t, result)
  25. require.Equal(t, customDesc.String, result.String)
  26. require.Equal(t, customDesc.Ext, result.Ext)
  27. require.Equal(t, customDesc.Mime, result.Mime)
  28. require.Equal(t, customDesc.IsVector, result.IsVector)
  29. require.Equal(t, customDesc.SupportsAlpha, result.SupportsAlpha)
  30. require.Equal(t, customDesc.SupportsColourProfile, result.SupportsColourProfile)
  31. }
  32. func TestTypeProperties(t *testing.T) {
  33. // Test that Type methods use TypeDesc fields correctly
  34. tests := []struct {
  35. name string
  36. typ Type
  37. expectVector bool
  38. expectAlpha bool
  39. expectColourProfile bool
  40. expectQuality bool
  41. expectAnimationLoad bool
  42. expectAnimationSave bool
  43. expectThumbnail bool
  44. }{
  45. {
  46. name: "JPEG",
  47. typ: JPEG,
  48. expectVector: false,
  49. expectAlpha: false,
  50. expectColourProfile: true,
  51. expectQuality: true,
  52. expectAnimationLoad: false,
  53. expectAnimationSave: false,
  54. expectThumbnail: false,
  55. },
  56. {
  57. name: "PNG",
  58. typ: PNG,
  59. expectVector: false,
  60. expectAlpha: true,
  61. expectColourProfile: true,
  62. expectQuality: false,
  63. expectAnimationLoad: false,
  64. expectAnimationSave: false,
  65. expectThumbnail: false,
  66. },
  67. {
  68. name: "WEBP",
  69. typ: WEBP,
  70. expectVector: false,
  71. expectAlpha: true,
  72. expectColourProfile: true,
  73. expectQuality: true,
  74. expectAnimationLoad: true,
  75. expectAnimationSave: true,
  76. expectThumbnail: false,
  77. },
  78. {
  79. name: "SVG",
  80. typ: SVG,
  81. expectVector: true,
  82. expectAlpha: true,
  83. expectColourProfile: false,
  84. expectQuality: false,
  85. expectAnimationLoad: false,
  86. expectAnimationSave: false,
  87. expectThumbnail: false,
  88. },
  89. {
  90. name: "GIF",
  91. typ: GIF,
  92. expectVector: false,
  93. expectAlpha: true,
  94. expectColourProfile: false,
  95. expectQuality: false,
  96. expectAnimationLoad: true,
  97. expectAnimationSave: true,
  98. expectThumbnail: false,
  99. },
  100. {
  101. name: "HEIC",
  102. typ: HEIC,
  103. expectVector: false,
  104. expectAlpha: true,
  105. expectColourProfile: true,
  106. expectQuality: true,
  107. expectAnimationLoad: false,
  108. expectAnimationSave: false,
  109. expectThumbnail: true,
  110. },
  111. {
  112. name: "AVIF",
  113. typ: AVIF,
  114. expectVector: false,
  115. expectAlpha: true,
  116. expectColourProfile: true,
  117. expectQuality: true,
  118. expectAnimationLoad: false,
  119. expectAnimationSave: false,
  120. expectThumbnail: true,
  121. },
  122. }
  123. for _, tt := range tests {
  124. t.Run(tt.name, func(t *testing.T) {
  125. require.Equal(t, tt.expectVector, tt.typ.IsVector())
  126. require.Equal(t, tt.expectAlpha, tt.typ.SupportsAlpha())
  127. require.Equal(t, tt.expectColourProfile, tt.typ.SupportsColourProfile())
  128. require.Equal(t, tt.expectQuality, tt.typ.SupportsQuality())
  129. require.Equal(t, tt.expectAnimationLoad, tt.typ.SupportsAnimationLoad())
  130. require.Equal(t, tt.expectAnimationSave, tt.typ.SupportsAnimationSave())
  131. require.Equal(t, tt.expectThumbnail, tt.typ.SupportsThumbnail())
  132. })
  133. }
  134. }
  135. func TestRegisterDetector(t *testing.T) {
  136. // Create a test registry to avoid interfering with global state
  137. testRegistry := NewRegistry()
  138. // Create a test detector function
  139. testDetector := func(r bufreader.ReadPeeker) (Type, error) {
  140. b, err := r.Peek(2)
  141. if err != nil {
  142. return Unknown, err
  143. }
  144. if len(b) >= 2 && b[0] == 0xFF && b[1] == 0xD8 {
  145. return JPEG, nil
  146. }
  147. return Unknown, newUnknownFormatError()
  148. }
  149. // Register the detector using the method
  150. testRegistry.RegisterDetector(testDetector)
  151. // Verify the detector is registered
  152. require.Len(t, testRegistry.detectors, 1)
  153. require.NotNil(t, testRegistry.detectors[0])
  154. }
  155. func TestRegisterMagicBytes(t *testing.T) {
  156. // Create a test registry to avoid interfering with global state
  157. testRegistry := NewRegistry()
  158. require.Empty(t, testRegistry.detectors)
  159. // Register magic bytes for JPEG using the method
  160. jpegMagic := []byte{0xFF, 0xD8}
  161. testRegistry.RegisterMagicBytes(JPEG, jpegMagic)
  162. // Verify the magic bytes are registered
  163. require.Len(t, testRegistry.detectors, 1)
  164. }
  165. func TestDetectionErrorReturns(t *testing.T) {
  166. // Create a test registry to avoid interfering with global state
  167. testRegistry := NewRegistry()
  168. detErr := error(nil)
  169. // The first detector will fail with detErr
  170. testRegistry.RegisterDetector(func(r bufreader.ReadPeeker) (Type, error) {
  171. return Unknown, detErr
  172. })
  173. // The second detector will succeed
  174. testRegistry.RegisterDetector(func(r bufreader.ReadPeeker) (Type, error) {
  175. return JPEG, nil
  176. })
  177. // We don't actually need to read anything, just create a reader
  178. r := strings.NewReader("")
  179. // Should not fail with io.EOF
  180. detErr = io.EOF
  181. typ, err := testRegistry.Detect(r)
  182. require.Equal(t, JPEG, typ)
  183. require.NoError(t, err)
  184. // Should not fail with io.ErrUnexpectedEOF
  185. detErr = io.ErrUnexpectedEOF
  186. typ, err = testRegistry.Detect(r)
  187. require.Equal(t, JPEG, typ)
  188. require.NoError(t, err)
  189. // Should fail with other read errors
  190. detErr = io.ErrClosedPipe
  191. typ, err = testRegistry.Detect(r)
  192. require.Equal(t, Unknown, typ)
  193. require.Error(t, err)
  194. require.ErrorAs(t, err, &TypeDetectionError{})
  195. require.ErrorIs(t, err, io.ErrClosedPipe)
  196. }