Skip to content

Commit

Permalink
Add unit test for parsing IsUITestBundle from xctestrun file
Browse files Browse the repository at this point in the history
  • Loading branch information
bahrimootaz committed Dec 18, 2024
1 parent 3e1b3d8 commit 9194d63
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
2 changes: 1 addition & 1 deletion ios/testmanagerd/xctestrunnerutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

// Helper function to create mock data and parse the .xctestrun file
func createAndParseXCTestRunFile(t *testing.T) XCTestRunData {
func createAndParseXCTestRunFile(t *testing.T) xCTestRunData {
// Arrange: Create a temporary .xctestrun file with mock data
tempFile, err := os.CreateTemp("", "testfile*.xctestrun")
assert.NoError(t, err, "Failed to create temp file")
Expand Down
66 changes: 33 additions & 33 deletions ios/testmanagerd/xctestrunutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

// xctestrunutils provides utilities for parsing `.xctestrun` files with FormatVersion 1.
// It simplifies the extraction of test configurations and metadata into structured objects (`XCTestRunData`),
// It simplifies the extraction of test configurations and metadata into structured objects (`xCTestRunData`),
// enabling efficient setup for iOS test execution.
//
// Features:
Expand All @@ -23,30 +23,30 @@ import (
// Note: Only `.xctestrun` files with `FormatVersion` 1 are supported. For other versions,
// contributions or requests for support can be made in the relevant GitHub repository.

// XCTestRunData represents the structure of an .xctestrun file
type XCTestRunData struct {
TestConfig SchemeData `plist:"-"`
XCTestRunMetadata XCTestRunMetadata `plist:"__xctestrun_metadata__"`
// xCTestRunData represents the structure of an .xctestrun file
type xCTestRunData struct {
TestConfig schemeData `plist:"-"`
XCTestRunMetadata xCTestRunMetadata `plist:"__xctestrun_metadata__"`
}

// SchemeData represents the structure of a scheme-specific test configuration
type SchemeData struct {
TestHostBundleIdentifier string `plist:"TestHostBundleIdentifier"`
TestBundlePath string `plist:"TestBundlePath"`
SkipTestIdentifiers []string `plist:"SkipTestIdentifiers"`
OnlyTestIdentifiers []string `plist:"OnlyTestIdentifiers"`
IsUITestBundle bool `plist:"IsUITestBundle"`
CommandLineArguments []string `plist:"CommandLineArguments"`
EnvironmentVariables map[string]any `plist:"EnvironmentVariables"`
TestingEnvironmentVariables map[string]any `plist:"TestingEnvironmentVariables"`
// schemeData represents the structure of a scheme-specific test configuration
type schemeData struct {
TestHostBundleIdentifier string
TestBundlePath string
SkipTestIdentifiers []string
OnlyTestIdentifiers []string
IsUITestBundle bool
CommandLineArguments []string
EnvironmentVariables map[string]any
TestingEnvironmentVariables map[string]any
}

// XCTestRunMetadata contains metadata about the .xctestrun file
type XCTestRunMetadata struct {
type xCTestRunMetadata struct {
FormatVersion int `plist:"FormatVersion"`
}

func (data XCTestRunData) buildTestConfig(device ios.DeviceEntry, listener *TestListener) (TestConfig, error) {
func (data xCTestRunData) buildTestConfig(device ios.DeviceEntry, listener *TestListener) (TestConfig, error) {
testsToRun := data.TestConfig.OnlyTestIdentifiers
testsToSkip := data.TestConfig.SkipTestIdentifiers

Expand Down Expand Up @@ -76,37 +76,37 @@ func (data XCTestRunData) buildTestConfig(device ios.DeviceEntry, listener *Test
}

// parseFile reads the .xctestrun file and decodes it into a map
func parseFile(filePath string) (XCTestRunData, error) {
func parseFile(filePath string) (xCTestRunData, error) {
file, err := os.Open(filePath)
if err != nil {
return XCTestRunData{}, fmt.Errorf("failed to open xctestrun file: %w", err)
return xCTestRunData{}, fmt.Errorf("failed to open xctestrun file: %w", err)
}
defer file.Close()
return decode(file)
}

// decode decodes the binary xctestrun content into the XCTestRunData struct
func decode(r io.Reader) (XCTestRunData, error) {
// decode decodes the binary xctestrun content into the xCTestRunData struct
func decode(r io.Reader) (xCTestRunData, error) {
// Read the entire content once
content, err := io.ReadAll(r)
if err != nil {
return XCTestRunData{}, fmt.Errorf("failed to read content: %w", err)
return xCTestRunData{}, fmt.Errorf("failed to read content: %w", err)
}

// Use a single map for initial parsing
var rawData map[string]interface{}
if _, err := plist.Unmarshal(content, &rawData); err != nil {
return XCTestRunData{}, fmt.Errorf("failed to unmarshal plist: %w", err)
return xCTestRunData{}, fmt.Errorf("failed to unmarshal plist: %w", err)
}

result := XCTestRunData{
TestConfig: SchemeData{}, // Initialize TestConfig
result := xCTestRunData{
TestConfig: schemeData{}, // Initialize TestConfig
}

// Parse metadata
metadataMap, ok := rawData["__xctestrun_metadata__"].(map[string]interface{})
if !ok {
return XCTestRunData{}, errors.New("invalid or missing __xctestrun_metadata__")
return xCTestRunData{}, errors.New("invalid or missing __xctestrun_metadata__")
}

// Direct decoding of metadata to avoid additional conversion
Expand All @@ -116,7 +116,7 @@ func decode(r io.Reader) (XCTestRunData, error) {
case uint64:
result.XCTestRunMetadata.FormatVersion = int(v)
default:
return XCTestRunData{}, fmt.Errorf("unexpected FormatVersion type: %T", metadataMap["FormatVersion"])
return xCTestRunData{}, fmt.Errorf("unexpected FormatVersion type: %T", metadataMap["FormatVersion"])
}

// Verify FormatVersion
Expand All @@ -128,36 +128,36 @@ func decode(r io.Reader) (XCTestRunData, error) {

// Parse test schemes
if err := parseTestSchemes(rawData, &result.TestConfig); err != nil {
return XCTestRunData{}, err
return xCTestRunData{}, err
}

return result, nil
}

// parseTestSchemes extracts and parses test schemes from the raw data
func parseTestSchemes(rawData map[string]interface{}, scheme *SchemeData) error {
func parseTestSchemes(rawData map[string]interface{}, scheme *schemeData) error {
// Dynamically find and parse test schemes
for key, value := range rawData {
// Skip metadata key
if key == "__xctestrun_metadata__" {
continue
}

// Attempt to convert to SchemeData
// Attempt to convert to schemeData
schemeMap, ok := value.(map[string]interface{})
if !ok {
continue // Skip if not a valid scheme map
}

// Parse the scheme into SchemeData and update the TestConfig
var schemeParsed SchemeData
// Parse the scheme into schemeData and update the TestConfig
var schemeParsed schemeData
schemeBuf := new(bytes.Buffer)
encoder := plist.NewEncoder(schemeBuf)
if err := encoder.Encode(schemeMap); err != nil {
return fmt.Errorf("failed to encode scheme %s: %w", key, err)
}

// Decode the plist buffer into SchemeData
// Decode the plist buffer into schemeData
decoder := plist.NewDecoder(bytes.NewReader(schemeBuf.Bytes()))
if err := decoder.Decode(&schemeParsed); err != nil {
return fmt.Errorf("failed to decode scheme %s: %w", key, err)
Expand Down

0 comments on commit 9194d63

Please sign in to comment.