blob: f03f1028e88b8888c610d8e9bccd6a5403967de7 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Tests for scanner_capabilities_utils.go.
package utils
import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"github.com/google/go-cmp/cmp"
)
// Well-formatted XML test data.
const XMLTestData = `<scan:ScannerCapabilities xmlns:pwg="http://www.pwg.org/schemas/2010/12/sm" xmlns:scan="http://schemas.hp.com/imaging/escl/2011/05/03">
<pwg:Version>2.63</pwg:Version>
<pwg:MakeAndModel>MF741C/743C</pwg:MakeAndModel>
<pwg:SerialNumber>TestSerialNumber</pwg:SerialNumber>
<scan:Manufacturer>Canon</scan:Manufacturer>
<scan:UUID>TestUuid</scan:UUID>
<scan:AdminURI>TestAdminURI</scan:AdminURI>
<scan:IconURI>TestIconURI</scan:IconURI>
<scan:SettingProfiles>
<scan:SettingProfile name="p1">
<scan:ColorModes>
<scan:ColorMode>BlackAndWhite1</scan:ColorMode>
</scan:ColorModes>
<scan:DocumentFormats>
<pwg:DocumentFormat>image/jpeg</pwg:DocumentFormat>
<pwg:DocumentFormat>application/pdf</pwg:DocumentFormat>
<scan:DocumentFormatExt>image/jpeg</scan:DocumentFormatExt>
<scan:DocumentFormatExt>application/pdf</scan:DocumentFormatExt>
</scan:DocumentFormats>
<scan:SupportedResolutions>
<scan:DiscreteResolutions>
<scan:DiscreteResolution>
<scan:XResolution>100</scan:XResolution>
<scan:YResolution>200</scan:YResolution>
</scan:DiscreteResolution>
<scan:DiscreteResolution>
<scan:XResolution>300</scan:XResolution>
<scan:YResolution>300</scan:YResolution>
</scan:DiscreteResolution>
</scan:DiscreteResolutions>
</scan:SupportedResolutions>
<scan:ColorSpaces>
<scan:ColorSpace>RGB</scan:ColorSpace>
</scan:ColorSpaces>
<scan:CcdChannels>
<scan:CcdChannel scan:default="true">Red</scan:CcdChannel>
<scan:CcdChannel>Green</scan:CcdChannel>
</scan:CcdChannels>
<scan:BinaryRenderings>
<scan:BinaryRendering>Threshold</scan:BinaryRendering>
<scan:BinaryRendering scan:default="true">Halftone</scan:BinaryRendering>
</scan:BinaryRenderings>
</scan:SettingProfile>
</scan:SettingProfiles>
<scan:Platen>
<scan:PlatenInputCaps>
<scan:MinWidth>16</scan:MinWidth>
<scan:MaxWidth>1200</scan:MaxWidth>
<scan:MinHeight>32</scan:MinHeight>
<scan:MaxHeight>2800</scan:MaxHeight>
<scan:MaxScanRegions>2</scan:MaxScanRegions>
<scan:MaxOpticalXResolution>800</scan:MaxOpticalXResolution>
<scan:MaxOpticalYResolution>1200</scan:MaxOpticalYResolution>
<scan:MaxPhysicalWidth>1200</scan:MaxPhysicalWidth>
<scan:MaxPhysicalHeight>2800</scan:MaxPhysicalHeight>
<scan:SettingProfiles>
<scan:SettingProfile>
<scan:ColorModes>
<scan:ColorMode>RGB24</scan:ColorMode>
</scan:ColorModes>
<scan:DocumentFormats>
<pwg:DocumentFormat>application/octet-stream</pwg:DocumentFormat>
</scan:DocumentFormats>
<scan:SupportedResolutions>
<scan:ResolutionRange>
<scan:XResolutionRange>
<scan:Min>75</scan:Min>
<scan:Max>800</scan:Max>
<scan:Normal>300</scan:Normal>
<scan:Step>10</scan:Step>
</scan:XResolutionRange>
<scan:YResolutionRange>
<scan:Min>150</scan:Min>
<scan:Max>1200</scan:Max>
<scan:Normal>600</scan:Normal>
<scan:Step>50</scan:Step>
</scan:YResolutionRange>
</scan:ResolutionRange>
</scan:SupportedResolutions>
<scan:ColorSpaces>
<scan:ColorSpace>RGB</scan:ColorSpace>
</scan:ColorSpaces>
<scan:CcdChannels>
<scan:CcdChannel>Blue</scan:CcdChannel>
</scan:CcdChannels>
</scan:SettingProfile>
</scan:SettingProfiles>
<scan:SupportedIntents>
<scan:Intent>Document</scan:Intent>
<scan:Intent>Photo</scan:Intent>
</scan:SupportedIntents>
<scan:EdgeAutoDetection>
<scan:SupportedEdge>TopEdge</scan:SupportedEdge>
<scan:SupportedEdge>BottomEdge</scan:SupportedEdge>
</scan:EdgeAutoDetection>
<scan:RiskyLeftMargin>28</scan:RiskyLeftMargin>
<scan:RiskyRightMargin>30</scan:RiskyRightMargin>
<scan:RiskyTopMargin>32</scan:RiskyTopMargin>
<scan:RiskyBottomMargin>44</scan:RiskyBottomMargin>
</scan:PlatenInputCaps>
</scan:Platen>
<scan:Adf>
<scan:AdfSimplexInputCaps>
<scan:MinWidth>32</scan:MinWidth>
<scan:MaxWidth>2551</scan:MaxWidth>
<scan:MinHeight>32</scan:MinHeight>
<scan:MaxHeight>4200</scan:MaxHeight>
<scan:MaxScanRegions>1</scan:MaxScanRegions>
<scan:MaxOpticalXResolution>300</scan:MaxOpticalXResolution>
<scan:MaxOpticalYResolution>300</scan:MaxOpticalYResolution>
<scan:MaxPhysicalWidth>2551</scan:MaxPhysicalWidth>
<scan:MaxPhysicalHeight>4200</scan:MaxPhysicalHeight>
<scan:SettingProfiles>
<scan:SettingProfile ref="p1"/>
</scan:SettingProfiles>
<scan:SupportedIntents>
<scan:Intent>Document</scan:Intent>
</scan:SupportedIntents>
</scan:AdfSimplexInputCaps>
<scan:AdfDuplexInputCaps>
<scan:MinWidth>32</scan:MinWidth>
<scan:MaxWidth>2551</scan:MaxWidth>
<scan:MinHeight>32</scan:MinHeight>
<scan:MaxHeight>4200</scan:MaxHeight>
<scan:MaxScanRegions>1</scan:MaxScanRegions>
<scan:MaxOpticalXResolution>300</scan:MaxOpticalXResolution>
<scan:MaxOpticalYResolution>300</scan:MaxOpticalYResolution>
<scan:MaxPhysicalWidth>2551</scan:MaxPhysicalWidth>
<scan:MaxPhysicalHeight>4200</scan:MaxPhysicalHeight>
<scan:SettingProfiles>
<scan:SettingProfile ref="p1"/>
</scan:SettingProfiles>
<scan:SupportedIntents>
<scan:Intent>Photo</scan:Intent>
</scan:SupportedIntents>
</scan:AdfDuplexInputCaps>
<scan:FeederCapacity>100</scan:FeederCapacity>
<scan:Justification>
<pwg:XImagePosition>Center</pwg:XImagePosition>
<pwg:YImagePosition>Top</pwg:YImagePosition>
</scan:Justification>
<scan:AdfOptions>
<scan:AdfOption>DetectPaperLoaded</scan:AdfOption>
<scan:AdfOption>Duplex</scan:AdfOption>
</scan:AdfOptions>
</scan:Adf>
<scan:StoredJobRequestSupport>
<scan:MaxStoredJobRequests>10</scan:MaxStoredJobRequests>
<scan:TimeoutInSeconds>120</scan:TimeoutInSeconds>
<scan:PINLength>4</scan:PINLength>
<scan:MaxJobNameLength>256</scan:MaxJobNameLength>
</scan:StoredJobRequestSupport>
<scan:BlankPageDetection>true</scan:BlankPageDetection>
<scan:BlankPageDetectionAndRemoval>true</scan:BlankPageDetectionAndRemoval>
</scan:ScannerCapabilities>`
// XML test data which references a SettingProfile which does not exist.
const noReferencedProfileXMLTestData = `<scan:ScannerCapabilities xmlns:pwg="http://www.pwg.org/schemas/2010/12/sm" xmlns:scan="http://schemas.hp.com/imaging/escl/2011/05/03">
<pwg:Version>2.63</pwg:Version>
<pwg:MakeAndModel>MF741C/743C</pwg:MakeAndModel>
<pwg:SerialNumber>TestSerialNumber</pwg:SerialNumber>
<scan:Manufacturer>Canon</scan:Manufacturer>
<scan:UUID>TestUUID</scan:UUID>
<scan:AdminURI>TestAdminURI</scan:AdminURI>
<scan:IconURI>TestIconURI</scan:IconURI>
<scan:Platen>
<scan:PlatenInputCaps>
<scan:MinWidth>16</scan:MinWidth>
<scan:MaxWidth>1200</scan:MaxWidth>
<scan:MinHeight>32</scan:MinHeight>
<scan:MaxHeight>2800</scan:MaxHeight>
<scan:MaxScanRegions>2</scan:MaxScanRegions>
<scan:MaxOpticalXResolution>800</scan:MaxOpticalXResolution>
<scan:MaxOpticalYResolution>1200</scan:MaxOpticalYResolution>
<scan:MaxPhysicalWidth>1200</scan:MaxPhysicalWidth>
<scan:MaxPhysicalHeight>2800</scan:MaxPhysicalHeight>
<scan:SettingProfiles>
<scan:SettingProfile ref="p1"/>
</scan:SettingProfiles>
<scan:SupportedIntents>
<scan:Intent>Document</scan:Intent>
<scan:Intent>Photo</scan:Intent>
</scan:SupportedIntents>
<scan:EdgeAutoDetection>
<scan:SupportedEdge>TopEdge</scan:SupportedEdge>
<scan:SupportedEdge>BottomEdge</scan:SupportedEdge>
</scan:EdgeAutoDetection>
<scan:RiskyLeftMargin>28</scan:RiskyLeftMargin>
<scan:RiskyRightMargin>30</scan:RiskyRightMargin>
<scan:RiskyTopMargin>32</scan:RiskyTopMargin>
<scan:RiskyBottomMargin>44</scan:RiskyBottomMargin>
</scan:PlatenInputCaps>
</scan:Platen>
</scan:ScannerCapabilities>`
// XML test data which is not valid XML.
const badXMLTestData = `<scan:ScannerCapabilities`
// Well-formatted test data from lorgnette_cli.
const lorgnetteCLITestData = `{
"SOURCE_ADF_DUPLEX":{
"ColorModes":["MODE_COLOR"],
"Name":"ADF Duplex",
"Resolutions":[150],
"ScannableArea":{"Height":400,"Width":120}},
"SOURCE_ADF_SIMPLEX":{
"ColorModes":["MODE_LINEART"],
"Name":"ADF","Resolutions":[200,600],
"ScannableArea":{"Height":200,"Width":100}},
"SOURCE_PLATEN":{
"ColorModes":["MODE_COLOR","MODE_GRAYSCALE"],
"Name":"Flatbed","Resolutions":[300],
"ScannableArea":{"Height":355.59999084472656,"Width":215.9846649169922}}
}`
// Test data from lorgnette_cli which is not valid JSON data.
const badJSONlorgnetteCLITestData = `{"SOURCE_ADF_DUPLEX":{"ColorModes":`
// prettyFormatStruct formats a struct as JSON for human-readability.
func prettyFormatStruct(i interface{}) string {
s, _ := json.MarshalIndent(i, "", " ")
return string(s)
}
// TestGetScannerCapabilities tests that a scanner capabilities response can be
// parsed successfully.
func TestGetScannerCapabilities(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, XMLTestData)
}))
defer ts.Close()
got, err := GetScannerCapabilities(ts.URL + "/")
if err != nil {
t.Error(err)
}
want := ScannerCapabilities{
Version: "2.63",
MakeAndModel: "MF741C/743C",
Manufacturer: "Canon",
SettingProfiles: []SettingProfile{
SettingProfile{
Name: "p1",
Ref: "",
ColorModes: []string{"BlackAndWhite1"},
DocumentFormats: []string{"image/jpeg", "application/pdf"},
DocumentFormatsExt: []string{"image/jpeg", "application/pdf"},
SupportedResolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 100,
YResolution: 200},
DiscreteResolution{
XResolution: 300,
YResolution: 300}},
XResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0},
YResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0}}}},
PlatenInputCaps: SourceCapabilities{
MaxWidth: 1200,
MinWidth: 16,
MaxHeight: 2800,
MinHeight: 32,
MaxScanRegions: 2,
SettingProfile: SettingProfile{
Name: "",
Ref: "",
ColorModes: []string{"RGB24"},
DocumentFormats: []string{"application/octet-stream"},
SupportedResolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 75,
Max: 800,
Normal: 300,
Step: 10},
YResolutionRange: ResolutionRange{
Min: 150,
Max: 1200,
Normal: 600,
Step: 50}}},
MaxOpticalXResolution: 800,
MaxOpticalYResolution: 1200,
MaxPhysicalWidth: 1200,
MaxPhysicalHeight: 2800},
AdfCapabilities: AdfCapabilities{
AdfSimplexInputCaps: SourceCapabilities{
MaxWidth: 2551,
MinWidth: 32,
MaxHeight: 4200,
MinHeight: 32,
MaxScanRegions: 1,
SettingProfile: SettingProfile{
Name: "p1",
Ref: "",
ColorModes: []string{"BlackAndWhite1"},
DocumentFormats: []string{"image/jpeg", "application/pdf"},
DocumentFormatsExt: []string{"image/jpeg", "application/pdf"},
SupportedResolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 100,
YResolution: 200},
DiscreteResolution{
XResolution: 300,
YResolution: 300}},
XResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0},
YResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0}}},
MaxOpticalXResolution: 300,
MaxOpticalYResolution: 300,
MaxPhysicalWidth: 2551,
MaxPhysicalHeight: 4200},
AdfDuplexInputCaps: SourceCapabilities{
MaxWidth: 2551,
MinWidth: 32,
MaxHeight: 4200,
MinHeight: 32,
MaxScanRegions: 1,
SettingProfile: SettingProfile{
Name: "p1",
Ref: "",
ColorModes: []string{"BlackAndWhite1"},
DocumentFormats: []string{"image/jpeg", "application/pdf"},
DocumentFormatsExt: []string{"image/jpeg", "application/pdf"},
SupportedResolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 100,
YResolution: 200},
DiscreteResolution{
XResolution: 300,
YResolution: 300}},
XResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0},
YResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0}}},
MaxOpticalXResolution: 300,
MaxOpticalYResolution: 300,
MaxPhysicalWidth: 2551,
MaxPhysicalHeight: 4200},
AdfOptions: []string{"DetectPaperLoaded", "Duplex"}},
CameraInputCaps: SourceCapabilities{
MaxWidth: 0,
MinWidth: 0,
MaxHeight: 0,
MinHeight: 0,
MaxScanRegions: 0,
SettingProfile: SettingProfile{
Name: "",
Ref: "",
SupportedResolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0},
YResolutionRange: ResolutionRange{
Min: 0,
Max: 0,
Normal: 0,
Step: 0}}},
MaxOpticalXResolution: 0,
MaxOpticalYResolution: 0,
MaxPhysicalWidth: 0,
MaxPhysicalHeight: 0},
StoredJobRequestSupport: StoredJobRequestSupport{
MaxStoredJobRequests: 10,
TimeoutInSeconds: 120,
PINLength: 4,
MaxJobNameLength: 256}}
if !cmp.Equal(want, got) {
// For such long structs, it's easier to compare if they're
// pretty-printed.
t.Errorf("Expected: %s, got: %s", prettyFormatStruct(want), prettyFormatStruct(got))
}
}
// TestGetScannerCapabilitiesNotReferencedProfile tests that an input
// capabilities object which references a SettingProfile which does exist fails
// to parse.
func TestGetScannerCapabilitiesNotReferencedProfile(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, noReferencedProfileXMLTestData)
}))
defer ts.Close()
_, err := GetScannerCapabilities(ts.URL + "/")
if err == nil {
t.Error("Expected error from referenced profile not existing")
}
}
// TestGetScannerCapabilitiesBadHttpResponse tests that a bad HTTP response is
// caught.
func TestGetScannerCapabilitiesBadHttpResponse(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, XMLTestData)
}))
defer ts.Close()
_, err := GetScannerCapabilities(ts.URL + "/")
if err == nil {
t.Error("Expected error from bad HTTP response status")
}
}
// TestGetScannerCapabilitiesBadXml tests that a bad XML response is caught.
func TestGetScannerCapabilitiesBadXml(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, badXMLTestData)
}))
defer ts.Close()
_, err := GetScannerCapabilities(ts.URL + "/")
if err == nil {
t.Error("Expected error from bad XML")
}
}
// TestParseLorgnetteCapabilities tests that JSON data can be parsed into
// LorgnetteCapabilities.
func TestParseLorgnetteCapabilities(t *testing.T) {
got, err := ParseLorgnetteCapabilities(lorgnetteCLITestData)
if err != nil {
t.Error(err)
}
want := LorgnetteCapabilities{
PlatenCaps: LorgnetteSource{
ColorModes: []string{
"MODE_COLOR",
"MODE_GRAYSCALE"},
Resolutions: []int{
300},
ScannableArea: ScannableArea{
Height: 355.59999084472656,
Width: 215.9846649169922}},
AdfSimplexCaps: LorgnetteSource{
ColorModes: []string{
"MODE_LINEART"},
Resolutions: []int{
200,
600},
ScannableArea: ScannableArea{
Height: 200,
Width: 100}},
AdfDuplexCaps: LorgnetteSource{
ColorModes: []string{
"MODE_COLOR"},
Resolutions: []int{
150},
ScannableArea: ScannableArea{
Height: 400,
Width: 120}}}
if !cmp.Equal(want, got) {
// For such long structs, it's easier to compare if they're
// pretty-printed.
t.Errorf("Expected: %s, got: %s", prettyFormatStruct(want), prettyFormatStruct(got))
}
}
// TestParseLorgnetteCapabilitiesBadJSON tests that incorrectly formatted JSON
// data is caught.
func TestParseLorgnetteCapabilitiesBadJSON(t *testing.T) {
_, err := ParseLorgnetteCapabilities(badJSONlorgnetteCLITestData)
if err == nil {
t.Error("Expected error from bad JSON")
}
}
// TestIsPopulated tests that the IsPopulated function works correctly.
func TestIsPopulated(t *testing.T) {
tests := []struct {
caps SourceCapabilities
ret bool
}{
{
caps: SourceCapabilities{
MaxWidth: 1200,
MinWidth: 16,
MaxHeight: 2800,
MinHeight: 32,
MaxScanRegions: 2,
SettingProfile: SettingProfile{
Name: "",
Ref: "",
ColorModes: []string{"RGB24"},
DocumentFormats: []string{"application/octet-stream"},
SupportedResolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 65,
Max: 85,
Normal: 75,
Step: 10},
YResolutionRange: ResolutionRange{
Min: 60,
Max: 105,
Normal: 90,
Step: 15}}},
MaxOpticalXResolution: 85,
MaxOpticalYResolution: 105,
MaxPhysicalWidth: 1200,
MaxPhysicalHeight: 2800},
ret: true,
},
{
caps: SourceCapabilities{},
ret: false,
},
}
for _, tc := range tests {
got := tc.caps.IsPopulated()
if got != tc.ret {
t.Errorf("Expected %t, got %t for caps: %v", tc.ret, got, tc.caps)
}
}
}
// TestToLorgnetteResolutions tests that the ToLorgnetteResolutions function
// works correctly.
func TestToLorgnetteResolutions(t *testing.T) {
tests := []struct {
resolutions SupportedResolutions
lorgnetteResolutions []int
}{
{
resolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 75,
Max: 600,
Normal: 300,
Step: 25},
YResolutionRange: ResolutionRange{
Min: 75,
Max: 600,
Normal: 300,
Step: 5}},
lorgnetteResolutions: []int{75, 100, 150, 200, 300, 600},
},
{
resolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 75,
YResolution: 75,
},
DiscreteResolution{
XResolution: 100,
YResolution: 100,
},
DiscreteResolution{
XResolution: 150,
YResolution: 150,
},
DiscreteResolution{
XResolution: 200,
YResolution: 200,
},
DiscreteResolution{
XResolution: 300,
YResolution: 300,
},
DiscreteResolution{
XResolution: 600,
YResolution: 600,
},
}},
lorgnetteResolutions: []int{75, 100, 150, 200, 300, 600},
},
{
resolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 0,
Max: 225,
Normal: 150,
Step: 75},
YResolutionRange: ResolutionRange{
Min: 0,
Max: 700,
Normal: 300,
Step: 100}},
},
{
resolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 50,
YResolution: 50,
},
DiscreteResolution{
XResolution: 125,
YResolution: 125,
},
DiscreteResolution{
XResolution: 1200,
YResolution: 1200,
},
DiscreteResolution{
XResolution: 200,
YResolution: 300,
},
DiscreteResolution{
XResolution: 300,
YResolution: 200,
},
}},
},
{
resolutions: SupportedResolutions{},
},
}
for _, tc := range tests {
got := tc.resolutions.ToLorgnetteResolutions()
if !cmp.Equal(got, tc.lorgnetteResolutions) {
t.Errorf("Expected %v, got %v for resolutions: %v", tc.lorgnetteResolutions, got, tc.resolutions)
}
}
}
// TestToLorgnetteSource tests that the ToLorgnetteSource function works
// correctly.
func TestToLorgnetteSource(t *testing.T) {
tests := []struct {
caps SourceCapabilities
lorgnetteSource LorgnetteSource
}{
{
caps: SourceCapabilities{
MaxWidth: 2551,
MaxHeight: 4200,
SettingProfile: SettingProfile{
ColorModes: []string{"BlackAndWhite1", "Grayscale8", "Grayscale16", "RGB24", "RGB48"},
SupportedResolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 75,
Max: 600,
Normal: 75,
Step: 25},
YResolutionRange: ResolutionRange{
Min: 60,
Max: 700,
Normal: 90,
Step: 5}}}},
lorgnetteSource: LorgnetteSource{
ColorModes: []string{"MODE_GRAYSCALE", "MODE_UNSPECIFIED", "MODE_COLOR", "MODE_UNSPECIFIED"},
Resolutions: []int{75, 100, 150, 200, 300, 600},
ScannableArea: ScannableArea{
Height: 355.6,
Width: 215.98466}},
},
{
caps: SourceCapabilities{},
lorgnetteSource: LorgnetteSource{},
},
}
for _, tc := range tests {
got := tc.caps.ToLorgnetteSource()
if !cmp.Equal(got, tc.lorgnetteSource) {
t.Errorf("Expected %v, got %v for caps: %v", tc.lorgnetteSource, got, tc.caps)
}
}
}
// TestToLorgnetteCaps tests that the ToLorgnetteCaps function works correctly.
func TestToLorgnetteCaps(t *testing.T) {
tests := []struct {
caps ScannerCapabilities
lorgnetteCaps LorgnetteCapabilities
}{
{
caps: ScannerCapabilities{
PlatenInputCaps: SourceCapabilities{
MaxWidth: 1200,
MaxHeight: 2800,
SettingProfile: SettingProfile{
ColorModes: []string{"Grayscale16", "RGB24"},
SupportedResolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 75,
Max: 150,
Normal: 150,
Step: 75},
YResolutionRange: ResolutionRange{
Min: 75,
Max: 150,
Normal: 150,
Step: 75}}}},
AdfCapabilities: AdfCapabilities{
AdfSimplexInputCaps: SourceCapabilities{
MaxWidth: 2551,
MaxHeight: 4200,
SettingProfile: SettingProfile{
ColorModes: []string{"BlackAndWhite1", "Grayscale8"},
SupportedResolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 100,
YResolution: 200},
DiscreteResolution{
XResolution: 300,
YResolution: 300}}}}},
AdfDuplexInputCaps: SourceCapabilities{
MaxWidth: 1850,
MaxHeight: 3200,
SettingProfile: SettingProfile{
ColorModes: []string{"BlackAndWhite1", "RGB48"},
SupportedResolutions: SupportedResolutions{
DiscreteResolutions: []DiscreteResolution{
DiscreteResolution{
XResolution: 200,
YResolution: 200},
DiscreteResolution{
XResolution: 600,
YResolution: 600}}}}}}},
lorgnetteCaps: LorgnetteCapabilities{
PlatenCaps: LorgnetteSource{
ColorModes: []string{"MODE_UNSPECIFIED", "MODE_COLOR"},
Resolutions: []int{75, 150},
ScannableArea: ScannableArea{
Height: 237.06667,
Width: 101.6}},
AdfSimplexCaps: LorgnetteSource{
ColorModes: []string{"MODE_GRAYSCALE"},
Resolutions: []int{300},
ScannableArea: ScannableArea{
Height: 355.6,
Width: 215.98466}},
AdfDuplexCaps: LorgnetteSource{
ColorModes: []string{"MODE_UNSPECIFIED"},
Resolutions: []int{200, 600},
ScannableArea: ScannableArea{
Height: 270.93333,
Width: 156.63333}}},
},
{
caps: ScannerCapabilities{
PlatenInputCaps: SourceCapabilities{
MaxWidth: 1200,
MaxHeight: 2800,
SettingProfile: SettingProfile{
ColorModes: []string{"Grayscale16", "RGB24"},
SupportedResolutions: SupportedResolutions{
XResolutionRange: ResolutionRange{
Min: 75,
Max: 150,
Normal: 150,
Step: 75},
YResolutionRange: ResolutionRange{
Min: 75,
Max: 150,
Normal: 150,
Step: 75}}}}},
lorgnetteCaps: LorgnetteCapabilities{
PlatenCaps: LorgnetteSource{
ColorModes: []string{"MODE_UNSPECIFIED", "MODE_COLOR"},
Resolutions: []int{75, 150},
ScannableArea: ScannableArea{
Height: 237.06667,
Width: 101.6}}},
},
{
caps: ScannerCapabilities{},
lorgnetteCaps: LorgnetteCapabilities{},
},
}
for _, tc := range tests {
got := tc.caps.ToLorgnetteCaps()
if !cmp.Equal(got, tc.lorgnetteCaps) {
t.Errorf("Expected %v, got %v for caps: %v", tc.lorgnetteCaps, got, tc.caps)
}
}
}