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

JaCraig / Archivist / 20796472236

07 Jan 2026 09:04PM UTC coverage: 77.884% (-1.0%) from 78.836%
20796472236

push

github

web-flow
Merge pull request #239 from JaCraig/dependabot/nuget/Archivist.OCR.Tests/dependencies-513ebfd917

chore: Bump the dependencies group with 1 update

2425 of 3412 branches covered (71.07%)

Branch coverage included in aggregate %.

3220 of 3836 relevant lines covered (83.94%)

7664.58 hits per line

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

89.56
/Archivist/DataTypes/TableRow.cs
1
using Archivist.Interfaces;
2
using ObjectCartographer;
3
using System;
4
using System.Collections;
5
using System.Collections.Generic;
6
using System.Dynamic;
7

8
namespace Archivist.DataTypes
9
{
10
    /// <summary>
11
    /// Represents a table row.
12
    /// </summary>
13
    public class TableRow : IComparable<TableRow>, IEquatable<TableRow>, IObjectConvertable, IList<TableCell>
14
    {
15
        /// <summary>
16
        /// Initializes a new instance of the <see cref="TableRow"/> class with the specified columns.
17
        /// </summary>
18
        /// <param name="columns">The list of column names.</param>
19
        public TableRow(List<string>? columns)
376,412✔
20
        {
21
            Columns = columns ?? new List<string>();
376,412✔
22
        }
376,412✔
23

24
        /// <summary>
25
        /// Gets the number of cells in the row.
26
        /// </summary>
27
        public int Count => Cells.Count;
162✔
28

29
        /// <summary>
30
        /// Gets a value indicating whether the row is read-only.
31
        /// </summary>
32
        public bool IsReadOnly => false;
2✔
33

34
        /// <summary>
35
        /// Gets the list of cells in the row.
36
        /// </summary>
37
        private List<TableCell> Cells { get; } = new List<TableCell>();
2,407,318✔
38

39
        /// <summary>
40
        /// Gets the list of column names.
41
        /// </summary>
42
        private List<string> Columns { get; }
103✔
43

44
        /// <summary>
45
        /// Gets or sets the cell at the specified index.
46
        /// </summary>
47
        /// <param name="index">The index of the cell.</param>
48
        /// <returns>The cell at the specified index.</returns>
49
        public TableCell this[int index]
50
        {
51
            get
52
            {
53
                if (index < 0 || index >= Count)
36✔
54
                    throw new ArgumentOutOfRangeException(nameof(index));
1✔
55
                return Cells[index];
35✔
56
            }
57
            set
58
            {
59
                if (index < 0 || index >= Count)
2✔
60
                    throw new ArgumentOutOfRangeException(nameof(index));
1✔
61
                Cells[index] = value;
1✔
62
            }
1✔
63
        }
64

65
        /// <summary>
66
        /// Gets or sets the cell with the specified column name.
67
        /// </summary>
68
        /// <param name="column">The name of the column.</param>
69
        /// <returns>The cell with the specified column name.</returns>
70
        public TableCell this[string column]
71
        {
72
            get
73
            {
74
                var ColumnIndex = Columns.IndexOf(column);
86✔
75
                if (ColumnIndex == -1)
86✔
76
                    throw new ArgumentOutOfRangeException(nameof(column));
1✔
77
                return Cells[ColumnIndex];
85✔
78
            }
79
            set
80
            {
81
                var ColumnIndex = Columns.IndexOf(column);
2✔
82
                if (ColumnIndex == -1)
2✔
83
                    throw new ArgumentOutOfRangeException(nameof(column));
1✔
84
                Cells[ColumnIndex] = value;
1✔
85
            }
1✔
86
        }
87

88
        /// <summary>
89
        /// Determines whether two <see cref="TableRow"/> objects are not equal.
90
        /// </summary>
91
        /// <param name="left">The first <see cref="TableRow"/> to compare.</param>
92
        /// <param name="right">The second <see cref="TableRow"/> to compare.</param>
93
        /// <returns>
94
        /// <c>true</c> if the two <see cref="TableRow"/> objects are not equal; otherwise, <c>false</c>.
95
        /// </returns>
96
        public static bool operator !=(TableRow? left, TableRow? right)
97
        {
98
            return !(left == right);
6✔
99
        }
100

101
        /// <summary>
102
        /// Determines whether the first <see cref="TableRow"/> is less than the second <see cref="TableRow"/>.
103
        /// </summary>
104
        /// <param name="left">The first <see cref="TableRow"/> to compare.</param>
105
        /// <param name="right">The second <see cref="TableRow"/> to compare.</param>
106
        /// <returns>
107
        /// <c>true</c> if the first <see cref="TableRow"/> is less than the second <see
108
        /// cref="TableRow"/>; otherwise, <c>false</c>.
109
        /// </returns>
110
        public static bool operator <(TableRow? left, TableRow? right)
111
        {
112
            return left is null ? right is not null : left.CompareTo(right) < 0;
4✔
113
        }
114

115
        /// <summary>
116
        /// Determines whether the first <see cref="TableRow"/> is less than or equal to the second
117
        /// <see cref="TableRow"/>.
118
        /// </summary>
119
        /// <param name="left">The first <see cref="TableRow"/> to compare.</param>
120
        /// <param name="right">The second <see cref="TableRow"/> to compare.</param>
121
        /// <returns>
122
        /// <c>true</c> if the first <see cref="TableRow"/> is less than or equal to the second <see
123
        /// cref="TableRow"/>; otherwise, <c>false</c>.
124
        /// </returns>
125
        public static bool operator <=(TableRow? left, TableRow? right)
126
        {
127
            return left is null || left.CompareTo(right) <= 0;
4✔
128
        }
129

130
        /// <summary>
131
        /// Determines whether two <see cref="TableRow"/> objects are equal.
132
        /// </summary>
133
        /// <param name="left">The first <see cref="TableRow"/> to compare.</param>
134
        /// <param name="right">The second <see cref="TableRow"/> to compare.</param>
135
        /// <returns>
136
        /// <c>true</c> if the two <see cref="TableRow"/> objects are equal; otherwise, <c>false</c>.
137
        /// </returns>
138
        public static bool operator ==(TableRow? left, TableRow? right)
139
        {
140
            if (left is null)
12✔
141
                return right is null;
4✔
142
            return left.Equals(right);
8✔
143
        }
144

145
        /// <summary>
146
        /// Determines whether the first <see cref="TableRow"/> is greater than the second <see cref="TableRow"/>.
147
        /// </summary>
148
        /// <param name="left">The first <see cref="TableRow"/> to compare.</param>
149
        /// <param name="right">The second <see cref="TableRow"/> to compare.</param>
150
        /// <returns>
151
        /// <c>true</c> if the first <see cref="TableRow"/> is greater than the second <see
152
        /// cref="TableRow"/>; otherwise, <c>false</c>.
153
        /// </returns>
154
        public static bool operator >(TableRow? left, TableRow? right)
155
        {
156
            return left?.CompareTo(right) > 0;
4✔
157
        }
158

159
        /// <summary>
160
        /// Determines whether the first <see cref="TableRow"/> is greater than or equal to the
161
        /// second <see cref="TableRow"/>.
162
        /// </summary>
163
        /// <param name="left">The first <see cref="TableRow"/> to compare.</param>
164
        /// <param name="right">The second <see cref="TableRow"/> to compare.</param>
165
        /// <returns>
166
        /// <c>true</c> if the first <see cref="TableRow"/> is greater than or equal to the second
167
        /// <see cref="TableRow"/>; otherwise, <c>false</c>.
168
        /// </returns>
169
        public static bool operator >=(TableRow? left, TableRow? right)
170
        {
171
            return left is null ? right is null : left.CompareTo(right) >= 0;
4✔
172
        }
173

174
        /// <summary>
175
        /// Adds a cell to the row.
176
        /// </summary>
177
        /// <param name="item">The cell to add.</param>
178
        public void Add(TableCell? item) => Cells.Add(item ?? new TableCell(""));
122,537✔
179

180
        /// <summary>
181
        /// Adds a cell to the row with the specified content.
182
        /// </summary>
183
        /// <param name="item">The content of the cell to add.</param>
184
        public void Add(string? item) => Add(new TableCell(item));
122,510✔
185

186
        /// <summary>
187
        /// Adds a list of cells to the row.
188
        /// </summary>
189
        /// <param name="collection">The list of cells to add.</param>
190
        public void AddRange(IEnumerable<TableCell> collection) => Cells.AddRange(collection ?? Array.Empty<TableCell>());
3✔
191

192
        /// <summary>
193
        /// Adds a list of cells to the row with the specified content.
194
        /// </summary>
195
        /// <param name="collection">The list of content to add.</param>
196
        public void AddRange(IEnumerable<string> collection)
197
        {
198
            if (collection is null)
6✔
199
                return;
1✔
200
            foreach (var Item in collection)
36✔
201
                Add(Item);
13✔
202
        }
5✔
203

204
        /// <summary>
205
        /// Removes all cells from the row.
206
        /// </summary>
207
        public void Clear() => Cells.Clear();
2✔
208

209
        /// <summary>
210
        /// Compares the current <see cref="TableRow"/> with another <see cref="TableRow"/> and
211
        /// returns an integer that indicates whether the current <see cref="TableRow"/> precedes,
212
        /// follows, or occurs in the same position in the sort order as the other <see cref="TableRow"/>.
213
        /// </summary>
214
        /// <param name="other">The <see cref="TableRow"/> to compare with the current <see cref="TableRow"/>.</param>
215
        /// <returns>A value that indicates the relative order of the objects being compared.</returns>
216
        public int CompareTo(TableRow? other)
217
        {
218
            if (other is null)
29✔
219
                return 1;
5✔
220
            if (other.Count != Count)
24!
221
                return Count.CompareTo(other.Count);
×
222
            for (var X = 0; X < Count; ++X)
118✔
223
            {
224
                var TempValue = Cells[X].CompareTo(other.Cells[X]);
41✔
225
                if (TempValue != 0)
41✔
226
                    return TempValue;
6✔
227
            }
228
            return 0;
18✔
229
        }
230

231
        /// <summary>
232
        /// Determines whether the row contains a specific cell.
233
        /// </summary>
234
        /// <param name="item">The cell to locate in the row.</param>
235
        /// <returns><c>true</c> if the cell is found in the row; otherwise, <c>false</c>.</returns>
236
        public bool Contains(TableCell? item) => item is not null && Cells.Contains(item);
3✔
237

238
        /// <summary>
239
        /// Copies the object to the row.
240
        /// </summary>
241
        /// <typeparam name="TObject">The object type</typeparam>
242
        /// <param name="obj">The object to copy.</param>
243
        public void ConvertFrom<TObject>(TObject obj)
244
        {
245
            Cells.Clear();
6✔
246
            if (obj is null)
6✔
247
                return;
1✔
248
            foreach (System.Reflection.PropertyInfo Property in obj.GetType().GetProperties())
24✔
249
            {
250
                var ColumnIndex = Columns.IndexOf(Property.Name);
7✔
251
                if (ColumnIndex == -1)
7!
252
                {
253
                    Columns.Add(Property.Name);
×
254
                    _ = Columns.Count - 1;
×
255
                }
256
                Cells.Add(new TableCell(Property.GetValue(obj)?.ToString() ?? ""));
7!
257
            }
258
        }
5✔
259

260
        /// <summary>
261
        /// Converts the current <see cref="TableRow"/> to an object array of the specified type.
262
        /// </summary>
263
        /// <typeparam name="TObject">The type of the object.</typeparam>
264
        /// <returns>The resulting array.</returns>
265
        public TObject ConvertTo<TObject>()
266
        {
267
            IDictionary<string, object?> TempValue = new ExpandoObject();
5✔
268
            for (var Y = 0; Y < Cells.Count; ++Y)
18✔
269
            {
270
                var ColumnName = Columns.Count > Y ? Columns[Y] : Y.ToString();
4!
271
                TempValue[ColumnName] = Cells[Y].Content;
4✔
272
            }
273
            return TempValue.To<TObject>();
5✔
274
        }
275

276
        /// <summary>
277
        /// Copies the elements of the row to an array, starting at a particular array index.
278
        /// </summary>
279
        /// <param name="array">
280
        /// The one-dimensional array that is the destination of the elements copied from the row.
281
        /// </param>
282
        /// <param name="arrayIndex">
283
        /// The zero-based index in <paramref name="array"/> at which copying begins.
284
        /// </param>
285
        public void CopyTo(TableCell[]? array, int arrayIndex)
286
        {
287
            if (array is null || array.Length == 0)
3✔
288
                return;
2✔
289
            if (arrayIndex < 0 || arrayIndex >= array.Length)
1!
290
                throw new ArgumentOutOfRangeException(nameof(arrayIndex));
×
291
            Cells.CopyTo(array, arrayIndex);
1✔
292
        }
1✔
293

294
        /// <summary>
295
        /// Determines whether the current <see cref="TableRow"/> is equal to another <see cref="TableRow"/>.
296
        /// </summary>
297
        /// <param name="other">The <see cref="TableRow"/> to compare with the current <see cref="TableRow"/>.</param>
298
        /// <returns>
299
        /// <c>true</c> if the two <see cref="TableRow"/> objects are equal; otherwise, <c>false</c>.
300
        /// </returns>
301
        public bool Equals(TableRow? other) => other is not null && CompareTo(other) == 0;
19✔
302

303
        /// <summary>
304
        /// Determines whether the current <see cref="TableRow"/> is equal to another object.
305
        /// </summary>
306
        /// <param name="obj">The object to compare with the current <see cref="TableRow"/>.</param>
307
        /// <returns>
308
        /// <c>true</c> if the object is a <see cref="TableRow"/> and is equal to the current <see
309
        /// cref="TableRow"/>; otherwise, <c>false</c>.
310
        /// </returns>
311
        public override bool Equals(object? obj)
312
        {
313
            if (ReferenceEquals(this, obj))
6!
314
                return true;
×
315
            if (obj is null)
6✔
316
                return false;
2✔
317
            return obj is TableRow TableRowObject && Equals(TableRowObject);
4✔
318
        }
319

320
        /// <summary>
321
        /// Returns an enumerator that iterates through the cells in the row.
322
        /// </summary>
323
        /// <returns>An enumerator that can be used to iterate through the cells in the row.</returns>
324
        public IEnumerator GetEnumerator() => Cells.GetEnumerator();
7,344✔
325

326
        /// <summary>
327
        /// Returns the enumerator that iterates through the cells in the row.
328
        /// </summary>
329
        /// <returns>An enumerator that can be used to iterate through the cells in the row.</returns>
330
        IEnumerator<TableCell> IEnumerable<TableCell>.GetEnumerator() => Cells.GetEnumerator();
1,887,937✔
331

332
        /// <summary>
333
        /// Returns the hash code for the row.
334
        /// </summary>
335
        /// <returns>A 32-bit signed integer hash code.</returns>
336
        public override int GetHashCode()
337
        {
338
            var HashCode = new HashCode();
14✔
339
            foreach (TableCell Cell in Cells)
52✔
340
                HashCode.Add(Cell);
12✔
341
            return HashCode.ToHashCode();
14✔
342
        }
343

344
        /// <summary>
345
        /// Searches for the specified cell and returns the zero-based index of the first occurrence
346
        /// within the entire row.
347
        /// </summary>
348
        /// <param name="item">The cell to locate in the row.</param>
349
        /// <returns>
350
        /// The zero-based index of the first occurrence of the cell within the entire row, if
351
        /// found; otherwise, -1.
352
        /// </returns>
353
        public int IndexOf(TableCell? item) => Cells.IndexOf(item ?? TableCell.Empty);
3✔
354

355
        /// <summary>
356
        /// Inserts a cell into the row at the specified index.
357
        /// </summary>
358
        /// <param name="index">The zero-based index at which the cell should be inserted.</param>
359
        /// <param name="item">The cell to insert into the row.</param>
360
        public void Insert(int index, TableCell? item)
361
        {
362
            if (index < 0 || index > Count)
3!
363
                throw new ArgumentOutOfRangeException(nameof(index));
×
364
            Cells.Insert(index, item ?? new TableCell(""));
3✔
365
        }
3✔
366

367
        /// <summary>
368
        /// Removes the first occurrence of a specific cell from the row.
369
        /// </summary>
370
        /// <param name="item">The cell to remove from the row.</param>
371
        /// <returns><c>true</c> if the cell is successfully removed; otherwise, <c>false</c>.</returns>
372
        public bool Remove(TableCell? item) => item is not null && Cells.Remove(item);
3✔
373

374
        /// <summary>
375
        /// Removes the cell at the specified index from the row.
376
        /// </summary>
377
        /// <param name="index">The zero-based index of the cell to remove.</param>
378
        public void RemoveAt(int index)
379
        {
380
            if (index < 0 || index >= Count)
2!
381
                return;
×
382
            Cells.RemoveAt(index);
2✔
383
        }
2✔
384

385
        /// <summary>
386
        /// Returns a string that represents the row.
387
        /// </summary>
388
        /// <returns>A string that represents the row.</returns>
389
        public override string ToString() => string.Join(' ', Cells);
12,666✔
390
    }
391
}
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