• 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

77.14
/src/DataManager/utils/TableView/core/TableViewBuilder.cpp
1
#include "TableViewBuilder.h"
2

3
#include "utils/TableView/adapters/DataManagerExtension.h"
4
#include "utils/TableView/interfaces/IColumnComputer.h"
5
#include "utils/TableView/interfaces/IMultiColumnComputer.h"
6
#include "utils/TableView/interfaces/IRowSelector.h"
7
#include "utils/TableView/interfaces/ILineSource.h"
8
#include "utils/TableView/interfaces/IPointSource.h"
9

10
#include <stdexcept>
11
#include <set>
12
#include <sstream>
13

14
TableViewBuilder::~TableViewBuilder() = default;
75✔
15

16
TableViewBuilder::TableViewBuilder(std::shared_ptr<DataManagerExtension> dataManager)
75✔
17
    : m_dataManager(std::move(dataManager)) {
75✔
18
    if (!m_dataManager) {
75✔
UNCOV
19
        throw std::invalid_argument("DataManagerExtension cannot be null");
×
20
    }
21
}
75✔
22

23
TableViewBuilder & TableViewBuilder::setRowSelector(std::unique_ptr<IRowSelector> rowSelector) {
75✔
24
    if (!rowSelector) {
75✔
UNCOV
25
        throw std::invalid_argument("IRowSelector cannot be null");
×
26
    }
27
    m_rowSelector = std::move(rowSelector);
75✔
28
    return *this;
75✔
29
}
30

31
TableViewBuilder & TableViewBuilder::addColumn(std::string const & name, std::unique_ptr<IColumnComputer<double>> computer) {
40✔
32
    if (name.empty()) {
40✔
UNCOV
33
        throw std::invalid_argument("Column name cannot be empty");
×
34
    }
35
    if (!computer) {
40✔
UNCOV
36
        throw std::invalid_argument("IColumnComputer cannot be null");
×
37
    }
38

39
    // Check for duplicate names
40
    for (auto const & column: m_columns) {
87✔
41
        if (column->getName() == name) {
47✔
UNCOV
42
            throw std::runtime_error("Column '" + name + "' already exists");
×
43
        }
44
    }
45

46
    // Create the double column
47
    auto column = std::shared_ptr<IColumn>(new Column<double>(name, std::move(computer)));
40✔
48
    m_columns.push_back(std::move(column));
40✔
49

50
    return *this;
40✔
51
}
40✔
52

53
TableView TableViewBuilder::build() {
75✔
54
    // Validate configuration
55
    if (!m_rowSelector) {
75✔
UNCOV
56
        throw std::runtime_error("Row selector must be set before building");
×
57
    }
58
    if (m_columns.empty()) {
75✔
UNCOV
59
        throw std::runtime_error("At least one column must be added before building");
×
60
    }
61

62
    // Validate multi-sample source constraints
63
    validateMultiSampleSources();
75✔
64

65
    // Create the TableView
66
    TableView tableView(std::move(m_rowSelector), m_dataManager);
72✔
67

68
    // Add columns to the table view
69
    for (auto & column: m_columns) {
327✔
70
        tableView.addColumn(std::move(column));
255✔
71
    }
72

73
    // Clear our state since we've moved everything
74
    m_columns.clear();
72✔
75
    m_rowSelector.reset();
72✔
76

77
    return tableView;
72✔
UNCOV
78
}
×
79

80
void TableViewBuilder::validateMultiSampleSources() {
75✔
81
    std::set<std::string> multiSampleSources;
75✔
82
    
83
    // Check each column for dependencies on multi-sample line sources
84
    for (auto const & column : m_columns) {
354✔
85
        // Get dependencies from the column's computer
86
        auto dependencies = column->getDependencies();
279✔
87
        
88
        for (auto const & dep : dependencies) {
279✔
89
            // Check if this dependency is a line source
NEW
90
            auto lineSource = m_dataManager->getLineSource(dep);
×
NEW
91
            if (lineSource && lineSource->hasMultiSamples()) {
×
NEW
92
                multiSampleSources.insert(dep);
×
93
            }
94
            
95
            // Check if this dependency is a point source
NEW
96
            auto pointSource = m_dataManager->getPointSource(dep);
×
NEW
97
            if (pointSource && pointSource->hasMultiSamples()) {
×
NEW
98
                multiSampleSources.insert(dep);
×
99
            }
NEW
100
        }
×
101
        
102
        // Also check the source dependency if it exists
103
        auto sourceDep = column->getSourceDependency();
279✔
104
        if (!sourceDep.empty()) {
279✔
105
            auto lineSource = m_dataManager->getLineSource(sourceDep);
279✔
106
            if (lineSource && lineSource->hasMultiSamples()) {
279✔
107
                multiSampleSources.insert(sourceDep);
90✔
108
            }
109
            
110
            auto pointSource = m_dataManager->getPointSource(sourceDep);
279✔
111
            if (pointSource && pointSource->hasMultiSamples()) {
279✔
NEW
112
                multiSampleSources.insert(sourceDep);
×
113
            }
114
        }
279✔
115
    }
279✔
116
    
117
    // If we have more than one multi-sample source, throw an error
118
    if (multiSampleSources.size() > 1) {
75✔
119
        std::ostringstream oss;
3✔
120
        oss << "Cannot build TableView with multiple multi-sample sources. "
121
            << "Entity expansion is undefined when multiple sources have multiple entities per timestamp. "
122
            << "Multi-sample sources detected: ";
3✔
123
        
124
        bool first = true;
3✔
125
        for (auto const & source : multiSampleSources) {
9✔
126
            if (!first) oss << ", ";
6✔
127
            oss << "'" << source << "'";
6✔
128
            first = false;
6✔
129
        }
130
        
131
        oss << ". Please ensure only one line or point source has multiple samples per timestamp.";
3✔
132
        
133
        throw std::runtime_error(oss.str());
3✔
134
    }
3✔
135
}
147✔
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