• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MeindertN / RoboClerk / 19313674688

12 Nov 2025 10:19PM UTC coverage: 81.831% (-2.2%) from 84.026%
19313674688

push

github

web-flow
Merge pull request #79 from MeindertN/V1.6.0

jumping to V1.7.0

2069 of 2635 branches covered (78.52%)

Branch coverage included in aggregate %.

1293 of 1710 new or added lines in 32 files covered. (75.61%)

17 existing lines in 5 files now uncovered.

6322 of 7619 relevant lines covered (82.98%)

189.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.54
/RoboClerk.TestDescriptionImportPlugin/TestDescriptionFilePlugin.cs
1
using RoboClerk.Configuration;
2
using System.Collections.Generic;
3
using System.IO.Abstractions;
4
using System.Text.Json;
5
using Tomlyn.Model;
6
using System;
7

8
namespace RoboClerk.TestDescriptionFilePlugin
9
{
10
    public class TestDescriptionFilePlugin : DataSourcePluginBase
11
    {
12
        private List<string> fileLocations = new List<string>();
20✔
13

14
        public TestDescriptionFilePlugin(IFileSystem fileSystem)
15
            : base(fileSystem)
20✔
16
        {
20✔
17
            SetBaseParam();
20✔
18
        }
20✔
19

20
        private void SetBaseParam()
21
        {
20✔
22
            name = "TestDescriptionFilePlugin";
20✔
23
            description = "A plugin that retrieves test descriptions (system/unit) via one or more files.";
20✔
24
        }
20✔
25

26
        public override void InitializePlugin(IConfiguration configuration)
27
        {
19✔
28
            logger.Info("Initializing the Test Description File Plugin");
19✔
29
            try
30
            {
19✔
31
                var config = GetConfigurationTable(configuration.PluginConfigDir, $"{name}.toml");
19✔
32
                foreach (var item in (TomlArray)config["FileLocations"])
126✔
33
                {
36✔
34
                    if (item == null)
36!
NEW
35
                    {
×
NEW
36
                        logger.Warn($"In the Test Description File Plugin configuration file (\"{name}.toml\"), there is a null valued item in \"FileLocations\".");
×
NEW
37
                        continue;
×
38
                    }
39
                    fileLocations.Add((string)item);
36✔
40
                }
36✔
41
            }
18✔
42
            catch (Exception e)
1✔
43
            {
1✔
44
                logger.Error("Error reading configuration file for Test Description File plugin.");
1✔
45
                logger.Error(e);
1✔
46
                throw new Exception("The Test Description File plugin could not read its configuration. Aborting...");
1✔
47
            }
48
        }
18✔
49

50
        public override void RefreshItems()
51
        {
17✔
52
            logger.Info("Refreshing the test descriptions from file.");
17✔
53
            
54
            for (int i = 0; i < fileLocations.Count; i++)
78✔
55
            {
29✔
56
                string json = fileSystem.File.ReadAllText(fileLocations[i]);
29✔
57
                try
58
                {
29✔
59
                    var fileTestDescriptions = JsonSerializer.Deserialize<List<TestDescriptionJSONObject>>(json);
29✔
60

61
                    foreach (var description in fileTestDescriptions)
130✔
62
                    {
29✔
63
                        ValidateTestDescription(description, fileLocations[i]);
29✔
64

65
                        if (description.Type == TestType.UNIT)
26✔
66
                        {
11✔
67
                            var test = new UnitTestItem();
11✔
68
                            test.ItemID = description.ID;
11✔
69
                            test.UnitTestFunctionName = description.Name;
11✔
70
                            test.UnitTestPurpose = description.Purpose;
11✔
71
                            test.UnitTestAcceptanceCriteria = description.Acceptance;   
11✔
72
                            test.UnitTestFileName = description.Filename;
11✔
73
                            test.ItemProject = description.Project ?? string.Empty;
11✔
74
                            foreach (var trace in description.Trace)
65✔
75
                            {
16✔
76
                                test.AddLinkedItem(new ItemLink(trace,ItemLinkType.Tests));
16✔
77
                            }
16✔
78
                            unitTests.Add(test);
11✔
79
                        }
11✔
80
                        if (description.Type == TestType.SYSTEM)
26✔
81
                        {
15✔
82
                            var test = new SoftwareSystemTestItem();
15✔
83
                            test.ItemID = description.ID;
15✔
84
                            test.ItemProject = description.Project ?? string.Empty;
15✔
85
                            var testDescription = description.Description.ToUpper();
15✔
86
                            if (testDescription.Contains("GIVEN:") && testDescription.Contains("WHEN:") && testDescription.Contains("THEN:"))
15✔
87
                            {
6✔
88
                                var steps = SoftwareSystemTestItem.GetTestSteps(description.Description);
6✔
89
                                foreach (var step in steps)
50✔
90
                                {
16✔
91
                                    test.AddTestCaseStep(step);
16✔
92
                                }
16✔
93
                                test.TestCaseDescription = description.Name;
6✔
94
                            }
6✔
95
                            else
96
                            {
9✔
97
                                test.TestCaseDescription = description.Description;
9✔
98
                            }                                
9✔
99
                            test.TestCaseAutomated = true;
15✔
100
                            foreach (var trace in description.Trace)
85✔
101
                            {
20✔
102
                                test.AddLinkedItem(new ItemLink(trace, ItemLinkType.Tests));
20✔
103
                            }
20✔
104
                            testCases.Add(test);
15✔
105
                        }
15✔
106
                    }
26✔
107
                }
22✔
108
                catch (JsonException ex)
7✔
109
                {
7✔
110
                    logger.Error($"Error parsing or validating the test description file: {fileLocations[i]}");
7✔
111
                    logger.Error($"Validation error: {ex.Message}");
7✔
112
                    throw;
7✔
113
                }
NEW
114
                catch (Exception ex)
×
NEW
115
                {
×
NEW
116
                    logger.Error($"Unexpected error processing test description file: {fileLocations[i]}");
×
NEW
117
                    logger.Error(ex);
×
NEW
118
                    throw;
×
119
                }
120
            }
22✔
121
        }
10✔
122

123
        private void ValidateTestDescription(TestDescriptionJSONObject description, string fileName)
124
        {
29✔
125
            // Basic validation
126
            if (string.IsNullOrEmpty(description.ID))
29!
NEW
127
                throw new JsonException("The 'id' field is required for all test descriptions.");
×
128
            
129
            if (string.IsNullOrEmpty(description.Name))
29!
NEW
130
                throw new JsonException($"The 'name' field is required for all test descriptions. Test ID: {description.ID}");
×
131
            
132
            if (string.IsNullOrEmpty(description.Description))
29!
NEW
133
                throw new JsonException($"The 'description' field is required for all test descriptions. Test ID: {description.ID}");
×
134
            
135
            if (description.Trace == null || description.Trace.Count == 0)
29!
136
                throw new JsonException($"The 'trace' field is required and must contain at least one item. Test ID: {description.ID}");
1✔
137

138
            // Conditional validation based on test type
139
            if (description.Type == TestType.UNIT)
28✔
140
            {
13✔
141
                if (string.IsNullOrEmpty(description.Purpose))
13✔
142
                    throw new JsonException($"The 'purpose' field is required for UNIT test descriptions. Test ID: {description.ID}, Name: {description.Name}");
1✔
143
                
144
                if (string.IsNullOrEmpty(description.Acceptance))
12✔
145
                    throw new JsonException($"The 'acceptance' field is required for UNIT test descriptions. Test ID: {description.ID}, Name: {description.Name}");
1✔
146
            }
11✔
147
        }
26✔
148
    }
149
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc