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

paulmthompson / WhiskerToolbox / 17270491352

27 Aug 2025 02:57PM UTC coverage: 65.333%. Remained the same
17270491352

push

github

paulmthompson
Merge branch 'main' of https://github.com/paulmthompson/WhiskerToolbox

352 of 628 new or added lines in 92 files covered. (56.05%)

357 existing lines in 24 files now uncovered.

26429 of 40453 relevant lines covered (65.33%)

1119.34 hits per line

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

58.14
/src/DataManager/IO/loaders/CSVLoader.cpp
1
#include "CSVLoader.hpp"
2

3
#include "Lines/IO/CSV/Line_Data_CSV.hpp"
4
#include "Lines/Line_Data.hpp"
5
#include "utils/json_helpers.hpp"
6

7
#include <iostream>
8

9
LoadResult CSVLoader::load(std::string const& filepath, 
2✔
10
                          IODataType dataType, 
11
                          nlohmann::json const& config, 
12
                          DataFactory* factory) const {
13
    if (!factory) {
2✔
14
        return LoadResult("DataFactory is null");
×
15
    }
16

17
    switch (dataType) {
2✔
18
        case IODataType::Line:
2✔
19
            return loadLineDataCSV(filepath, config, factory);
2✔
20
            
21
        default:
×
22
            return LoadResult("CSV loader does not support data type: " + std::to_string(static_cast<int>(dataType)));
×
23
    }
24
}
25

26
bool CSVLoader::supportsFormat(std::string const& format, IODataType dataType) const {
26✔
27
    // Support CSV format for LineData
28
    if (format == "csv" && dataType == IODataType::Line) {
26✔
29
        return true;
6✔
30
    }
31
    
32
    // Could add support for other data types in the future
33
    return false;
20✔
34
}
35

36
LoadResult CSVLoader::save(std::string const& filepath,
1✔
37
                           IODataType dataType,
38
                           nlohmann::json const& config,
39
                           void const* data) const {
40
    static_cast<void>(filepath);
41
    if (dataType != IODataType::Line) {
1✔
UNCOV
42
        return LoadResult("CSVLoader only supports saving LineData");
×
43
    }
44

45
    if (!data) {
1✔
UNCOV
46
        return LoadResult("Data pointer is null");
×
47
    }
48

49
    try {
50
        // Cast void pointer back to LineData
51
        auto const* line_data = static_cast<LineData const*>(data);
1✔
52

53
        // Check if it's single-file or multi-file format
54
        std::string save_type = config.value("save_type", "single");
1✔
55

56
        if (save_type == "single") {
1✔
57
            // Convert JSON config to CSVSingleFileLineSaverOptions
58
            CSVSingleFileLineSaverOptions save_opts;
1✔
59
            save_opts.parent_dir = config.value("parent_dir", ".");
1✔
60
            save_opts.filename = config.value("filename", "line_data.csv");
1✔
61
            save_opts.delimiter = config.value("delimiter", ",");
1✔
62
            save_opts.line_delim = config.value("line_delim", "\n");
1✔
63
            save_opts.save_header = config.value("save_header", true);
1✔
64
            save_opts.header = config.value("header", "Frame,X,Y");
1✔
65
            save_opts.precision = config.value("precision", 1);
1✔
66

67
            // Call the existing save function
68
            ::save(line_data, save_opts);
1✔
69

70
        } else if (save_type == "multi") {
1✔
71
            // Convert JSON config to CSVMultiFileLineSaverOptions
UNCOV
72
            CSVMultiFileLineSaverOptions save_opts;
×
73
            save_opts.parent_dir = config.value("parent_dir", ".");
×
74
            save_opts.delimiter = config.value("delimiter", ",");
×
75
            save_opts.line_delim = config.value("line_delim", "\n");
×
76
            save_opts.save_header = config.value("save_header", true);
×
77
            save_opts.header = config.value("header", "X,Y");
×
78
            save_opts.precision = config.value("precision", 1);
×
79
            save_opts.frame_id_padding = config.value("frame_id_padding", 7);
×
80
            save_opts.overwrite_existing = config.value("overwrite_existing", false);
×
81

82
            // Call the existing save function
UNCOV
83
            ::save(line_data, save_opts);
×
84

UNCOV
85
        } else {
×
86
            return LoadResult("Unsupported CSV save_type: " + save_type + ". Use 'single' or 'multi'");
×
87
        }
88

89
        // Return success - use default constructor which sets success=true by default
90
        LoadResult result;
1✔
91
        result.success = true;
1✔
92
        return result;
1✔
93

94
    } catch (std::exception const& e) {
1✔
UNCOV
95
        return LoadResult("CSVLoader save failed: " + std::string(e.what()));
×
UNCOV
96
    }
×
97
}
98

99
std::string CSVLoader::getLoaderName() const {
96✔
100
    return "CSVLoader (Internal)";
288✔
101
}
102

103
LoadResult CSVLoader::loadLineDataCSV(std::string const& filepath, 
2✔
104
                                     nlohmann::json const& config, 
105
                                     DataFactory* factory) const {
106
    try {
107
        std::map<TimeFrameIndex, std::vector<Line2D>> line_map;
2✔
108
        
109
        if (config.contains("multi_file") && config["multi_file"] == true) {
2✔
110
            // Multi-file CSV loading
UNCOV
111
            CSVMultiFileLineLoaderOptions opts;
×
UNCOV
112
            opts.parent_dir = filepath;
×
113
            
UNCOV
114
            if (config.contains("delimiter")) {
×
115
                opts.delimiter = config["delimiter"];
×
116
            }
UNCOV
117
            if (config.contains("x_column")) {
×
118
                opts.x_column = config["x_column"];
×
119
            }
UNCOV
120
            if (config.contains("y_column")) {
×
121
                opts.y_column = config["y_column"];
×
122
            }
UNCOV
123
            if (config.contains("has_header")) {
×
124
                opts.has_header = config["has_header"];
×
125
            }
126
            
127
            line_map = ::load(opts);
×
128
        } else {
×
129
            // Single-file CSV loading
130
            CSVSingleFileLineLoaderOptions opts;
2✔
131
            opts.filepath = filepath;
2✔
132
            
133
            if (config.contains("delimiter")) {
2✔
134
                opts.delimiter = config["delimiter"];
2✔
135
            }
136
            if (config.contains("coordinate_delimiter")) {
2✔
137
                opts.coordinate_delimiter = config["coordinate_delimiter"];
2✔
138
            }
139
            if (config.contains("has_header")) {
2✔
140
                opts.has_header = config["has_header"];
2✔
141
            }
142
            if (config.contains("header_identifier")) {
2✔
143
                opts.header_identifier = config["header_identifier"];
2✔
144
            }
145
            
146
            line_map = ::load(opts);
2✔
147
        }
2✔
148
        
149
        // Create LineData using factory
150
        auto line_data_variant = factory->createLineData(line_map);
2✔
151
        
152
        // Apply image size if specified in config
153
        if (config.contains("image_width") && config.contains("image_height")) {
2✔
UNCOV
154
            int width = config["image_width"];
×
UNCOV
155
            int height = config["image_height"];
×
UNCOV
156
            factory->setLineDataImageSize(line_data_variant, width, height);
×
157
        }
158
        
159
        return LoadResult(std::move(line_data_variant));
2✔
160
        
161
    } catch (std::exception const& e) {
2✔
UNCOV
162
        return LoadResult("CSV loading failed: " + std::string(e.what()));
×
UNCOV
163
    }
×
164
}
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