-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
167 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# This workflow will build a .NET project | ||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net | ||
|
||
name: 'dotnet.yml' | ||
|
||
on: | ||
push: | ||
branches: [ "dev" ] | ||
paths-ignore: | ||
- 'docs/**' | ||
- '**/*.md' | ||
pull_request: | ||
branches: [ "dev" ] | ||
|
||
jobs: | ||
net8: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Setup .NET 8. | ||
uses: actions/setup-dotnet@v4 | ||
with: | ||
dotnet-version: '8.0.x' | ||
- name: Restore dependencies | ||
run: dotnet restore | ||
- name: Build | ||
run: dotnet build --configuration Release --no-restore | ||
- name: Run tests | ||
run: dotnet test --framework net8.0 --configuration Release --no-build --verbosity normal | ||
|
||
net462: | ||
runs-on: windows-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Setup .NET Framework | ||
uses: microsoft/setup-msbuild@v2 | ||
- name: Build | ||
run: msbuild test/HtmlToOpenXml.Tests/HtmlToOpenXml.Tests.csproj /p:Configuration=Release /p:TargetFramework=net462 /restore | ||
- name: Setup VSTest | ||
uses: darenm/[email protected] | ||
- name: Run tests (NET Framework) | ||
run: vstest.console.exe test\HtmlToOpenXml.Tests\bin\Release\net462\HtmlToOpenXml.Tests.dll /parallel |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
test/HtmlToOpenXml.Tests/Utilities/CollectionExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace System.Linq; | ||
|
||
#if NET462 | ||
|
||
/// <summary> | ||
/// Helper class that provide some extension methods to <see cref="IEnumerable{T}"/> API. | ||
/// </summary> | ||
static class CollectionExtensions | ||
{ | ||
/// <summary> | ||
/// Attempts to add the specified key and value to the dictionary. | ||
/// </summary> | ||
/// <param name="dictionary">The dictionary in which to insert the item.</param> | ||
/// <param name="key">The key of the element to add.</param> | ||
/// <param name="value">The value of the element to add. It can be <see langword="null"/>.</param> | ||
/// <returns><see langword="true"/> if the key/value pair was added to the dictionary successfully; otherwise, <see langword="false"/>.</returns> | ||
/// <summary>Returns the maximum value in a generic sequence according to a specified key selector function.</summary> | ||
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> | ||
/// <typeparam name="TKey">The type of key to compare elements by.</typeparam> | ||
/// <param name="source">A sequence of values to determine the maximum value of.</param> | ||
/// <param name="keySelector">A function to extract the key for each element.</param> | ||
/// <param name="comparer">The <see cref="IComparer{TKey}" /> to compare keys.</param> | ||
/// <returns>The value with the maximum key in the sequence.</returns> | ||
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception> | ||
/// <exception cref="ArgumentException">No key extracted from <paramref name="source" /> implements the <see cref="IComparable" /> or <see cref="IComparable{TKey}" /> interface.</exception> | ||
/// <remarks> | ||
/// <para>If <typeparamref name="TKey" /> is a reference type and the source sequence is empty or contains only values that are <see langword="null" />, this method returns <see langword="null" />.</para> | ||
/// </remarks> | ||
public static TSource MaxBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) | ||
{ | ||
if (source == null) | ||
throw new ArgumentNullException(nameof(source)); | ||
|
||
if (keySelector == null) | ||
throw new ArgumentNullException(nameof(keySelector)); | ||
|
||
var comparer = Comparer<TKey>.Default; | ||
|
||
using IEnumerator<TSource> e = source.GetEnumerator(); | ||
|
||
if (!e.MoveNext()) | ||
{ | ||
if (default(TSource) is null) | ||
{ | ||
return default; | ||
} | ||
else | ||
{ | ||
throw new InvalidOperationException("Sequence contains no elements"); | ||
} | ||
} | ||
|
||
TSource value = e.Current; | ||
TKey key = keySelector(value); | ||
|
||
if (default(TKey) is null) | ||
{ | ||
if (key == null) | ||
{ | ||
TSource firstValue = value; | ||
|
||
do | ||
{ | ||
if (!e.MoveNext()) | ||
{ | ||
// All keys are null, surface the first element. | ||
return firstValue; | ||
} | ||
|
||
value = e.Current; | ||
key = keySelector(value); | ||
} | ||
while (key == null); | ||
} | ||
|
||
while (e.MoveNext()) | ||
{ | ||
TSource nextValue = e.Current; | ||
TKey nextKey = keySelector(nextValue); | ||
if (nextKey != null && comparer.Compare(nextKey, key) > 0) | ||
{ | ||
key = nextKey; | ||
value = nextValue; | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
if (comparer == Comparer<TKey>.Default) | ||
{ | ||
while (e.MoveNext()) | ||
{ | ||
TSource nextValue = e.Current; | ||
TKey nextKey = keySelector(nextValue); | ||
if (Comparer<TKey>.Default.Compare(nextKey, key) > 0) | ||
{ | ||
key = nextKey; | ||
value = nextValue; | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
while (e.MoveNext()) | ||
{ | ||
TSource nextValue = e.Current; | ||
TKey nextKey = keySelector(nextValue); | ||
if (comparer.Compare(nextKey, key) > 0) | ||
{ | ||
key = nextKey; | ||
value = nextValue; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return value; | ||
} | ||
} | ||
#endif |