|
15 | 15 | using System;
|
16 | 16 | using System.Collections.Generic;
|
17 | 17 | using System.Globalization;
|
18 |
| -using System.Linq; |
19 | 18 | using System.Numerics;
|
20 | 19 | using OnixLabs.Core.Linq;
|
21 | 20 | using OnixLabs.Core.UnitTests.Data;
|
@@ -107,6 +106,62 @@ public void CountNotShouldProduceExpectedResult()
|
107 | 106 | Assert.Equal(expected, actual);
|
108 | 107 | }
|
109 | 108 |
|
| 109 | + [Fact(DisplayName = "IEnumerable.FirstOrNone should return none when the enumerable is empty.")] |
| 110 | + public void FirstOrNoneShouldReturnNoneWhenEnumerableIsEmpty() |
| 111 | + { |
| 112 | + // Given |
| 113 | + IEnumerable<int> elements = []; |
| 114 | + Optional<int> expected = Optional<int>.None; |
| 115 | + |
| 116 | + // When |
| 117 | + Optional<int> actual = elements.FirstOrNone(); |
| 118 | + |
| 119 | + // Then |
| 120 | + Assert.Equal(expected, actual); |
| 121 | + } |
| 122 | + |
| 123 | + [Fact(DisplayName = "IEnumerable.FirstOrNone should return the first element when the collection is not empty.")] |
| 124 | + public void FirstOrNoneShouldReturnFirstElementWhenCollectionIsNotEmpty() |
| 125 | + { |
| 126 | + // Given |
| 127 | + IEnumerable<int> elements = [1, 2, 3]; |
| 128 | + Optional<int> expected = 1; |
| 129 | + |
| 130 | + // When |
| 131 | + Optional<int> actual = elements.FirstOrNone(); |
| 132 | + |
| 133 | + // Then |
| 134 | + Assert.Equal(expected, actual); |
| 135 | + } |
| 136 | + |
| 137 | + [Fact(DisplayName = "IEnumerable.FirstOrNone should return the first element matching the predicate when the collection is not empty.")] |
| 138 | + public void FirstOrNoneShouldReturnFirstElementMatchingPredicateWhenCollectionIsNotEmpty() |
| 139 | + { |
| 140 | + // Given |
| 141 | + IEnumerable<int> elements = [1, 2, 3]; |
| 142 | + Optional<int> expected = 2; |
| 143 | + |
| 144 | + // When |
| 145 | + Optional<int> actual = elements.FirstOrNone(number => number > 1); |
| 146 | + |
| 147 | + // Then |
| 148 | + Assert.Equal(expected, actual); |
| 149 | + } |
| 150 | + |
| 151 | + [Fact(DisplayName = "IEnumerable.FirstOrNone should return none when no element matches the predicate and the collection is not empty.")] |
| 152 | + public void FirstOrNoneShouldReturnNoneWhenNoElementMatchesPredicateAndCollectionIsNotEmpty() |
| 153 | + { |
| 154 | + // Given |
| 155 | + IEnumerable<int> elements = [1, 2, 3]; |
| 156 | + Optional<int> expected = Optional<int>.None; |
| 157 | + |
| 158 | + // When |
| 159 | + Optional<int> actual = elements.FirstOrNone(number => number > 3); |
| 160 | + |
| 161 | + // Then |
| 162 | + Assert.Equal(expected, actual); |
| 163 | + } |
| 164 | + |
110 | 165 | [Fact(DisplayName = "IEnumerable.ForEach should iterate over every element in the enumerable")]
|
111 | 166 | public void ForEachShouldProduceExpectedResult()
|
112 | 167 | {
|
@@ -321,6 +376,62 @@ public void JoinToStringShouldProduceExpectedResultWithCustomSeparator()
|
321 | 376 | Assert.Equal(expected, actual);
|
322 | 377 | }
|
323 | 378 |
|
| 379 | + [Fact(DisplayName = "IEnumerable.LastOrNone should return none when the enumerable is empty.")] |
| 380 | + public void LastOrNoneShouldReturnNoneWhenEnumerableIsEmpty() |
| 381 | + { |
| 382 | + // Given |
| 383 | + IEnumerable<int> elements = []; |
| 384 | + Optional<int> expected = Optional<int>.None; |
| 385 | + |
| 386 | + // When |
| 387 | + Optional<int> actual = elements.LastOrNone(); |
| 388 | + |
| 389 | + // Then |
| 390 | + Assert.Equal(expected, actual); |
| 391 | + } |
| 392 | + |
| 393 | + [Fact(DisplayName = "IEnumerable.LastOrNone should return the last element when the collection is not empty.")] |
| 394 | + public void LastOrNoneShouldReturnLastElementWhenCollectionIsNotEmpty() |
| 395 | + { |
| 396 | + // Given |
| 397 | + IEnumerable<int> elements = [1, 2, 3]; |
| 398 | + Optional<int> expected = 3; |
| 399 | + |
| 400 | + // When |
| 401 | + Optional<int> actual = elements.LastOrNone(); |
| 402 | + |
| 403 | + // Then |
| 404 | + Assert.Equal(expected, actual); |
| 405 | + } |
| 406 | + |
| 407 | + [Fact(DisplayName = "IEnumerable.LastOrNone should return the last element matching the predicate when the collection is not empty.")] |
| 408 | + public void LastOrNoneShouldReturnFirstElementMatchingPredicateWhenCollectionIsNotEmpty() |
| 409 | + { |
| 410 | + // Given |
| 411 | + IEnumerable<int> elements = [1, 2, 3]; |
| 412 | + Optional<int> expected = 3; |
| 413 | + |
| 414 | + // When |
| 415 | + Optional<int> actual = elements.LastOrNone(number => number > 1); |
| 416 | + |
| 417 | + // Then |
| 418 | + Assert.Equal(expected, actual); |
| 419 | + } |
| 420 | + |
| 421 | + [Fact(DisplayName = "IEnumerable.LastOrNone should return none when no element matches the predicate and the collection is not empty.")] |
| 422 | + public void LastOrNoneShouldReturnNoneWhenNoElementMatchesPredicateAndCollectionIsNotEmpty() |
| 423 | + { |
| 424 | + // Given |
| 425 | + IEnumerable<int> elements = [1, 2, 3]; |
| 426 | + Optional<int> expected = Optional<int>.None; |
| 427 | + |
| 428 | + // When |
| 429 | + Optional<int> actual = elements.LastOrNone(number => number > 3); |
| 430 | + |
| 431 | + // Then |
| 432 | + Assert.Equal(expected, actual); |
| 433 | + } |
| 434 | + |
324 | 435 | [Fact(DisplayName = "IEnumerable.None should return true when none of the elements satisfy the specified predicate condition")]
|
325 | 436 | public void NoneShouldProduceExpectedResultTrue()
|
326 | 437 | {
|
@@ -369,6 +480,96 @@ public void NoneShouldProduceExpectedResultFalseAll()
|
369 | 480 | Assert.False(result);
|
370 | 481 | }
|
371 | 482 |
|
| 483 | + [Fact(DisplayName = "IEnumerable.SingleOrNone should return success none when the enumerable contains no elements.")] |
| 484 | + public void SingleOrNoneShouldReturnSuccessNoneWhenEnumerableContainsNoElements() |
| 485 | + { |
| 486 | + // Given |
| 487 | + IEnumerable<int> elements = []; |
| 488 | + Result<Optional<int>> expected = Optional<int>.None.ToResult(); |
| 489 | + |
| 490 | + // When |
| 491 | + Result<Optional<int>> actual = elements.SingleOrNone(); |
| 492 | + |
| 493 | + // Then |
| 494 | + Assert.Equal(expected, actual); |
| 495 | + } |
| 496 | + |
| 497 | + [Fact(DisplayName = "IEnumerable.SingleOrNone should return success some when the enumerable contains a single element.")] |
| 498 | + public void SingleOrNoneShouldReturnSuccessSomeWhenEnumerableContainsSingleElement() |
| 499 | + { |
| 500 | + // Given |
| 501 | + IEnumerable<int> elements = [1]; |
| 502 | + Result<Optional<int>> expected = Optional<int>.Some(1).ToResult(); |
| 503 | + |
| 504 | + // When |
| 505 | + Result<Optional<int>> actual = elements.SingleOrNone(); |
| 506 | + |
| 507 | + // Then |
| 508 | + Assert.Equal(expected, actual); |
| 509 | + } |
| 510 | + |
| 511 | + [Fact(DisplayName = "IEnumerable.SingleOrNone should return failure when the enumerable contains more than one element.")] |
| 512 | + public void SingleOrNoneShouldReturnFailureSomeWhenEnumerableContainsMoreThanOneElement() |
| 513 | + { |
| 514 | + // Given |
| 515 | + IEnumerable<int> elements = [1, 2, 3]; |
| 516 | + Failure<Optional<int>> expected = Result<Optional<int>>.Failure(new InvalidOperationException("Sequence contains more than one matching element")); |
| 517 | + |
| 518 | + // When |
| 519 | + Result<Optional<int>> actual = elements.SingleOrNone(); |
| 520 | + Exception actualException = Assert.Throws<InvalidOperationException>(actual.Throw); |
| 521 | + |
| 522 | + // Then |
| 523 | + Assert.True(actual is Failure<Optional<int>>); |
| 524 | + Assert.Equal(expected.Exception.GetType(), actualException.GetType()); |
| 525 | + Assert.Equal(expected.Exception.Message, actualException.Message); |
| 526 | + } |
| 527 | + |
| 528 | + [Fact(DisplayName = "IEnumerable.SingleOrNone should return success none when the enumerable contains no elements matching the predicate.")] |
| 529 | + public void SingleOrNoneShouldReturnSuccessNoneWhenEnumerableContainsNoElementsMatchingPredicate() |
| 530 | + { |
| 531 | + // Given |
| 532 | + IEnumerable<int> elements = [1, 2, 3]; |
| 533 | + Result<Optional<int>> expected = Optional<int>.None.ToResult(); |
| 534 | + |
| 535 | + // When |
| 536 | + Result<Optional<int>> actual = elements.SingleOrNone(number => number > 3); |
| 537 | + |
| 538 | + // Then |
| 539 | + Assert.Equal(expected, actual); |
| 540 | + } |
| 541 | + |
| 542 | + [Fact(DisplayName = "IEnumerable.SingleOrNone should return success some when the enumerable contains a single element matching the predicate.")] |
| 543 | + public void SingleOrNoneShouldReturnSuccessSomeWhenEnumerableContainsSingleElementMatchingPredicate() |
| 544 | + { |
| 545 | + // Given |
| 546 | + IEnumerable<int> elements = [1, 2, 3]; |
| 547 | + Result<Optional<int>> expected = Optional<int>.Some(1).ToResult(); |
| 548 | + |
| 549 | + // When |
| 550 | + Result<Optional<int>> actual = elements.SingleOrNone(number => number < 2); |
| 551 | + |
| 552 | + // Then |
| 553 | + Assert.Equal(expected, actual); |
| 554 | + } |
| 555 | + |
| 556 | + [Fact(DisplayName = "IEnumerable.SingleOrNone should return failure when the enumerable contains more than one element matching the predicate.")] |
| 557 | + public void SingleOrNoneShouldReturnFailureSomeWhenEnumerableContainsMoreThanOneElementMatchingPredidate() |
| 558 | + { |
| 559 | + // Given |
| 560 | + IEnumerable<int> elements = [1, 2, 3]; |
| 561 | + Failure<Optional<int>> expected = Result<Optional<int>>.Failure(new InvalidOperationException("Sequence contains more than one matching element")); |
| 562 | + |
| 563 | + // When |
| 564 | + Result<Optional<int>> actual = elements.SingleOrNone(number => number > 1); |
| 565 | + Exception actualException = Assert.Throws<InvalidOperationException>(actual.Throw); |
| 566 | + |
| 567 | + // Then |
| 568 | + Assert.True(actual is Failure<Optional<int>>); |
| 569 | + Assert.Equal(expected.Exception.GetType(), actualException.GetType()); |
| 570 | + Assert.Equal(expected.Exception.Message, actualException.Message); |
| 571 | + } |
| 572 | + |
372 | 573 | [Fact(DisplayName = "IEnumerable.Sum should produce the expected result")]
|
373 | 574 | public void SumShouldProduceExpectedResult()
|
374 | 575 | {
|
|
0 commit comments