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

GothenburgBitFactory / taskwarrior / 10152339701

29 Jul 2024 09:45PM UTC coverage: 84.437% (+0.07%) from 84.372%
10152339701

push

github

web-flow
Merge pull request #3566 from felixschurk/add-clang-format

Add clang-format to enforce style guide

12359 of 13760 new or added lines in 147 files covered. (89.82%)

123 existing lines in 42 files now uncovered.

19070 of 22585 relevant lines covered (84.44%)

19724.02 hits per line

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

99.03
/src/columns/ColTypeDate.cpp
1
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2006 - 2021, Tomas Babej, Paul Beckingham, Federico Hernandez.
4
//
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included
13
// in all copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
// SOFTWARE.
22
//
23
// https://www.opensource.org/licenses/mit-license.php
24
//
25
////////////////////////////////////////////////////////////////////////////////
26

27
#include <cmake.h>
28
// cmake.h include header must come first
29

30
#include <ColTypeDate.h>
31
#include <Context.h>
32
#include <Datetime.h>
33
#include <Duration.h>
34
#include <Eval.h>
35
#include <Filter.h>
36
#include <Variant.h>
37
#include <format.h>
38

39
////////////////////////////////////////////////////////////////////////////////
40
ColumnTypeDate::ColumnTypeDate() {
38,106✔
41
  _name = "";
38,106✔
42
  _type = "date";
38,106✔
43
  _style = "formatted";
38,106✔
44
  _label = "";
38,106✔
45
  _styles = {"formatted", "julian", "epoch", "iso", "age", "relative", "remaining", "countdown"};
342,954✔
46

47
  Datetime now;
38,106✔
48
  now -= 125;  // So that "age" is non-zero.
38,106✔
49
  _examples = {now.toString(Context::getContext().config.get("dateformat")),
533,484✔
50
               format(now.toJulian(), 13, 12),
51
               now.toEpochString(),
52
               now.toISO(),
53
               Duration(Datetime() - now).formatVague(true),
38,106✔
54
               '-' + Duration(Datetime() - now).formatVague(true),
76,212✔
55
               "",
56
               Duration(Datetime() - now).format()};
419,166✔
57
}
38,106✔
58

59
////////////////////////////////////////////////////////////////////////////////
60
// Set the minimum and maximum widths for the value.
61
void ColumnTypeDate::measure(Task& task, unsigned int& minimum, unsigned int& maximum) {
4,670✔
62
  minimum = maximum = 0;
4,670✔
63
  if (task.has(_name)) {
4,670✔
64
    Datetime date(task.get_date(_name));
1,326✔
65

66
    if (_style == "default" || _style == "formatted") {
1,326✔
67
      // Determine the output date format, which uses a hierarchy of definitions.
68
      //   rc.report.<report>.dateformat
69
      //   rc.dateformat.report
70
      //   rc.dateformat.
71
      std::string format = Context::getContext().config.get("report." + _report + ".dateformat");
724✔
72
      if (format == "") format = Context::getContext().config.get("dateformat.report");
362✔
73
      if (format == "") format = Context::getContext().config.get("dateformat");
362✔
74

75
      minimum = maximum = Datetime::length(format);
362✔
76
    } else if (_style == "countdown") {
1,326✔
77
      Datetime now;
84✔
78
      minimum = maximum = Duration(date - now).formatVague(true).length();
84✔
79
    } else if (_style == "julian") {
880✔
80
      minimum = maximum = format(date.toJulian(), 13, 12).length();
2✔
81
    } else if (_style == "epoch") {
878✔
82
      minimum = maximum = date.toEpochString().length();
2✔
83
    } else if (_style == "iso") {
876✔
84
      minimum = maximum = date.toISO().length();
2✔
85
    } else if (_style == "age") {
874✔
86
      Datetime now;
820✔
87
      if (now > date)
820✔
88
        minimum = maximum = Duration(now - date).formatVague(true).length();
466✔
89
      else
90
        minimum = maximum = Duration(date - now).formatVague(true).length() + 1;
354✔
91
    } else if (_style == "relative") {
54✔
92
      Datetime now;
19✔
93
      if (now < date)
19✔
94
        minimum = maximum = Duration(date - now).formatVague(true).length();
9✔
95
      else
96
        minimum = maximum = Duration(now - date).formatVague(true).length() + 1;
10✔
97
    } else if (_style == "remaining") {
35✔
98
      Datetime now;
35✔
99
      if (date > now) minimum = maximum = Duration(date - now).formatVague(true).length();
35✔
100
    }
101
  }
102
}
4,670✔
103

104
////////////////////////////////////////////////////////////////////////////////
105
void ColumnTypeDate::render(std::vector<std::string>& lines, Task& task, int width, Color& color) {
1,717✔
106
  if (task.has(_name)) {
1,717✔
107
    Datetime date(task.get_date(_name));
1,307✔
108

109
    if (_style == "default" || _style == "formatted") {
1,307✔
110
      // Determine the output date format, which uses a hierarchy of definitions.
111
      //   rc.report.<report>.dateformat
112
      //   rc.dateformat.report
113
      //   rc.dateformat
114
      std::string format = Context::getContext().config.get("report." + _report + ".dateformat");
724✔
115
      if (format == "") {
362✔
116
        format = Context::getContext().config.get("dateformat.report");
343✔
117
        if (format == "") format = Context::getContext().config.get("dateformat");
343✔
118
      }
119

120
      renderStringLeft(lines, width, color, date.toString(format));
362✔
121
    } else if (_style == "countdown") {
1,307✔
122
      Datetime now;
68✔
123
      renderStringRight(lines, width, color, Duration(date - now).formatVague(true));
68✔
124
    } else if (_style == "julian")
877✔
125
      renderStringRight(lines, width, color, format(date.toJulian(), 13, 12));
2✔
126

127
    else if (_style == "epoch")
875✔
128
      renderStringRight(lines, width, color, date.toEpochString());
2✔
129

130
    else if (_style == "iso")
873✔
131
      renderStringLeft(lines, width, color, date.toISO());
2✔
132

133
    else if (_style == "age") {
871✔
134
      Datetime now;
820✔
135
      if (now > date)
820✔
136
        renderStringRight(lines, width, color, Duration(now - date).formatVague(true));
466✔
137
      else
138
        renderStringRight(lines, width, color, '-' + Duration(date - now).formatVague(true));
354✔
139
    } else if (_style == "relative") {
51✔
140
      Datetime now;
19✔
141
      if (now < date)
19✔
142
        renderStringRight(lines, width, color, Duration(date - now).formatVague(true));
9✔
143
      else
144
        renderStringRight(lines, width, color, '-' + Duration(now - date).formatVague(true));
10✔
145
    }
146

147
    else if (_style == "remaining") {
32✔
148
      Datetime now;
32✔
149
      if (date > now)
32✔
150
        renderStringRight(lines, width, color, Duration(date - now).formatVague(true));
31✔
151
    }
152
  }
153
}
1,717✔
154

155
////////////////////////////////////////////////////////////////////////////////
156
bool ColumnTypeDate::validate(const std::string& input) const {
9✔
157
  return input.length() ? true : false;
9✔
158
}
159

160
////////////////////////////////////////////////////////////////////////////////
161
void ColumnTypeDate::modify(Task& task, const std::string& value) {
724✔
162
  // Try to evaluate 'value'.  It might work.
163
  Variant evaluatedValue;
724✔
164
  try {
165
    Eval e;
724✔
166
    e.addSource(domSource);
724✔
167
    e.evaluateInfixExpression(value, evaluatedValue);
724✔
168
  }
724✔
169

170
  catch (...) {
124✔
171
    evaluatedValue = Variant(value);
124✔
172
  }
124✔
173

174
  // If v is duration, we need to convert it to date (and implicitly add now),
175
  // else store as date.
176
  std::string label = "   [1;37;43mMODIFICATION [0m ";
724✔
177
  if (evaluatedValue.type() == Variant::type_duration) {
724✔
178
    Context::getContext().debug(label + _name + " <-- '" +
248✔
179
                                format("{1}", format(evaluatedValue.get_duration())) + "' <-- '" +
248✔
180
                                (std::string)evaluatedValue + "' <-- '" + value + '\'');
248✔
181
    evaluatedValue.cast(Variant::type_date);
62✔
182
  } else {
183
    evaluatedValue.cast(Variant::type_date);
662✔
184
    Context::getContext().debug(label + _name + " <-- '" +
1,112✔
185
                                format("{1}", evaluatedValue.get_date()) + "' <-- '" +
1,112✔
186
                                (std::string)evaluatedValue + "' <-- '" + value + '\'');
1,112✔
187
  }
188

189
  // If a date doesn't parse (2/29/2014) then it evaluates to zero.
190
  if (value != "" && evaluatedValue.get_date() == 0)
340✔
NEW
191
    throw format("'{1}' is not a valid date in the '{2}' format.", value, Variant::dateFormat);
×
192

193
  task.set(_name, evaluatedValue.get_date());
340✔
194
}
1,108✔
195

196
////////////////////////////////////////////////////////////////////////////////
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

© 2025 Coveralls, Inc