diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 00000000..eae45905 --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -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/Setup-VSTest@v1.2 + - name: Run tests (NET Framework) + run: vstest.console.exe test\HtmlToOpenXml.Tests\bin\Release\net462\HtmlToOpenXml.Tests.dll /parallel diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 492cb427..00000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: csharp -solution: HtmlToOpenXml.sln -dotnet: 3.1.301 -mono: none -install: - - dotnet restore HtmlToOpenXml.sln -script: - - dotnet build /p:Configuration=Release HtmlToOpenXml.sln - - dotnet test ./test/HtmlToOpenXml.Tests/HtmlToOpenXml.Tests.csproj \ No newline at end of file diff --git a/test/HtmlToOpenXml.Tests/HtmlToOpenXml.Tests.csproj b/test/HtmlToOpenXml.Tests/HtmlToOpenXml.Tests.csproj index e9471714..a0a61761 100755 --- a/test/HtmlToOpenXml.Tests/HtmlToOpenXml.Tests.csproj +++ b/test/HtmlToOpenXml.Tests/HtmlToOpenXml.Tests.csproj @@ -1,8 +1,9 @@  - net8.0 + net462;net8.0 enable + latest false true true diff --git a/test/HtmlToOpenXml.Tests/Utilities/CollectionExtensions.cs b/test/HtmlToOpenXml.Tests/Utilities/CollectionExtensions.cs new file mode 100644 index 00000000..4cc4d988 --- /dev/null +++ b/test/HtmlToOpenXml.Tests/Utilities/CollectionExtensions.cs @@ -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 + +/// +/// Helper class that provide some extension methods to API. +/// +static class CollectionExtensions +{ + /// + /// Attempts to add the specified key and value to the dictionary. + /// + /// The dictionary in which to insert the item. + /// The key of the element to add. + /// The value of the element to add. It can be . + /// if the key/value pair was added to the dictionary successfully; otherwise, . + /// Returns the maximum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// + public static TSource MaxBy(this IEnumerable source, Func keySelector) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + var comparer = Comparer.Default; + + using IEnumerator 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.Default) + { + while (e.MoveNext()) + { + TSource nextValue = e.Current; + TKey nextKey = keySelector(nextValue); + if (Comparer.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