package exifcommon import ( "math" "testing" "github.com/dsoprea/go-logging" ) func TestTypeByte_String(t *testing.T) { if TypeByte.String() != "BYTE" { t.Fatalf("Type name not correct (byte): [%s]", TypeByte.String()) } } func TestTypeAscii_String(t *testing.T) { if TypeAscii.String() != "ASCII" { t.Fatalf("Type name not correct (ASCII): [%s]", TypeAscii.String()) } } func TestTypeAsciiNoNul_String(t *testing.T) { if TypeAsciiNoNul.String() != "_ASCII_NO_NUL" { t.Fatalf("Type name not correct (ASCII no-NUL): [%s]", TypeAsciiNoNul.String()) } } func TestTypeShort_String(t *testing.T) { if TypeShort.String() != "SHORT" { t.Fatalf("Type name not correct (short): [%s]", TypeShort.String()) } } func TestTypeLong_String(t *testing.T) { if TypeLong.String() != "LONG" { t.Fatalf("Type name not correct (long): [%s]", TypeLong.String()) } } func TestTypeRational_String(t *testing.T) { if TypeRational.String() != "RATIONAL" { t.Fatalf("Type name not correct (rational): [%s]", TypeRational.String()) } } func TestTypeSignedLong_String(t *testing.T) { if TypeSignedLong.String() != "SLONG" { t.Fatalf("Type name not correct (signed long): [%s]", TypeSignedLong.String()) } } func TestTypeSignedRational_String(t *testing.T) { if TypeSignedRational.String() != "SRATIONAL" { t.Fatalf("Type name not correct (signed rational): [%s]", TypeSignedRational.String()) } } func TestTypeFloat_String(t *testing.T) { if TypeFloat.String() != "FLOAT" { t.Fatalf("Type name not correct (float): [%s]", TypeFloat.String()) } } func TestTypeDouble_String(t *testing.T) { if TypeDouble.String() != "DOUBLE" { t.Fatalf("Type name not correct (double): [%s]", TypeDouble.String()) } } func TestTypeByte_Size(t *testing.T) { if TypeByte.Size() != 1 { t.Fatalf("Type size not correct (byte): (%d)", TypeByte.Size()) } } func TestTypeAscii_Size(t *testing.T) { if TypeAscii.Size() != 1 { t.Fatalf("Type size not correct (ASCII): (%d)", TypeAscii.Size()) } } func TestTypeAsciiNoNul_Size(t *testing.T) { if TypeAsciiNoNul.Size() != 1 { t.Fatalf("Type size not correct (ASCII no-NUL): (%d)", TypeAsciiNoNul.Size()) } } func TestTypeShort_Size(t *testing.T) { if TypeShort.Size() != 2 { t.Fatalf("Type size not correct (short): (%d)", TypeShort.Size()) } } func TestTypeLong_Size(t *testing.T) { if TypeLong.Size() != 4 { t.Fatalf("Type size not correct (long): (%d)", TypeLong.Size()) } } func TestTypeRational_Size(t *testing.T) { if TypeRational.Size() != 8 { t.Fatalf("Type size not correct (rational): (%d)", TypeRational.Size()) } } func TestTypeSignedLong_Size(t *testing.T) { if TypeSignedLong.Size() != 4 { t.Fatalf("Type size not correct (signed long): (%d)", TypeSignedLong.Size()) } } func TestTypeSignedRational_Size(t *testing.T) { if TypeSignedRational.Size() != 8 { t.Fatalf("Type size not correct (signed rational): (%d)", TypeSignedRational.Size()) } } func TestTypeFloat_Size(t *testing.T) { if TypeFloat.Size() != 4 { t.Fatalf("Type size not correct (float): (%d)", TypeFloat.Size()) } } func TestTypeDouble_Size(t *testing.T) { if TypeDouble.Size() != 8 { t.Fatalf("Type size not correct (double): (%d)", TypeDouble.Size()) } } func TestFormat__Byte(t *testing.T) { r := []byte{1, 2, 3, 4, 5, 6, 7, 8} s, err := FormatFromBytes(r, TypeByte, false, TestDefaultByteOrder) log.PanicIf(err) if s != "01 02 03 04 05 06 07 08" { t.Fatalf("Format output not correct (bytes): [%s]", s) } } func TestFormat__Ascii(t *testing.T) { r := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 0} s, err := FormatFromBytes(r, TypeAscii, false, TestDefaultByteOrder) log.PanicIf(err) if s != "abcdefg" { t.Fatalf("Format output not correct (ASCII): [%s]", s) } } func TestFormat__AsciiNoNul(t *testing.T) { r := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'} s, err := FormatFromBytes(r, TypeAsciiNoNul, false, TestDefaultByteOrder) log.PanicIf(err) if s != "abcdefgh" { t.Fatalf("Format output not correct (ASCII no-NUL): [%s]", s) } } func TestFormat__Short(t *testing.T) { r := []byte{0, 1, 0, 2} s, err := FormatFromBytes(r, TypeShort, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[1 2]" { t.Fatalf("Format output not correct (shorts): [%s]", s) } } func TestFormat__Long(t *testing.T) { r := []byte{0, 0, 0, 1, 0, 0, 0, 2} s, err := FormatFromBytes(r, TypeLong, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[1 2]" { t.Fatalf("Format output not correct (longs): [%s]", s) } } func TestFormat__Float(t *testing.T) { r := []byte{0x3f, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00} s, err := FormatFromBytes(r, TypeFloat, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[1 2]" { t.Fatalf("Format output not correct (floats): [%s]", s) } } func TestFormat__Double(t *testing.T) { r := []byte{0x40, 0x09, 0x21, 0xfb, 0x53, 0xc8, 0xd4, 0xf1, 0x40, 0x05, 0xbf, 0x0a, 0x89, 0xf1, 0xb0, 0xdd} s, err := FormatFromBytes(r, TypeDouble, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[3.14159265 2.71828182]" { t.Fatalf("Format output not correct (doubles): [%s]", s) } } func TestFormat__Rational(t *testing.T) { r := []byte{ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, } s, err := FormatFromBytes(r, TypeRational, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[1/2 3/4]" { t.Fatalf("Format output not correct (rationals): [%s]", s) } } func TestFormat__SignedLong(t *testing.T) { r := []byte{0, 0, 0, 1, 0, 0, 0, 2} s, err := FormatFromBytes(r, TypeSignedLong, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[1 2]" { t.Fatalf("Format output not correct (signed longs): [%s]", s) } } func TestFormat__SignedRational(t *testing.T) { r := []byte{ 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, } s, err := FormatFromBytes(r, TypeSignedRational, false, TestDefaultByteOrder) log.PanicIf(err) if s != "[1/2 3/4]" { t.Fatalf("Format output not correct (signed rationals): [%s]", s) } } func TestFormat__Undefined(t *testing.T) { r := []byte{'a', 'b'} _, err := FormatFromBytes(r, TypeUndefined, false, TestDefaultByteOrder) if err == nil { t.Fatalf("Expected error.") } else if err.Error() != "can not determine tag-value size for type (7): [UNDEFINED]" { log.Panic(err) } } func TestTranslateStringToType__TypeUndefined(t *testing.T) { _, err := TranslateStringToType(TypeUndefined, "") if err == nil { t.Fatalf("Expected error.") } else if err.Error() != "undefined-type values are not supported" { log.Panic(err) } } func TestTranslateStringToType__TypeByte(t *testing.T) { v, err := TranslateStringToType(TypeByte, "02") log.PanicIf(err) if v != byte(2) { t.Fatalf("Translation of string to type not correct (bytes): %v", v) } } func TestTranslateStringToType__TypeAscii(t *testing.T) { v, err := TranslateStringToType(TypeAscii, "abcdefgh") log.PanicIf(err) if v != "abcdefgh" { t.Fatalf("Translation of string to type not correct (ascii): %v", v) } } func TestTranslateStringToType__TypeAsciiNoNul(t *testing.T) { v, err := TranslateStringToType(TypeAsciiNoNul, "abcdefgh") log.PanicIf(err) if v != "abcdefgh" { t.Fatalf("Translation of string to type not correct (ascii no-NUL): %v", v) } } func TestTranslateStringToType__TypeShort(t *testing.T) { v, err := TranslateStringToType(TypeShort, "11") log.PanicIf(err) if v != uint16(11) { t.Fatalf("Translation of string to type not correct (short): %v", v) } } func TestTranslateStringToType__TypeLong(t *testing.T) { v, err := TranslateStringToType(TypeLong, "11") log.PanicIf(err) if v != uint32(11) { t.Fatalf("Translation of string to type not correct (long): %v", v) } } func TestTranslateStringToType__TypeFloat(t *testing.T) { v, err := TranslateStringToType(TypeFloat, "3.14159265") log.PanicIf(err) expected := float32(3.14159265) if v.(float32) < expected || v.(float32) >= math.Nextafter32(expected, expected+1) { t.Fatalf("Translation of string to type not correct (float32): %v", v) } } func TestTranslateStringToType__TypeDouble(t *testing.T) { v, err := TranslateStringToType(TypeDouble, "3.14159265") log.PanicIf(err) expected := float64(3.14159265) if v.(float64) < expected || v.(float64) >= math.Nextafter(expected, expected+1) { t.Fatalf("Translation of string to type not correct (double): %v", v) } } func TestTranslateStringToType__TypeRational(t *testing.T) { v, err := TranslateStringToType(TypeRational, "11/22") log.PanicIf(err) r := v.(Rational) if r.Numerator != 11 || r.Denominator != 22 { t.Fatalf("Translation of string to type not correct (rational): %v", r) } } func TestTranslateStringToType__TypeSignedLong(t *testing.T) { v, err := TranslateStringToType(TypeSignedLong, "11") log.PanicIf(err) if v != int32(11) { t.Fatalf("Translation of string to type not correct (signed long): %v", v) } } func TestTranslateStringToType__TypeSignedRational(t *testing.T) { v, err := TranslateStringToType(TypeSignedRational, "11/22") log.PanicIf(err) r := v.(SignedRational) if r.Numerator != 11 || r.Denominator != 22 { t.Fatalf("Translation of string to type not correct (signed rational): %v", r) } } func TestTranslateStringToType__InvalidType(t *testing.T) { _, err := TranslateStringToType(99, "11/22") if err == nil { t.Fatalf("Expected error for invalid type.") } else if err.Error() != "from-string encoding for type not supported; this shouldn't happen: []" { log.Panic(err) } } // } else if tagType == TypeLong { // n, err := strconv.ParseUint(valueString, 10, 32) // log.PanicIf(err) // return uint32(n), nil // } else if tagType == TypeRational { // parts := strings.SplitN(valueString, "/", 2) // numerator, err := strconv.ParseUint(parts[0], 10, 32) // log.PanicIf(err) // denominator, err := strconv.ParseUint(parts[1], 10, 32) // log.PanicIf(err) // return Rational{ // Numerator: uint32(numerator), // Denominator: uint32(denominator), // }, nil // } else if tagType == TypeSignedLong { // n, err := strconv.ParseInt(valueString, 10, 32) // log.PanicIf(err) // return int32(n), nil // } else if tagType == TypeSignedRational { // parts := strings.SplitN(valueString, "/", 2) // numerator, err := strconv.ParseInt(parts[0], 10, 32) // log.PanicIf(err) // denominator, err := strconv.ParseInt(parts[1], 10, 32) // log.PanicIf(err) // return SignedRational{ // Numerator: int32(numerator), // Denominator: int32(denominator), // }, nil // } // log.Panicf("from-string encoding for type not supported; this shouldn't happen: [%s]", tagType.String()) // return nil, nil // } func TestIsPrintableText_letters(t *testing.T) { if isPrintableText("abc") != true { t.Fatalf("Printable text interpreted as nonprintable.") } } func TestIsPrintableText_space(t *testing.T) { if isPrintableText(" ") != true { t.Fatalf("Printable text interpreted as nonprintable.") } } func TestIsPrintableText_newlines(t *testing.T) { if isPrintableText("\r\n") != true { t.Fatalf("Printable text interpreted as nonprintable.") } } func TestIsPrintableText_punctuationAndSymbols(t *testing.T) { if isPrintableText(",:-/$©") != true { t.Fatalf("Printable text interpreted as nonprintable.") } }