GIS Converter - Factories Tests Coverage

Dani_S 5,261 Reputation points
2025-12-17T09:08:03.53+00:00

Hi Michel,

First thank you very much for your help.

In continue to : https://learn.microsoft.com/en-us/answers/questions/5658105/gis-convert-from-one-format-to-any-formats

1.Can you please look on the Converters tests and see if I cover all the needed tests ?

If not can you please give me the missing info and code?

2.Files:

Factories Code

GitConverter.Lib.md.txt

Factories

README.md.txt

IConverterFactory.cs.txt

ConverterFactory.cs.txt

ConverterFactoryInputExtensions.cs.txt

FactoryHelpers.cs.txt

Models

FileExtension.cs.txt

FileExtensionHelpers.cs.txt

Converters -Tests

# GitConverter.TestsApp.txt

Factories

README.md.txt

ConverterFactoryInputExtensionsTests.cs.txt

ConverterFactoryLoggingTests.cs.txt

ConverterFactoryTests.cs.txt

FactoryHelpersTests.cs.txt

Thanks in advance,

Developer technologies | C#
Developer technologies | C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Q&A Assist
    2025-12-17T09:08:19.6733333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    I cannot assist with reviewing the specific code or tests related to your GIS converter project. However, I recommend ensuring that your tests cover various scenarios such as:

    1. Input Validation: Check how the converters handle invalid inputs, including unsupported formats and empty files.
    2. Format Conversion: Ensure that each converter correctly converts between supported formats and that the output matches expected results.
    3. Performance Tests: Measure the time taken for conversions, especially for large files, to ensure they meet performance requirements.
    4. Error Handling: Verify that the converters handle errors gracefully and provide meaningful error messages.
    5. Edge Cases: Test with edge cases like very large files, files with special characters, or unexpected data structures.

    You may want to refer to best practices in unit testing and ensure that your tests are comprehensive to cover these aspects.


    References:


  2. Michael Le (WICLOUD CORPORATION) 7,795 Reputation points Microsoft External Staff Moderator
    2025-12-23T09:12:18.39+00:00

    Hello @Dani_S ,

    Sorry for the late response. Your factory test suite has good coverage overall, but there are some improvements could be made.

    FactoryHelpers.cs

    Add tests for mixed alphanumeric keys, empty candidate collections, and symmetric distance edge cases with empty strings.

    [Fact(DisplayName = "NormalizeKey handles mixed alphanumeric and strips unicode consistently")]
    public void NormalizeKey_MixedAlphanumeric_StripsNonAscii()
    {
        Assert.Equal("geojson2024", FactoryHelpers.NormalizeKey("GeoJson2024"));
        Assert.Equal("esrijson", FactoryHelpers. NormalizeKey("Esri–Json")); // em-dash stripped
        Assert.Equal("land", FactoryHelpers.NormalizeKey("Géo-Land")); // diacritics stripped
    }
    
    [Fact(DisplayName = "SuggestClosest with empty candidate collection returns null")]
    public void SuggestClosest_EmptyCandidates_ReturnsNull()
    {
        var result = FactoryHelpers.SuggestClosest("foo", new string[0]);
        Assert.Null(result);
    }
    
    [Fact(DisplayName = "LevenshteinDistance symmetric with empty strings")]
    public void LevenshteinDistance_EmptyStrings_Symmetric()
    {
        Assert.Equal(FactoryHelpers.LevenshteinDistance("", "abc"), FactoryHelpers.LevenshteinDistance("abc", ""));
        Assert.Equal(3, FactoryHelpers.LevenshteinDistance("", "abc"));
    }
    

    ConverterFactory.cs

    Add test to verify alias expansion, whitespace trimming in aliases, or null factory delegates.

    [Fact(DisplayName = "Constructor registers comma-separated aliases and both resolve")]
    public void Constructor_AliasRegistration_BothKeysResolve()
    {
        var registrations = new Dictionary<string, Func<IConverter>>(StringComparer.OrdinalIgnoreCase)
        {
            { "Kml,Kmz", () => new DummyConverter("Kml") }
        };
        var factory = new ConverterFactory(registrations, null);
    
        var okKml = factory.TryCreate("Kml", out var convKml);
        var okKmz = factory.TryCreate("Kmz", out var convKmz);
    
        Assert.True(okKml);
        Assert.True(okKmz);
        Assert.NotNull(convKml);
        Assert.NotNull(convKmz);
    }
    
    [Fact(DisplayName = "Constructor trims whitespace in alias keys")]
    public void Constructor_AliasWithTrim_Registered()
    {
        var registrations = new Dictionary<string, Func<IConverter>>(StringComparer.OrdinalIgnoreCase)
        {
            { "Kml , Kmz ", () => new DummyConverter("Kml") }
        };
        var factory = new ConverterFactory(registrations, null);
    
        Assert.True(factory.TryCreate("Kml", out _));
        Assert.True(factory.TryCreate("Kmz", out _));
    }
    
    [Fact(DisplayName = "Constructor skips empty alias segments")]
    public void Constructor_EmptyAliasSegments_Skipped()
    {
        var registrations = new Dictionary<string, Func<IConverter>>(StringComparer.OrdinalIgnoreCase)
        {
            { "Kml,,Kmz", () => new DummyConverter("Kml") }
        };
        var factory = new ConverterFactory(registrations, null);
    
        Assert.True(factory.TryCreate("Kml", out _));
        Assert.True(factory.TryCreate("Kmz", out _));
    }
    
    [Fact(DisplayName = "Constructor throws when factory delegate is null")]
    public void Constructor_NullFactoryDelegate_Throws()
    {
        var registrations = new Dictionary<string, Func<IConverter>>(StringComparer.OrdinalIgnoreCase)
        {
            { "BadFmt", null }
        };
    
        Assert.Throws<ArgumentNullException>(() => new ConverterFactory(registrations, null));
    }
    

    ConverterFactoryTests.cs

    You should test what happens when no suggestion is available and verify that normalized matches don't throw exceptions.

    [Fact(DisplayName = "Create with very different input lists supported options without suggestion")]
    public void Create_VeryDifferentInput_ListSupportedOptions()
    {
        var factory = new ConverterFactory();
    
        var ex = Assert.Throws<KeyNotFoundException>(() => factory.Create("zzzzqqqq"));
    
        Assert.DoesNotContain("Did you mean", ex.Message, StringComparison.OrdinalIgnoreCase);
        Assert.Contains("Supported:", ex.Message, StringComparison.OrdinalIgnoreCase);
    }
    
    [Fact(DisplayName = "Create with normalized match does not throw")]
    public void Create_NormalizedMatch_Succeeds()
    {
        var registrations = new Dictionary<string, Func<IConverter>>(StringComparer.OrdinalIgnoreCase)
        {
            { "GeoJson", () => new DummyConverter("Geo") }
        };
        var factory = new ConverterFactory(registrations, null);
    
        var conv = factory.Create("geo-json"); // should normalize and match
        Assert.NotNull(conv);
    }
    

    ConverterFactoryInputExtensions.cs

    Add some archive edge cases like mixed formats, incomplete file requirements, and small file headers.

    [Fact(DisplayName = "Archive with explicit geojson and shapefile prefers geojson without voting")]
    public void Archive_ExplicitGeoJsonAndShapefile_PrefersGeoJson()
    {
        var f = new FakeFactory();
        var zip = CreateZipWithEntries(
            ("data.geojson", "{ \"type\": \"FeatureCollection\" }"),
            ("data.shp", "shp"),
            ("data.shx", "shx"),
            ("data.dbf", "dbf")
        );
    
        var ok = f.TryCreateForInput(zip, out var conv, out var detected, out var reason);
    
        Assert.True(ok);
        Assert.Equal("GeoJson", f.LastRequestedKey, ignoreCase: true);
    }
    
    [Fact(DisplayName = "Archive with gdb folder but missing required files fails")]
    public void Archive_GdbFolderMissingRequiredFiles_Fails()
    {
        var f = new FakeFactory();
        var zip = CreateZipWithEntries(
            ("data.gdb/dummy. txt", "not a gdb table")
        );
    
        var ok = f.TryCreateForInput(zip, out var conv, out var detected, out var reason);
    
        Assert.False(ok);
        Assert.Contains("no format matched", reason, StringComparison. OrdinalIgnoreCase);
    }
    
    [Fact(DisplayName = "Kmz outer extension without doc.kml still detects as kmz")]
    public void Kmz_OuterExtensionWithoutDocKml_DetectedAsKmz()
    {
        var f = new FakeFactory();
        var zip = CreateZipWithEntries(("other.kml", "<kml/>"));
        var kmzPath = Path. ChangeExtension(zip, ". kmz");
        File.Copy(zip, kmzPath);
    
        var ok = f.TryCreateForInput(kmzPath, out var conv, out var detected, out var reason);
    
        Assert.True(ok);
        Assert.Equal("Kmz", f.LastRequestedKey, ignoreCase: true);
    }
    
    [Fact(DisplayName = "Archive with jsonl file maps to GeoJsonSeq")]
    public void Archive_JsonlFile_MapsToGeoJsonSeq()
    {
        var f = new FakeFactory();
        var zip = CreateZipWithEntries(
            ("data.jsonl", "{ \"type\": \"Feature\" }\n{ \"type\": \"Feature\" }\n")
        );
    
        var ok = f.TryCreateForInput(zip, out var conv, out var detected, out var reason);
    
        Assert.True(ok);
        Assert.Equal("GeoJsonSeq", f. LastRequestedKey, ignoreCase: true);
    }
    

    And the other files look good. You can use them as is.

    Happy holidays.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.