From 22f3566d19ef0c2a98ee1273470cf2a30f9d0d43 Mon Sep 17 00:00:00 2001 From: Jonatan Gonzalez Date: Tue, 12 Dec 2023 10:30:55 -0800 Subject: [PATCH 01/20] Create class for reading Json files in chunks (#5530) * Moved files over and addressed some PR comments * added comment * switched to true and false strings * Added ctr to specify buffer for testing purposes. * remove commented code * switch to use Utf8 preamble for BOM * Create method for checking complete * combined code for ReadStringArray * Updated buffer size to match STJ's default buffer size * Switch Utf8JsonStreamReader to be disposable. * Switch to read the value for numbers into a string directly * revert back to using private var for utf8Bom * Remove ReadStringArrayAsList * Avoid referencing buffer after returning * Actually avoid referencing _buffer after returning * Update how buffers are fed into Utf8JsonReader to avoid feeding extra empty data. * remove extra line * Reverted back to using try get int for ReadTokenAsString * Update src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs Co-authored-by: Andy Zivkovic * Remove ValueTextEquals taking in string * Switched to Skip instead of TrySkip * Update src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs Co-authored-by: Andy Zivkovic * Added some unit tests * fix Bom * Switched to using Moq * Update src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs Co-authored-by: Andy Zivkovic * loop through stream when reading to ensure reading full bytes or to the end * update signature comment * Switched stream back to field and supress warning --------- Co-authored-by: Andy Zivkovic --- .../Utf8JsonReaderExtensions.cs | 40 + .../Utf8JsonStreamReader.cs | 273 ++++++ .../Utf8JsonStreamReaderConverter.cs | 13 + .../LockFileFormatTests.cs | 1 - .../Utf8JsonReaderExtensionsTests.cs | 35 + .../Utf8JsonStreamReaderTests.cs | 833 ++++++++++++++++++ 6 files changed, 1194 insertions(+), 1 deletion(-) create mode 100644 src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs create mode 100644 src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs create mode 100644 src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReaderConverter.cs create mode 100644 test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonReaderExtensionsTests.cs create mode 100644 test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs new file mode 100644 index 00000000000..7b40b3f1b30 --- /dev/null +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonReaderExtensions.cs @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Text.Json; + +namespace NuGet.ProjectModel +{ + internal static class Utf8JsonReaderExtensions + { + internal static string ReadTokenAsString(this ref Utf8JsonReader reader) + { + switch (reader.TokenType) + { + case JsonTokenType.True: + return bool.TrueString; + case JsonTokenType.False: + return bool.FalseString; + case JsonTokenType.Number: + return reader.ReadNumberAsString(); + case JsonTokenType.String: + return reader.GetString(); + case JsonTokenType.None: + case JsonTokenType.Null: + return null; + default: + throw new InvalidCastException(); + } + } + + private static string ReadNumberAsString(this ref Utf8JsonReader reader) + { + if (reader.TryGetInt64(out long value)) + { + return value.ToString(); + } + return reader.GetDouble().ToString(); + } + } +} diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs new file mode 100644 index 00000000000..0dc89846b86 --- /dev/null +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs @@ -0,0 +1,273 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.Json; + +namespace NuGet.ProjectModel +{ + /// + /// This struct is used to read over a memeory stream in parts, in order to avoid reading the entire stream into memory. + /// It functions as a wrapper around , while maintaining a stream and a buffer to read from. + /// + internal ref struct Utf8JsonStreamReader + { + private static readonly char[] DelimitedStringDelimiters = [' ', ',']; + private static readonly byte[] Utf8Bom = [0xEF, 0xBB, 0xBF]; + + private const int BufferSizeDefault = 16 * 1024; + private const int MinBufferSize = 1024; + private Utf8JsonReader _reader; +#pragma warning disable CA2213 // Disposable fields should be disposed + private Stream _stream; +#pragma warning restore CA2213 // Disposable fields should be disposed + // The buffer is used to read from the stream in chunks. + private byte[] _buffer; + private bool _disposed; + private ArrayPool _bufferPool; + private int _bufferUsed = 0; + + internal Utf8JsonStreamReader(Stream stream, int bufferSize = BufferSizeDefault, ArrayPool arrayPool = null) + { + if (stream is null) + { + throw new ArgumentNullException(nameof(stream)); + } + + if (bufferSize < MinBufferSize) + { + throw new ArgumentException($"Buffer size must be at least {MinBufferSize} bytes", nameof(bufferSize)); + } + + _bufferPool = arrayPool ?? ArrayPool.Shared; + _buffer = _bufferPool.Rent(bufferSize); + _disposed = false; + _stream = stream; + _stream.Read(_buffer, 0, 3); + if (!Utf8Bom.AsSpan().SequenceEqual(_buffer.AsSpan(0, 3))) + { + _bufferUsed = 3; + } + + var iniialJsonReaderState = new JsonReaderState(new JsonReaderOptions + { + AllowTrailingCommas = true, + CommentHandling = JsonCommentHandling.Skip, + }); + + ReadStreamIntoBuffer(iniialJsonReaderState); + _reader.Read(); + } + + internal bool IsFinalBlock => _reader.IsFinalBlock; + + internal JsonTokenType TokenType => _reader.TokenType; + + internal bool ValueTextEquals(ReadOnlySpan utf8Text) => _reader.ValueTextEquals(utf8Text); + + internal bool TryGetInt32(out int value) => _reader.TryGetInt32(out value); + + internal string GetString() => _reader.GetString(); + + internal bool GetBoolean() => _reader.GetBoolean(); + + internal int GetInt32() => _reader.GetInt32(); + + internal bool Read() + { + ThrowExceptionIfDisposed(); + + bool wasRead; + while (!(wasRead = _reader.Read()) && !_reader.IsFinalBlock) + { + GetMoreBytesFromStream(); + } + return wasRead; + } + + internal void Skip() + { + ThrowExceptionIfDisposed(); + + bool wasSkipped; + while (!(wasSkipped = _reader.TrySkip()) && !_reader.IsFinalBlock) + { + GetMoreBytesFromStream(); + } + if (!wasSkipped) + { + _reader.Skip(); + } + } + + internal string ReadNextTokenAsString() + { + ThrowExceptionIfDisposed(); + + if (Read()) + { + return _reader.ReadTokenAsString(); + } + + return null; + } + + internal IList ReadStringArrayAsIList(IList strings = null) + { + if (TokenType == JsonTokenType.StartArray) + { + while (Read() && TokenType != JsonTokenType.EndArray) + { + string value = _reader.ReadTokenAsString(); + + strings = strings ?? new List(); + + strings.Add(value); + } + } + return strings; + } + + internal IReadOnlyList ReadDelimitedString() + { + ThrowExceptionIfDisposed(); + + if (Read()) + { + switch (TokenType) + { + case JsonTokenType.String: + var value = GetString(); + + return value.Split(DelimitedStringDelimiters, StringSplitOptions.RemoveEmptyEntries); + + default: + var invalidCastException = new InvalidCastException(); + throw new JsonException(invalidCastException.Message, invalidCastException); + } + } + + return null; + } + + internal bool ReadNextTokenAsBoolOrFalse() + { + ThrowExceptionIfDisposed(); + + if (Read() && (TokenType == JsonTokenType.False || TokenType == JsonTokenType.True)) + { + return GetBoolean(); + } + return false; + } + + internal IReadOnlyList ReadNextStringOrArrayOfStringsAsReadOnlyList() + { + ThrowExceptionIfDisposed(); + + if (Read()) + { + switch (_reader.TokenType) + { + case JsonTokenType.String: + return new[] { (string)_reader.GetString() }; + + case JsonTokenType.StartArray: + return ReadStringArrayAsReadOnlyListFromArrayStart(); + + case JsonTokenType.StartObject: + return null; + } + } + + return null; + } + + internal IReadOnlyList ReadStringArrayAsReadOnlyListFromArrayStart() + { + ThrowExceptionIfDisposed(); + + List strings = null; + + while (Read() && _reader.TokenType != JsonTokenType.EndArray) + { + string value = _reader.ReadTokenAsString(); + + strings = strings ?? new List(); + + strings.Add(value); + } + + return (IReadOnlyList)strings ?? Array.Empty(); + } + + // This function is called when Read() returns false and we're not already in the final block + private void GetMoreBytesFromStream() + { + if (_reader.BytesConsumed < _bufferUsed) + { + // If the number of bytes consumed by the reader is less than the amount set in the buffer then we have leftover bytes + var oldBuffer = _buffer; + ReadOnlySpan leftover = oldBuffer.AsSpan((int)_reader.BytesConsumed); + _bufferUsed = leftover.Length; + + // If the leftover bytes are the same as the buffer size then we are at capacity and need to double the buffer size + if (leftover.Length == _buffer.Length) + { + _buffer = _bufferPool.Rent(_buffer.Length * 2); + leftover.CopyTo(_buffer); + _bufferPool.Return(oldBuffer, true); + } + else + { + leftover.CopyTo(_buffer); + } + } + else + { + _bufferUsed = 0; + } + + ReadStreamIntoBuffer(_reader.CurrentState); + } + + /// + /// Loops through the stream and reads it into the buffer until the buffer is full or the stream is empty, creates the Utf8JsonReader. + /// + private void ReadStreamIntoBuffer(JsonReaderState jsonReaderState) + { + int bytesRead; + do + { + var spaceLeftInBuffer = _buffer.Length - _bufferUsed; + bytesRead = _stream.Read(_buffer, _bufferUsed, spaceLeftInBuffer); + _bufferUsed += bytesRead; + } + while (bytesRead != 0 && _bufferUsed != _buffer.Length); + _reader = new Utf8JsonReader(_buffer.AsSpan(0, _bufferUsed), isFinalBlock: bytesRead == 0, jsonReaderState); + } + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + byte[] toReturn = _buffer; + _buffer = null!; + _bufferPool.Return(toReturn, true); + } + } + + private void ThrowExceptionIfDisposed() + { + if (_disposed) + { + throw new ObjectDisposedException(nameof(Utf8JsonStreamReader)); + } + } + } +} diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReaderConverter.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReaderConverter.cs new file mode 100644 index 00000000000..167750c3828 --- /dev/null +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReaderConverter.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +namespace NuGet.ProjectModel +{ + /// + /// An abstract class that defines a function for reading a into a + /// + /// + internal abstract class Utf8JsonStreamReaderConverter + { + public abstract T Read(ref Utf8JsonStreamReader reader); + } +} diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs index 54977dc03b8..310781aa194 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/LockFileFormatTests.cs @@ -213,7 +213,6 @@ public void LockFileFormat_ReadsLockFileWithNoTools() var target = lockFile.Targets.Single(); Assert.Equal(NuGetFramework.Parse("dotnet"), target.TargetFramework); - var runtimeTargetLibrary = target.Libraries.Single(); Assert.Equal("System.Runtime", runtimeTargetLibrary.Name); Assert.Equal(NuGetVersion.Parse("4.0.20-beta-22927"), runtimeTargetLibrary.Version); diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonReaderExtensionsTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonReaderExtensionsTests.cs new file mode 100644 index 00000000000..0c60a72b4e3 --- /dev/null +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonReaderExtensionsTests.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Text; +using System.Text.Json; +using Xunit; + +namespace NuGet.ProjectModel.Test +{ + [UseCulture("")] // Fix tests failing on systems with non-English locales + public class Utf8JsonReaderExtensionsTests + { + [Theory] + [InlineData("null", null)] + [InlineData("true", "True")] + [InlineData("false", "False")] + [InlineData("-2", "-2")] + [InlineData("9223372036854775807", "9223372036854775807")] + [InlineData("3.14", "3.14")] + [InlineData("\"b\"", "b")] + public void ReadTokenAsString_WhenValueIsConvertibleToString_ReturnsValueAsString( + string value, + string expectedResult) + { + var json = $"{{\"a\":{value}}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + var reader = new Utf8JsonReader(encodedBytes); + reader.Read(); + reader.Read(); + reader.Read(); + string actualResult = reader.ReadTokenAsString(); + Assert.Equal(expectedResult, actualResult); + } + } +} diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs new file mode 100644 index 00000000000..3193f43c4f5 --- /dev/null +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs @@ -0,0 +1,833 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Buffers; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using Moq; +using Xunit; + +namespace NuGet.ProjectModel.Test +{ + [UseCulture("")] // Fix tests failing on systems with non-English locales + public class Utf8JsonStreamReaderTests + { + private static readonly string JsonWithOverflowObject = "{\"object1\":{\"a\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"b\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"c\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"d\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"e\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"f\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"g\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"h\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"i\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"j\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"k\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"l\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"m\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"n\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"o\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"p\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"q\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"r\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"s\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"t\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"u\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"},\"object2\":{\"a\":\"abcdefghijklmnopqrstuvwxyz\",\"b\":\"abcdefghijklmnopqrstuvwxyz\",\"c\":\"abcdefghijklmnopqrstuvwxyz\",\"d\":\"abcdefghijklmnopqrstuvwxyz\",\"e\":\"abcdefghijklmnopqrstuvwxyz\",\"f\":\"abcdefghijklmnopqrstuvwxyz\",\"g\":\"abcdefghijklmnopqrstuvwxyz\",\"h\":\"abcdefghijklmnopqrstuvwxyz\",\"i\":\"abcdefghijklmnopqrstuvwxyz\",\"j\":\"abcdefghijklmnopqrstuvwxyz\",\"k\":\"abcdefghijklmnopqrstuvwxyz\",\"l\":\"abcdefghijklmnopqrstuvwxyz\",\"m\":\"abcdefghijklmnopqrstuvwxyz\",\"n\":\"abcdefghijklmnopqrstuvwxyz\",\"o\":\"abcdefghijklmnopqrstuvwxyz\",\"p\":\"abcdefghijklmnopqrstuvwxyz\",\"q\":\"abcdefghijklmnopqrstuvwxyz\",\"r\":\"abcdefghijklmnopqrstuvwxyz\",\"s\":\"abcdefghijklmnopqrstuvwxyz\",\"t\":\"abcdefghijklmnopqrstuvwxyz\",\"u\":\"abcdefghijklmnopqrstuvwxyz\"}}"; + private static readonly string JsonWithoutOverflow = "{\"object1\":{\"a\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"b\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"c\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"d\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"e\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"f\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"g\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"h\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"i\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"j\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"k\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"l\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"m\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"n\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"o\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"p\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"q\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"r\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"s\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"t\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"u\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"}}"; + private static readonly string JsonWithOverflow = "{\"object1\":{\"a\":\"abcdefghijklmnopqrstuvwxyz\",\"b\":\"abcdefghijklmnopqrstuvwxyz\",\"c\":\"abcdefghijklmnopqrstuvwxyz\",\"d\":\"abcdefghijklmnopqrstuvwxyz\",\"e\":\"abcdefghijklmnopqrstuvwxyz\",\"f\":\"abcdefghijklmnopqrstuvwxyz\",\"g\":\"abcdefghijklmnopqrstuvwxyz\",\"h\":\"abcdefghijklmnopqrstuvwxyz\",\"i\":\"abcdefghijklmnopqrstuvwxyz\",\"j\":\"abcdefghijklmnopqrstuvwxyz\",\"k\":\"abcdefghijklmnopqrstuvwxyz\",\"l\":\"abcdefghijklmnopqrstuvwxyz\",\"m\":\"abcdefghijklmnopqrstuvwxyz\",\"n\":\"abcdefghijklmnopqrstuvwxyz\",\"o\":\"abcdefghijklmnopqrstuvwxyz\",\"p\":\"abcdefghijklmnopqrstuvwxyz\",\"q\":\"abcdefghijklmnopqrstuvwxyz\",\"r\":\"abcdefghijklmnopqrstuvwxyz\",\"s\":\"abcdefghijklmnopqrstuvwxyz\",\"t\":\"abcdefghijklmnopqrstuvwxyz\",\"u\":\"abcdefghijklmnopqrstuvwxyz\"}, \"object2\": {\"a\":\"abcdefghijklmnopqrstuvwxyz\",\"b\":\"abcdefghijklmnopqrstuvwxyz\",\"c\":\"abcdefghijklmnopqrstuvwxyz\",\"d\":\"abcdefghijklmnopqrstuvwxyz\",\"e\":\"abcdefghijklmnopqrstuvwxyz\",\"f\":\"abcdefghijklmnopqrstuvwxyz\",\"g\":\"abcdefghijklmnopqrstuvwxyz\",\"h\":\"abcdefghijklmnopqrstuvwxyz\",\"i\":\"abcdefghijklmnopqrstuvwxyz\",\"j\":\"abcdefghijklmnopqrstuvwxyz\",\"k\":\"abcdefghijklmnopqrstuvwxyz\",\"l\":\"abcdefghijklmnopqrstuvwxyz\",\"m\":\"abcdefghijklmnopqrstuvwxyz\",\"n\":\"abcdefghijklmnopqrstuvwxyz\",\"o\":\"abcdefghijklmnopqrstuvwxyz\",\"p\":\"abcdefghijklmnopqrstuvwxyz\",\"q\":\"abcdefghijklmnopqrstuvwxyz\",\"r\":\"abcdefghijklmnopqrstuvwxyz\",\"s\":\"abcdefghijklmnopqrstuvwxyz\",\"t\":\"abcdefghijklmnopqrstuvwxyz\",\"u\":\"abcdefghijklmnopqrstuvwxyz\"}, \"object3\":{\"a\":\"abcdefghijklmnopqrstuvwxyz\",\"b\":\"abcdefghijklmnopqrstuvwxyz\",\"c\":\"abcdefghijklmnopqrstuvwxyz\",\"d\":\"abcdefghijklmnopqrstuvwxyz\",\"e\":\"abcdefghijklmnopqrstuvwxyz\",\"f\":\"abcdefghijklmnopqrstuvwxyz\",\"g\":\"abcdefghijklmnopqrstuvwxyz\",\"h\":\"abcdefghijklmnopqrstuvwxyz\",\"i\":\"abcdefghijklmnopqrstuvwxyz\",\"j\":\"abcdefghijklmnopqrstuvwxyz\",\"k\":\"abcdefghijklmnopqrstuvwxyz\",\"l\":\"abcdefghijklmnopqrstuvwxyz\",\"m\":\"abcdefghijklmnopqrstuvwxyz\",\"n\":\"abcdefghijklmnopqrstuvwxyz\",\"o\":\"abcdefghijklmnopqrstuvwxyz\",\"p\":\"abcdefghijklmnopqrstuvwxyz\",\"q\":\"abcdefghijklmnopqrstuvwxyz\",\"r\":\"abcdefghijklmnopqrstuvwxyz\",\"s\":\"abcdefghijklmnopqrstuvwxyz\",\"t\":\"abcdefghijklmnopqrstuvwxyz\",\"u\":\"abcdefghijklmnopqrstuvwxyz\"}}"; + private static readonly string SmallJson = "{\"object1\":{\"a\":\"abcdefghijklmnopqrstuvwxyz\"}}"; + + [Fact] + public void Utf8JsonStreamReaderCtr_WhenStreamIsNull_Throws() + { + Assert.Throws(() => + { + using var reader = new Utf8JsonStreamReader(null); + }); + } + + [Fact] + public void Utf8JsonStreamReaderCtr_WhenBufferToSmall_Throws() + { + Assert.Throws(() => + { + var json = "{}"; + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + using (var reader = new Utf8JsonStreamReader(stream, 10)) + { + } + }); + } + + [Fact] + public void Utf8JsonStreamReaderCtr_WhenStreamStartsWithUtf8Bom_SkipThem() + { + var json = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()) + "{}"; + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(5, stream.Position); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + } + } + + [Fact] + public void Utf8JsonStreamReaderCtr_WhenStreamStartsWithoutUtf8Bom_ReadFromStart() + { + var json = "{}"; + + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(2, stream.Position); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + } + } + + [Fact] + public void Utf8JsonStreamReaderCtr_WhenReadingWithOverflow_FinalBlockFalse() + { + var json = Encoding.UTF8.GetBytes(JsonWithOverflowObject); + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024)) + { + Assert.False(reader.IsFinalBlock); + } + } + + [Fact] + public void Read_WhenReadingMalfornedJsonString_Throws() + { + var json = Encoding.UTF8.GetBytes("{\"a\":\"string}"); + + Assert.ThrowsAny(() => + { + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.True(reader.IsFinalBlock); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.Read(); + } + }); + } + + [Fact] + public void Read_WhenReadingMalfornedJson_Throws() + { + var json = Encoding.UTF8.GetBytes("{\"a\":\"string\"}ohno"); + Assert.ThrowsAny(() => + { + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.True(reader.IsFinalBlock); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); + } + }); + } + + [Fact] + public void Read_WhenReadingSmallJson_Read() + { + var json = Encoding.UTF8.GetBytes(SmallJson); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.True(reader.IsFinalBlock); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.String, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + } + } + + [Fact] + public void Read_WhenReadingSmallJsonPastEnd_Read() + { + var json = Encoding.UTF8.GetBytes(SmallJson); + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.True(reader.IsFinalBlock); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.String, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + Assert.False(reader.Read()); + } + } + + [Fact] + public void Read_WhenReadingWithoutOverflow_Read() + { + var json = Encoding.UTF8.GetBytes(JsonWithoutOverflow); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + } + } + + [Fact] + public void Read_WhenReadingWithOverflow_ReadNextBuffer() + { + var json = Encoding.UTF8.GetBytes(JsonWithOverflowObject); + var mock = SetupMockArrayBuffer(); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024, mock.Object)) + { + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.PropertyName && reader.GetString() == "r") + { + break; + } + } + reader.Read(); + mock.Verify(m => m.Rent(1024), Times.Exactly(1)); + Assert.Equal(JsonTokenType.String, reader.TokenType); + Assert.Equal("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", reader.GetString()); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + Assert.Equal("s", reader.GetString()); + } + } + + [Fact] + public void Read_WhenReadingWithLargeToken_ResizeBuffer() + { + var json = Encoding.UTF8.GetBytes("{\"largeToken\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"smallToken\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"}"); + var mock = SetupMockArrayBuffer(); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024, mock.Object)) + { + reader.Read(); + reader.Read(); + + mock.Verify(m => m.Rent(1024), Times.Exactly(1)); + mock.Verify(m => m.Rent(2048), Times.Exactly(1)); + mock.Verify(m => m.Return(It.IsAny(), true), Times.Exactly(1)); + Assert.Equal(JsonTokenType.String, reader.TokenType); + Assert.Equal("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", + reader.GetString()); + } + } + + [Fact] + public void Read_WhenReadingWithLargeTokenReadPastFinal() + { + var json = Encoding.UTF8.GetBytes("{\"largeToken\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\",\"smallToken\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"}"); + var mock = SetupMockArrayBuffer(); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024, mock.Object)) + { + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); + mock.Verify(m => m.Rent(1024), Times.Exactly(1)); + mock.Verify(m => m.Rent(2048), Times.Exactly(1)); + mock.Verify(m => m.Return(It.IsAny(), true), Times.Exactly(1)); + Assert.False(reader.Read()); + } + } + + [Fact] + public void Read_WhenReadingWithOverflowToBufferSize_LoadNextBuffer() + { + var json = Encoding.UTF8.GetBytes("{\"largeToken\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst\",\"smallToken\":\"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\"}"); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024)) + { + reader.Read(); + reader.Read(); + reader.Read(); + + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + Assert.Equal("smallToken", reader.GetString()); + Assert.True(reader.Read()); + Assert.Equal(JsonTokenType.String, reader.TokenType); + Assert.Equal("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", reader.GetString()); + } + } + + [Fact] + public void Dispose_NoErrors() + { + var json = Encoding.UTF8.GetBytes(SmallJson); + var mock = SetupMockArrayBuffer(); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024, arrayPool: mock.Object)) + { + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + } + mock.Verify(m => m.Return(It.IsAny(), true), Times.Exactly(1)); + } + + [Fact] + public void Dispose_Read_ObjectDisposedException() + { + var json = Encoding.UTF8.GetBytes(SmallJson); + Assert.Throws(() => + { + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Dispose(); + reader.Read(); + } + }); + } + + [Fact] + public void Dispose_Skip_ObjectDisposedException() + { + var json = Encoding.UTF8.GetBytes(SmallJson); + Assert.Throws(() => + { + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Dispose(); + reader.Skip(); + } + }); + } + + [Theory] + [InlineData("{\"object1\": { \"a\":\"asdad\" }")] + [InlineData("{\"object1\": { \"a\":\"asdad }}")] + [InlineData("{\"object1\": \"a\":\"asdad\" }}")] + public void Skip_WhenReadingWithMalformedJson(string malformedJson) + { + var json = Encoding.UTF8.GetBytes(malformedJson); + + Assert.ThrowsAny(() => + { + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Skip(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + } + }); + } + + [Fact] + public void Skip_WhenReadingWithoutOverflow_SkipObject() + { + var json = Encoding.UTF8.GetBytes(JsonWithoutOverflow); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(JsonTokenType.StartObject, reader.TokenType); + reader.Skip(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + } + } + + [Fact] + public void Skip_WhenReadingWithOverflow_Skip() + { + var json = Encoding.UTF8.GetBytes(JsonWithOverflow); + var mock = SetupMockArrayBuffer(); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024, mock.Object)) + { + reader.Read(); + reader.Skip(); + reader.Read(); + reader.Skip(); + Assert.Equal(JsonTokenType.EndObject, reader.TokenType); + reader.Read(); + Assert.Equal("object3", reader.GetString()); + mock.Verify(m => m.Rent(1024), Times.Exactly(1)); + } + } + + [Fact] + public void Skip_WhenReadingWithOverflowObject_ResizeBuffer() + { + var json = Encoding.UTF8.GetBytes(JsonWithOverflowObject); + var mock = SetupMockArrayBuffer(); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream, 1024, mock.Object)) + { + reader.Read(); + reader.Skip(); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + Assert.Equal("object2", reader.GetString()); + mock.Verify(m => m.Rent(1024), Times.Exactly(1)); + mock.Verify(m => m.Rent(2048), Times.Exactly(1)); + mock.Verify(m => m.Return(It.IsAny(), true), Times.Exactly(1)); + } + } + + [Fact] + public void ReadNextTokenAsString_WhenCalled_AdvanceToken() + { + var json = Encoding.UTF8.GetBytes("{\"token\":\"value\"}"); + + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + var result = reader.ReadNextTokenAsString(); + Assert.Equal(JsonTokenType.String, reader.TokenType); + Assert.Equal("value", result); + } + } + + [Fact] + public void ReadNextTokenAsString_WithMalformedJson_GetException() + { + var json = Encoding.UTF8.GetBytes("{\"token\":\"value}"); + Assert.ThrowsAny(() => + { + using (var stream = new MemoryStream(json)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + reader.ReadNextTokenAsString(); + } + }); + } + + [Theory] + [InlineData("true", JsonTokenType.True)] + [InlineData("false", JsonTokenType.False)] + [InlineData("-2", JsonTokenType.Number)] + [InlineData("3.14", JsonTokenType.Number)] + [InlineData("{}", JsonTokenType.StartObject)] + [InlineData("[]", JsonTokenType.StartArray)] + [InlineData("[true]", JsonTokenType.StartArray)] + [InlineData("[-2]", JsonTokenType.StartArray)] + [InlineData("[3.14]", JsonTokenType.StartArray)] + [InlineData("[\"a\", \"b\"]", JsonTokenType.StartArray)] + public void ReadDelimitedString_WhenValueIsNotString_Throws(string value, JsonTokenType expectedTokenType) + { + var json = $"{{\"a\":{value}}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + var tokenType = JsonTokenType.None; + var exceptionThrown = Assert.Throws(() => + { + using var stream = new MemoryStream(encodedBytes); + using var reader = new Utf8JsonStreamReader(stream); + reader.Read(); + try + { + reader.ReadDelimitedString(); + } + finally + { + tokenType = reader.TokenType; + } + }); + Assert.NotNull(exceptionThrown.InnerException); + Assert.IsType(typeof(InvalidCastException), exceptionThrown.InnerException); + Assert.Equal(expectedTokenType, tokenType); + } + + [Fact] + public void ReadDelimitedString_WhenValueIsString_ReturnsValue() + { + const string expectedResult = "b"; + var json = $"{{\"a\":\"{expectedResult}\"}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + IEnumerable actualResults = reader.ReadDelimitedString(); + Assert.Collection(actualResults, actualResult => Assert.Equal(expectedResult, actualResult)); + Assert.Equal(JsonTokenType.String, reader.TokenType); + } + } + + [Theory] + [InlineData("b,c,d")] + [InlineData("b c d")] + public void ReadDelimitedString_WhenValueIsDelimitedString_ReturnsValues(string value) + { + string[] expectedResults = value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); + var json = $"{{\"a\":\"{value}\"}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + IEnumerable actualResults = reader.ReadDelimitedString(); + Assert.Equal(expectedResults, actualResults); + Assert.Equal(JsonTokenType.String, reader.TokenType); + } + } + + [Theory] + [InlineData("null")] + [InlineData("\"b\"")] + [InlineData("{}")] + public void ReadStringArrayAsIList_WhenValueIsNotArray_ReturnsNull(string value) + { + var json = $"{{\"a\":{value}}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + reader.Read(); + Assert.NotEqual(JsonTokenType.PropertyName, reader.TokenType); + IList actualValues = reader.ReadStringArrayAsIList(); + Assert.Null(actualValues); + } + } + + [Fact] + public void ReadStringArrayAsIList_WhenValueIsEmptyArray_ReturnsNull() + { + var encodedBytes = Encoding.UTF8.GetBytes("{\"a\":[]}"); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + reader.Read(); + Assert.NotEqual(JsonTokenType.PropertyName, reader.TokenType); + IList actualValues = reader.ReadStringArrayAsIList(); + Assert.Null(actualValues); + } + } + + [Fact] + public void ReadStringArrayAsIList_WithSupportedTypes_ReturnsStringArray() + { + var encodedBytes = Encoding.UTF8.GetBytes("[\"a\",-2,3.14,true,null]"); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + IList actualValues = reader.ReadStringArrayAsIList(); + + Assert.Collection( + actualValues, + actualValue => Assert.Equal("a", actualValue), + actualValue => Assert.Equal("-2", actualValue), + actualValue => Assert.Equal("3.14", actualValue), + actualValue => Assert.Equal("True", actualValue), + actualValue => Assert.Equal(null, actualValue)); + Assert.Equal(JsonTokenType.EndArray, reader.TokenType); + } + } + + [Theory] + [InlineData("[]")] + [InlineData("{}")] + public void ReadStringArrayAsIList_WithUnsupportedTypes_Throws(string element) + { + var encodedBytes = Encoding.UTF8.GetBytes($"[{element}]"); + Assert.Throws(() => + { + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.ReadStringArrayAsIList(); + } + }); + } + + + [Theory] + [InlineData("true", true)] + [InlineData("false", false)] + public void ReadNextTokenAsBoolOrFalse_WithValidValues_ReturnsBoolean(string value, bool expectedResult) + { + var json = $"{{\"a\":{value}}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + bool actualResult = reader.ReadNextTokenAsBoolOrFalse(); + Assert.Equal(expectedResult, actualResult); + } + } + + [Theory] + [InlineData("\"words\"")] + [InlineData("-3")] + [InlineData("3.3")] + [InlineData("[]")] + [InlineData("{}")] + public void ReadNextTokenAsBoolOrFalse_WithInvalidValues_ReturnsFalse(string value) + { + var json = $"{{\"a\":{value}}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + bool actualResult = reader.ReadNextTokenAsBoolOrFalse(); + Assert.False(actualResult); + } + } + + [Fact] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsNull_ReturnsNull() + { + const string json = "{\"a\":null}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + IEnumerable actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + Assert.Null(actualResults); + Assert.Equal(JsonTokenType.Null, reader.TokenType); + } + } + + [Theory] + [InlineData("true", JsonTokenType.True)] + [InlineData("false", JsonTokenType.False)] + [InlineData("-2", JsonTokenType.Number)] + [InlineData("3.14", JsonTokenType.Number)] + [InlineData("{}", JsonTokenType.StartObject)] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsNotString_ReturnsNull( + string value, + JsonTokenType expectedTokenType) + { + var json = $"{{\"a\":{value}}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + + IEnumerable actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + Assert.Null(actualResults); + Assert.Equal(expectedTokenType, reader.TokenType); + } + } + + [Fact] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsString_ReturnsValue() + { + const string expectedResult = "b"; + var json = $"{{\"a\":\"{expectedResult}\"}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + + IEnumerable actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + Assert.Collection(actualResults, actualResult => Assert.Equal(expectedResult, actualResult)); + Assert.Equal(JsonTokenType.String, reader.TokenType); + } + } + + [Theory] + [InlineData("b,c,d")] + [InlineData("b c d")] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsDelimitedString_ReturnsValue(string expectedResult) + { + var json = $"{{\"a\":\"{expectedResult}\"}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + + IEnumerable actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + Assert.Collection(actualResults, actualResult => Assert.Equal(expectedResult, actualResult)); + Assert.Equal(JsonTokenType.String, reader.TokenType); + } + } + + [Fact] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsEmptyArray_ReturnsEmptyList() + { + const string json = "{\"a\":[]}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + + IReadOnlyList actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + Assert.Empty(actualResults); + Assert.Equal(JsonTokenType.EndArray, reader.TokenType); + } + } + + [Theory] + [InlineData("null", null)] + [InlineData("true", "True")] + [InlineData("-2", "-2")] + [InlineData("3.14", "3.14")] + [InlineData("\"b\"", "b")] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsConvertibleToString_ReturnsValueAsString( + string value, + string expectedResult) + { + var json = $"{{\"a\":[{value}]}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + + IEnumerable actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + Assert.Collection(actualResults, actualResult => Assert.Equal(expectedResult, actualResult)); + Assert.Equal(JsonTokenType.EndArray, reader.TokenType); + } + } + + [Theory] + [InlineData("[]", JsonTokenType.StartArray)] + [InlineData("{}", JsonTokenType.StartObject)] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsNotConvertibleToString_ReturnsValueAsString( + string value, + JsonTokenType expectedToken) + { + var json = $"{{\"a\":[{value}]}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + var tokenType = JsonTokenType.None; + var exceptionThrown = Assert.Throws(() => + { + using var stream = new MemoryStream(encodedBytes); + using var reader = new Utf8JsonStreamReader(stream); + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + try + { + reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + finally + { + tokenType = reader.TokenType; + } + }); + Assert.Equal(expectedToken, tokenType); + } + + [Fact] + public void ReadNextStringOrArrayOfStringsAsReadOnlyList_WhenValueIsArrayOfStrings_ReturnsValues() + { + string[] expectedResults = { "b", "c" }; + var json = $"{{\"a\":[{string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\""))}]}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + reader.Read(); + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + + IEnumerable actualResults = reader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + Assert.Equal(expectedResults, actualResults); + Assert.Equal(JsonTokenType.EndArray, reader.TokenType); + } + } + + [Fact] + public void ReadStringArrayAsReadOnlyListFromArrayStart_WhenValuesAreConvertibleToString_ReturnsReadOnlyList() + { + const string json = "[null, true, -2, 3.14, \"a\"]"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + using (var stream = new MemoryStream(encodedBytes)) + using (var reader = new Utf8JsonStreamReader(stream)) + { + Assert.Equal(JsonTokenType.StartArray, reader.TokenType); + + IEnumerable actualResults = reader.ReadStringArrayAsReadOnlyListFromArrayStart(); + + Assert.Collection( + actualResults, + actualResult => Assert.Equal(null, actualResult), + actualResult => Assert.Equal("True", actualResult), + actualResult => Assert.Equal("-2", actualResult), + actualResult => Assert.Equal("3.14", actualResult), + actualResult => Assert.Equal("a", actualResult)); + Assert.Equal(JsonTokenType.EndArray, reader.TokenType); + } + } + + [Theory] + [InlineData("[]", JsonTokenType.StartArray)] + [InlineData("{}", JsonTokenType.StartObject)] + public void ReadStringArrayAsReadOnlyListFromArrayStart_WhenValuesAreNotConvertibleToString_Throws( + string value, + JsonTokenType expectedToken) + { + var json = $"[{value}]"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + var tokenType = JsonTokenType.None; + var exceptionThrown = Assert.Throws(() => + { + using var stream = new MemoryStream(encodedBytes); + using var reader = new Utf8JsonStreamReader(stream); + Assert.Equal(JsonTokenType.StartArray, reader.TokenType); + try + { + reader.ReadStringArrayAsReadOnlyListFromArrayStart(); + } + finally + { + tokenType = reader.TokenType; + } + }); + Assert.Equal(expectedToken, tokenType); + } + + private Mock> SetupMockArrayBuffer() + { + Mock> mock = new Mock>(); + mock.Setup(m => m.Rent(1024)).Returns(new byte[1024]); + mock.Setup(m => m.Rent(2048)).Returns(new byte[2048]); + mock.Setup(m => m.Return(It.IsAny(), It.IsAny())); + + return mock; + } + } +} From b92d83fc70fb1f4596e6e3f6189c74350a0a9c75 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Tue, 12 Dec 2023 11:45:22 -0800 Subject: [PATCH 02/20] Copy files from previous PR --- .../NuGet.ProjectModel/DependencyGraphSpec.cs | 3 +- .../NuGet.ProjectModel/FileFormatException.cs | 56 +- .../JsonPackageSpecReader.cs | 1759 +------- .../LockFile/LockFileFormat.cs | 10 +- .../NuGet.ProjectModel/NjPackageSpecReader.cs | 1765 ++++++++ .../Utf8JsonStreamPackageSpecReader.cs | 1860 +++++++++ .../JsonPackageSpecReaderTests.cs | 58 +- .../Utf8JsonStreamPackageSpecReaderTests.cs | 3635 +++++++++++++++++ .../Utf8JsonStreamReaderTests.cs | 14 + 9 files changed, 7374 insertions(+), 1786 deletions(-) create mode 100644 src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs create mode 100644 src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs create mode 100644 test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs diff --git a/src/NuGet.Core/NuGet.ProjectModel/DependencyGraphSpec.cs b/src/NuGet.Core/NuGet.ProjectModel/DependencyGraphSpec.cs index 67db6eff2b0..9ed7a32b54e 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/DependencyGraphSpec.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/DependencyGraphSpec.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using NuGet.Common; using NuGet.Packaging; @@ -253,7 +252,9 @@ public static DependencyGraphSpec Load(string path) case "projects": jsonReader.ReadObject(projectsPropertyName => { +#pragma warning disable CS0612 // Type or member is obsolete PackageSpec packageSpec = JsonPackageSpecReader.GetPackageSpec(jsonReader, path); +#pragma warning restore CS0612 // Type or member is obsolete dgspec._projects.Add(projectsPropertyName, packageSpec); }); diff --git a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs index c2992999a27..7998fcb790b 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs @@ -10,6 +10,8 @@ namespace NuGet.ProjectModel { public class FileFormatException : Exception { + static internal string SurfaceMessage = "SurfaceMessage"; + public FileFormatException(string message) : base(message) { @@ -47,6 +49,14 @@ private FileFormatException WithLineInfo(int line, int column) return this; } + private FileFormatException WithLineInfo(long? line, long? column) + { + Line = unchecked((int)line.Value); + Column = unchecked((int)column); + + return this; + } + private FileFormatException WithLineInfo(IJsonLineInfo lineInfo) { Line = lineInfo.LineNumber; @@ -101,32 +111,50 @@ internal static FileFormatException Create(string message, int line, int column, return ex.WithFilePath(path).WithLineInfo(line, column); } - internal static FileFormatException Create(Exception exception, string path) + internal static FileFormatException Create(JsonReaderException exception, string path) { - var jex = exception as JsonReaderException; + string message; + message = string.Format(CultureInfo.CurrentCulture, + Strings.Log_ErrorReadingProjectJsonWithLocation, + path, exception.LineNumber, + exception.LinePosition, + exception.Message); + + return new FileFormatException(message, exception) + .WithFilePath(path) + .WithLineInfo(exception); + } + internal static FileFormatException Create(System.Text.Json.JsonException exception, string path) + { string message; - if (jex == null) + if (exception.Data.Contains(SurfaceMessage)) + { + message = exception.Message; + } + else if (exception.BytePositionInLine is not null && exception.LineNumber is not null) { message = string.Format(CultureInfo.CurrentCulture, - Strings.Log_ErrorReadingProjectJson, - path, + Strings.Log_ErrorReadingProjectJsonWithLocation, + path, exception.LineNumber, + exception.BytePositionInLine, exception.Message); - - return new FileFormatException(message, exception).WithFilePath(path); } else { message = string.Format(CultureInfo.CurrentCulture, - Strings.Log_ErrorReadingProjectJsonWithLocation, - path, jex.LineNumber, - jex.LinePosition, + Strings.Log_ErrorReadingProjectJson, + path, exception.Message); - - return new FileFormatException(message, exception) - .WithFilePath(path) - .WithLineInfo(jex); } + var fileFormatException = new FileFormatException(message, exception); + fileFormatException.WithFilePath(path); + if (exception.BytePositionInLine is not null && exception.LineNumber is not null) + { + fileFormatException.WithLineInfo(exception.LineNumber, exception.BytePositionInLine); + } + + return fileFormatException; } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index 0a97ed258c0..122803d8bf5 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -2,28 +2,16 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Collections.Generic; -using System.Globalization; using System.IO; -using System.Linq; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NuGet.Common; -using NuGet.Configuration; -using NuGet.Frameworks; -using NuGet.LibraryModel; -using NuGet.Packaging.Core; -using NuGet.RuntimeModel; -using NuGet.Versioning; namespace NuGet.ProjectModel { public static class JsonPackageSpecReader { - private static readonly char[] DelimitedStringSeparators = { ' ', ',' }; - private static readonly char[] VersionSeparators = new[] { ';' }; - public static readonly string RestoreOptions = "restore"; public static readonly string RestoreSettings = "restoreSettings"; public static readonly string HideWarningsAndErrors = "hideWarningsAndErrors"; @@ -49,1757 +37,46 @@ public static PackageSpec GetPackageSpec(string json, string name, string packag } } - [Obsolete("This method is obsolete and will be removed in a future release.")] - public static PackageSpec GetPackageSpec(JObject json) - { - return GetPackageSpec(json, name: null, packageSpecPath: null, snapshotValue: null); - } - public static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue) { - using (var streamReader = new StreamReader(stream)) - using (var jsonReader = new JsonTextReader(streamReader)) - { - return GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); - } - } - - [Obsolete("This method is obsolete and will be removed in a future release.")] - public static PackageSpec GetPackageSpec(JObject rawPackageSpec, string name, string packageSpecPath, string snapshotValue) - { - using (var stringReader = new StringReader(rawPackageSpec.ToString())) - using (var jsonReader = new JsonTextReader(stringReader)) + var useNj = EnvironmentVariableWrapper.Instance.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"); + if (string.IsNullOrEmpty(useNj) || useNj.Equals("false", StringComparison.OrdinalIgnoreCase)) { - return GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); + return Utf8JsonStreamPackageSpecReader.GetPackageSpec(stream, name, packageSpecPath, snapshotValue); } - } - - internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string packageSpecPath) - { - return GetPackageSpec(jsonReader, name: null, packageSpecPath, snapshotValue: null); - } - - private static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string name, string packageSpecPath, string snapshotValue) - { - var packageSpec = new PackageSpec(); - - List compatibilityProfiles = null; - List runtimeDescriptions = null; - var wasPackOptionsSet = false; - var isMappingsNull = false; - - string filePath = name == null ? null : Path.GetFullPath(packageSpecPath); - - jsonReader.ReadObject(propertyName => + else { - if (string.IsNullOrWhiteSpace(propertyName)) - { - return; - } - - switch (propertyName) + using (var textReader = new StreamReader(stream)) + using (var jsonReader = new JsonTextReader(textReader)) { #pragma warning disable CS0612 // Type or member is obsolete - case "authors": - packageSpec.Authors = ReadStringArray(jsonReader) ?? Array.Empty(); - break; - - case "buildOptions": - ReadBuildOptions(jsonReader, packageSpec); - break; - - case "contentFiles": - List contentFiles = jsonReader.ReadStringArrayAsList(); - - if (contentFiles != null) - { - packageSpec.ContentFiles = contentFiles; - } - break; - - case "copyright": - packageSpec.Copyright = jsonReader.ReadNextTokenAsString(); - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "dependencies": - ReadDependencies( - jsonReader, - packageSpec.Dependencies, - filePath, - isGacOrFrameworkReference: false); - break; - -#pragma warning disable CS0612 // Type or member is obsolete - case "description": - packageSpec.Description = jsonReader.ReadNextTokenAsString(); - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "frameworks": - ReadFrameworks(jsonReader, packageSpec); - break; - -#pragma warning disable CS0612 // Type or member is obsolete - case "language": - packageSpec.Language = jsonReader.ReadNextTokenAsString(); - break; - - case "packInclude": - ReadPackInclude(jsonReader, packageSpec); - break; - - case "packOptions": - ReadPackOptions(jsonReader, packageSpec, ref isMappingsNull); - wasPackOptionsSet = true; - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "restore": - ReadMSBuildMetadata(jsonReader, packageSpec); - break; - - case "runtimes": - runtimeDescriptions = ReadRuntimes(jsonReader); - break; - -#pragma warning disable CS0612 // Type or member is obsolete - case "scripts": - ReadScripts(jsonReader, packageSpec); - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "supports": - compatibilityProfiles = ReadSupports(jsonReader); - break; - - case "title": - packageSpec.Title = jsonReader.ReadNextTokenAsString(); - break; - - case "version": - string version = jsonReader.ReadAsString(); - - if (version != null) - { - try - { -#pragma warning disable CS0612 // Type or member is obsolete - packageSpec.HasVersionSnapshot = PackageSpecUtility.IsSnapshotVersion(version); -#pragma warning restore CS0612 // Type or member is obsolete - packageSpec.Version = PackageSpecUtility.SpecifySnapshot(version, snapshotValue); - } - catch (Exception ex) - { - throw FileFormatException.Create(ex, version, packageSpec.FilePath); - } - } - break; - } - }); - - packageSpec.Name = name; - packageSpec.FilePath = name == null ? null : Path.GetFullPath(packageSpecPath); - -#pragma warning disable CS0612 // Type or member is obsolete - if (!wasPackOptionsSet) - { - packageSpec.Owners = Array.Empty(); - packageSpec.PackOptions = new PackOptions() - { - PackageType = Array.Empty() - }; - packageSpec.Tags = Array.Empty(); - } - - if (isMappingsNull) - { - packageSpec.PackOptions.Mappings = null; - } + return GetPackageSpec(jsonReader, packageSpecPath); #pragma warning restore CS0612 // Type or member is obsolete - - packageSpec.RuntimeGraph = new RuntimeGraph( - runtimeDescriptions ?? Enumerable.Empty(), - compatibilityProfiles ?? Enumerable.Empty()); - - if (packageSpec.Name == null) - { - packageSpec.Name = packageSpec.RestoreMetadata?.ProjectName; - } - - // Use the project.json path if one is set, otherwise use the project path - if (packageSpec.FilePath == null) - { - packageSpec.FilePath = packageSpec.RestoreMetadata?.ProjectJsonPath - ?? packageSpec.RestoreMetadata?.ProjectPath; - } - - return packageSpec; - } - - private static PackageType CreatePackageType(JsonTextReader jsonReader) - { - var name = (string)jsonReader.Value; - - return new PackageType(name, Packaging.Core.PackageType.EmptyVersion); - } - - [Obsolete] - private static void ReadBuildOptions(JsonTextReader jsonReader, PackageSpec packageSpec) - { - packageSpec.BuildOptions = new BuildOptions(); - - jsonReader.ReadObject(buildOptionsPropertyName => - { - if (buildOptionsPropertyName == "outputName") - { - packageSpec.BuildOptions.OutputName = jsonReader.ReadNextTokenAsString(); - } - }); - } - - private static void ReadCentralPackageVersions( - JsonTextReader jsonReader, - IDictionary centralPackageVersions, - string filePath) - { - jsonReader.ReadObject(propertyName => - { - int line = jsonReader.LineNumber; - int column = jsonReader.LinePosition; - - if (string.IsNullOrEmpty(propertyName)) - { - throw FileFormatException.Create( - "Unable to resolve central version ''.", - line, - column, - filePath); - } - - string version = jsonReader.ReadNextTokenAsString(); - - if (string.IsNullOrEmpty(version)) - { - throw FileFormatException.Create( - "The version cannot be null or empty.", - line, - column, - filePath); - } - - centralPackageVersions[propertyName] = new CentralPackageVersion(propertyName, VersionRange.Parse(version)); - }); - } - - private static CompatibilityProfile ReadCompatibilityProfile(JsonTextReader jsonReader, string profileName) - { - List sets = null; - - jsonReader.ReadObject(propertyName => - { - sets = sets ?? new List(); - - IEnumerable profiles = ReadCompatibilitySets(jsonReader, propertyName); - - sets.AddRange(profiles); - }); - - return new CompatibilityProfile(profileName, sets ?? Enumerable.Empty()); - } - - private static IEnumerable ReadCompatibilitySets(JsonTextReader jsonReader, string compatibilitySetName) - { - NuGetFramework framework = NuGetFramework.Parse(compatibilitySetName); - - IReadOnlyList values = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList() ?? Array.Empty(); - - foreach (string value in values) - { - yield return new FrameworkRuntimePair(framework, value); - } - } - - internal static void ReadDependencies( - JsonTextReader jsonReader, - IList results, - string packageSpecPath, - bool isGacOrFrameworkReference) - { - jsonReader.ReadObject(propertyName => - { - if (string.IsNullOrEmpty(propertyName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve dependency ''.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - - // Support - // "dependencies" : { - // "Name" : "1.0" - // } - - if (jsonReader.ReadNextToken()) - { - int dependencyValueLine = jsonReader.LineNumber; - int dependencyValueColumn = jsonReader.LinePosition; - var versionLine = 0; - var versionColumn = 0; - - var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; - var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; - var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - List noWarn = null; - - // This method handles both the dependencies and framework assembly sections. - // Framework references should be limited to references. - // Dependencies should allow everything but framework references. - LibraryDependencyTarget targetFlagsValue = isGacOrFrameworkReference - ? LibraryDependencyTarget.Reference - : LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference; - - var autoReferenced = false; - var generatePathProperty = false; - var versionCentrallyManaged = false; - string aliases = null; - string dependencyVersionValue = null; - VersionRange versionOverride = null; - - if (jsonReader.TokenType == JsonToken.String) - { - dependencyVersionValue = (string)jsonReader.Value; - } - else if (jsonReader.TokenType == JsonToken.StartObject) - { - jsonReader.ReadProperties(dependenciesPropertyName => - { - IEnumerable values = null; - - switch (dependenciesPropertyName) - { - case "autoReferenced": - autoReferenced = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); - break; - - case "exclude": - values = jsonReader.ReadDelimitedString(); - dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "generatePathProperty": - generatePathProperty = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); - break; - - case "include": - values = jsonReader.ReadDelimitedString(); - dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "noWarn": - noWarn = ReadNuGetLogCodesList(jsonReader); - break; - - case "suppressParent": - values = jsonReader.ReadDelimitedString(); - suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "target": - targetFlagsValue = ReadTarget(jsonReader, packageSpecPath, targetFlagsValue); - break; - - case "version": - if (jsonReader.ReadNextToken()) - { - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - - dependencyVersionValue = (string)jsonReader.Value; - } - break; - case "versionOverride": - if (jsonReader.ReadNextToken()) - { - try - { - versionOverride = VersionRange.Parse((string)jsonReader.Value); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - } - break; - case "versionCentrallyManaged": - versionCentrallyManaged = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); - break; - - case "aliases": - aliases = jsonReader.ReadAsString(); - break; - } - }); - } - - VersionRange dependencyVersionRange = null; - - if (!string.IsNullOrEmpty(dependencyVersionValue)) - { - try - { - dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - versionLine, - versionColumn, - packageSpecPath); - } - } - - // Projects and References may have empty version ranges, Packages may not - if (dependencyVersionRange == null) - { - if ((targetFlagsValue & LibraryDependencyTarget.Package) == LibraryDependencyTarget.Package) - { - throw FileFormatException.Create( - new ArgumentException(Strings.MissingVersionOnDependency), - dependencyValueLine, - dependencyValueColumn, - packageSpecPath); - } - else - { - // Projects and references with no version property allow all versions - dependencyVersionRange = VersionRange.All; - } - } - - // the dependency flags are: Include flags - Exclude flags - var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency() - { - LibraryRange = new LibraryRange() - { - Name = propertyName, - TypeConstraint = targetFlagsValue, - VersionRange = dependencyVersionRange - }, - IncludeType = includeFlags, - SuppressParent = suppressParentFlagsValue, - AutoReferenced = autoReferenced, - GeneratePathProperty = generatePathProperty, - VersionCentrallyManaged = versionCentrallyManaged, - Aliases = aliases, - // The ReferenceType is not persisted to the assets file - // Default to LibraryDependencyReferenceType.Direct on Read - ReferenceType = LibraryDependencyReferenceType.Direct, - VersionOverride = versionOverride - }; - - if (noWarn != null) - { - libraryDependency.NoWarn = noWarn; - } - - results.Add(libraryDependency); - } - }); - } - - internal static void ReadCentralTransitiveDependencyGroup( - JsonTextReader jsonReader, - IList results, - string packageSpecPath) - { - jsonReader.ReadObject(propertyName => - { - if (string.IsNullOrEmpty(propertyName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve dependency ''.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - - if (jsonReader.ReadNextToken()) - { - int dependencyValueLine = jsonReader.LineNumber; - int dependencyValueColumn = jsonReader.LinePosition; - var versionLine = 0; - var versionColumn = 0; - - var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; - var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; - var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - string dependencyVersionValue = null; - - if (jsonReader.TokenType == JsonToken.String) - { - dependencyVersionValue = (string)jsonReader.Value; - } - else if (jsonReader.TokenType == JsonToken.StartObject) - { - jsonReader.ReadProperties(dependenciesPropertyName => - { - IEnumerable values = null; - - switch (dependenciesPropertyName) - { - case "exclude": - values = jsonReader.ReadDelimitedString(); - dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "include": - values = jsonReader.ReadDelimitedString(); - dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "suppressParent": - values = jsonReader.ReadDelimitedString(); - suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "version": - if (jsonReader.ReadNextToken()) - { - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - dependencyVersionValue = (string)jsonReader.Value; - } - break; - - default: - break; - } - }); - } - - VersionRange dependencyVersionRange = null; - - if (!string.IsNullOrEmpty(dependencyVersionValue)) - { - try - { - dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - versionLine, - versionColumn, - packageSpecPath); - } - } - - if (dependencyVersionRange == null) - { - throw FileFormatException.Create( - new ArgumentException(Strings.MissingVersionOnDependency), - dependencyValueLine, - dependencyValueColumn, - packageSpecPath); - } - - // the dependency flags are: Include flags - Exclude flags - var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency() - { - LibraryRange = new LibraryRange() - { - Name = propertyName, - TypeConstraint = LibraryDependencyTarget.Package, - VersionRange = dependencyVersionRange - }, - - IncludeType = includeFlags, - SuppressParent = suppressParentFlagsValue, - VersionCentrallyManaged = true, - ReferenceType = LibraryDependencyReferenceType.Transitive - }; - - results.Add(libraryDependency); } - }); - } - - private static void ReadDownloadDependencies( - JsonTextReader jsonReader, - IList downloadDependencies, - string packageSpecPath) - { - var seenIds = new HashSet(); - - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) - { - do - { - string name = null; - string versionValue = null; - var isNameDefined = false; - var isVersionDefined = false; - int line = jsonReader.LineNumber; - int column = jsonReader.LinePosition; - int versionLine = 0; - int versionColumn = 0; - - jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "name": - isNameDefined = true; - name = jsonReader.ReadNextTokenAsString(); - break; - - case "version": - isVersionDefined = true; - versionValue = jsonReader.ReadNextTokenAsString(); - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - break; - } - }, out line, out column); - - if (jsonReader.TokenType == JsonToken.EndArray) - { - break; - } - - if (!isNameDefined) - { - throw FileFormatException.Create( - "Unable to resolve downloadDependency ''.", - line, - column, - packageSpecPath); - } - - if (!seenIds.Add(name)) - { - // package ID already seen, only use first definition. - continue; - } - - if (string.IsNullOrEmpty(versionValue)) - { - throw FileFormatException.Create( - "The version cannot be null or empty", - isVersionDefined ? versionLine : line, - isVersionDefined ? versionColumn : column, - packageSpecPath); - } - - string[] versions = versionValue.Split(VersionSeparators, StringSplitOptions.RemoveEmptyEntries); - - foreach (string singleVersionValue in versions) - { - try - { - VersionRange version = VersionRange.Parse(singleVersionValue); - - downloadDependencies.Add(new DownloadDependency(name, version)); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - isVersionDefined ? versionLine : line, - isVersionDefined ? versionColumn : column, - packageSpecPath); - } - } - } while (jsonReader.TokenType == JsonToken.EndObject); } - } - - private static IReadOnlyList ReadEnumerableOfString(JsonTextReader jsonReader) - { - string value = jsonReader.ReadNextTokenAsString(); - - return value.Split(DelimitedStringSeparators, StringSplitOptions.RemoveEmptyEntries); - } - - private static void ReadFrameworkReferences( - JsonTextReader jsonReader, - ISet frameworkReferences, - string packageSpecPath) - { - jsonReader.ReadObject(frameworkName => - { - if (string.IsNullOrEmpty(frameworkName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve frameworkReference.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - var privateAssets = FrameworkDependencyFlagsUtils.Default; - - jsonReader.ReadObject(propertyName => - { - if (propertyName == "privateAssets") - { - IEnumerable strings = ReadEnumerableOfString(jsonReader); - - privateAssets = FrameworkDependencyFlagsUtils.GetFlags(strings); - } - }); - - frameworkReferences.Add(new FrameworkDependency(frameworkName, privateAssets)); - }); - } - - private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packageSpec) - { - jsonReader.ReadObject(_ => - { - var frameworkLine = 0; - var frameworkColumn = 0; - - try - { - ReadTargetFrameworks(packageSpec, jsonReader, out frameworkLine, out frameworkColumn); - } - catch (Exception ex) - { - throw FileFormatException.Create(ex, frameworkLine, frameworkColumn, packageSpec.FilePath); - } - }); } - private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) + [Obsolete("This method is obsolete and will be removed in a future release.")] + public static PackageSpec GetPackageSpec(JObject json) { - int lineNumber = jsonReader.LineNumber; - int linePosition = jsonReader.LinePosition; - - IReadOnlyList imports = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - - if (imports != null && imports.Count > 0) - { - foreach (string import in imports.Where(element => !string.IsNullOrEmpty(element))) - { - NuGetFramework framework = NuGetFramework.Parse(import); - - if (!framework.IsSpecificFramework) - { - throw FileFormatException.Create( - string.Format( - CultureInfo.CurrentCulture, - Strings.Log_InvalidImportFramework, - import, - PackageSpec.PackageSpecFileName), - lineNumber, - linePosition, - packageSpec.FilePath); - } - - targetFrameworkInformation.Imports.Add(framework); - } - } + return GetPackageSpec(json, name: null, packageSpecPath: null, snapshotValue: null); } - private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, IDictionary mappings) + [Obsolete("This method is obsolete and will be removed in a future release.")] + public static PackageSpec GetPackageSpec(JObject rawPackageSpec, string name, string packageSpecPath, string snapshotValue) { - if (jsonReader.ReadNextToken()) + using (var stringReader = new StringReader(rawPackageSpec.ToString())) + using (var jsonReader = new JsonTextReader(stringReader)) { - switch (jsonReader.TokenType) - { - case JsonToken.String: - { - var files = new IncludeExcludeFiles() - { - Include = new[] { (string)jsonReader.Value } - }; - - mappings.Add(mappingKey, files); - } - break; - - case JsonToken.StartArray: - { - IReadOnlyList include = jsonReader.ReadStringArrayAsReadOnlyListFromArrayStart(); - - var files = new IncludeExcludeFiles() - { - Include = include - }; - - mappings.Add(mappingKey, files); - } - break; - - case JsonToken.StartObject: - { - IReadOnlyList excludeFiles = null; - IReadOnlyList exclude = null; - IReadOnlyList includeFiles = null; - IReadOnlyList include = null; - - jsonReader.ReadProperties(filesPropertyName => - { - switch (filesPropertyName) - { - case "excludeFiles": - excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "exclude": - exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "includeFiles": - includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "include": - include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - } - }); - - if (include != null || includeFiles != null || exclude != null || excludeFiles != null) - { - var files = new IncludeExcludeFiles() - { - ExcludeFiles = excludeFiles, - Exclude = exclude, - IncludeFiles = includeFiles, - Include = include - }; - - mappings.Add(mappingKey, files); - } - } - break; - } + return NjPackageSpecReader.GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); } } - private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec packageSpec) + [Obsolete] + internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string packageSpecPath) { - var centralPackageVersionsManagementEnabled = false; - var centralPackageVersionOverrideDisabled = false; - var CentralPackageTransitivePinningEnabled = false; - List configFilePaths = null; - var crossTargeting = false; - List fallbackFolders = null; - List files = null; - var legacyPackagesDirectory = false; - ProjectRestoreMetadata msbuildMetadata = null; - List originalTargetFrameworks = null; - string outputPath = null; - string packagesConfigPath = null; - string packagesPath = null; - string projectJsonPath = null; - string projectName = null; - string projectPath = null; - ProjectStyle? projectStyle = null; - string projectUniqueName = null; - RestoreLockProperties restoreLockProperties = null; - var skipContentFileWrite = false; - List sources = null; - List targetFrameworks = null; - var validateRuntimeAssets = false; - WarningProperties warningProperties = null; - RestoreAuditProperties auditProperties = null; - - jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "centralPackageVersionsManagementEnabled": - centralPackageVersionsManagementEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "centralPackageVersionOverrideDisabled": - centralPackageVersionOverrideDisabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "CentralPackageTransitivePinningEnabled": - CentralPackageTransitivePinningEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "configFilePaths": - configFilePaths = jsonReader.ReadStringArrayAsList(); - break; - - case "crossTargeting": - crossTargeting = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "fallbackFolders": - fallbackFolders = jsonReader.ReadStringArrayAsList(); - break; - - case "files": - jsonReader.ReadObject(filePropertyName => - { - files = files ?? new List(); - - files.Add(new ProjectRestoreMetadataFile(filePropertyName, jsonReader.ReadNextTokenAsString())); - }); - break; - - case "frameworks": - targetFrameworks = ReadTargetFrameworks(jsonReader); - break; - - case "legacyPackagesDirectory": - legacyPackagesDirectory = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "originalTargetFrameworks": - originalTargetFrameworks = jsonReader.ReadStringArrayAsList(); - break; - - case "outputPath": - outputPath = jsonReader.ReadNextTokenAsString(); - break; - - case "packagesConfigPath": - packagesConfigPath = jsonReader.ReadNextTokenAsString(); - break; - - case "packagesPath": - packagesPath = jsonReader.ReadNextTokenAsString(); - break; - - case "projectJsonPath": - projectJsonPath = jsonReader.ReadNextTokenAsString(); - break; - - case "projectName": - projectName = jsonReader.ReadNextTokenAsString(); - break; - - case "projectPath": - projectPath = jsonReader.ReadNextTokenAsString(); - break; - - case "projectStyle": - string projectStyleString = jsonReader.ReadNextTokenAsString(); - - if (!string.IsNullOrEmpty(projectStyleString) - && Enum.TryParse(projectStyleString, ignoreCase: true, result: out ProjectStyle projectStyleValue)) - { - projectStyle = projectStyleValue; - } - break; - - case "projectUniqueName": - projectUniqueName = jsonReader.ReadNextTokenAsString(); - break; - - case "restoreLockProperties": - string nuGetLockFilePath = null; - var restoreLockedMode = false; - string restorePackagesWithLockFile = null; - - jsonReader.ReadObject(restoreLockPropertiesPropertyName => - { - switch (restoreLockPropertiesPropertyName) - { - case "nuGetLockFilePath": - nuGetLockFilePath = jsonReader.ReadNextTokenAsString(); - break; - - case "restoreLockedMode": - restoreLockedMode = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "restorePackagesWithLockFile": - restorePackagesWithLockFile = jsonReader.ReadNextTokenAsString(); - break; - } - }); - - restoreLockProperties = new RestoreLockProperties(restorePackagesWithLockFile, nuGetLockFilePath, restoreLockedMode); - break; - - case "restoreAuditProperties": - string enableAudit = null, auditLevel = null, auditMode = null; - jsonReader.ReadObject(auditPropertyName => - { - - switch (auditPropertyName) - { - case "enableAudit": - enableAudit = jsonReader.ReadNextTokenAsString(); - break; - - case "auditLevel": - auditLevel = jsonReader.ReadNextTokenAsString(); - break; - - case "auditMode": - auditMode = jsonReader.ReadNextTokenAsString(); - break; - } - }); - auditProperties = new RestoreAuditProperties() - { - EnableAudit = enableAudit, - AuditLevel = auditLevel, - AuditMode = auditMode, - }; - break; - - case "skipContentFileWrite": - skipContentFileWrite = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "sources": - jsonReader.ReadObject(sourcePropertyName => - { - sources = sources ?? new List(); - - sources.Add(new PackageSource(sourcePropertyName)); - }); - break; - - case "validateRuntimeAssets": - validateRuntimeAssets = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "warningProperties": - var allWarningsAsErrors = false; - var noWarn = new HashSet(); - var warnAsError = new HashSet(); - var warningsNotAsErrors = new HashSet(); - - jsonReader.ReadObject(warningPropertiesPropertyName => - { - switch (warningPropertiesPropertyName) - { - case "allWarningsAsErrors": - allWarningsAsErrors = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "noWarn": - ReadNuGetLogCodes(jsonReader, noWarn); - break; - - case "warnAsError": - ReadNuGetLogCodes(jsonReader, warnAsError); - break; - - case "warnNotAsError": - ReadNuGetLogCodes(jsonReader, warningsNotAsErrors); - break; - } - }); - - warningProperties = new WarningProperties(warnAsError, noWarn, allWarningsAsErrors, warningsNotAsErrors); - break; - } - }); - - if (projectStyle == ProjectStyle.PackagesConfig) - { - msbuildMetadata = new PackagesConfigProjectRestoreMetadata() - { - PackagesConfigPath = packagesConfigPath - }; - } - else - { - msbuildMetadata = new ProjectRestoreMetadata(); - } - - msbuildMetadata.CentralPackageVersionsEnabled = centralPackageVersionsManagementEnabled; - msbuildMetadata.CentralPackageVersionOverrideDisabled = centralPackageVersionOverrideDisabled; - msbuildMetadata.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; - msbuildMetadata.RestoreAuditProperties = auditProperties; - - if (configFilePaths != null) - { - msbuildMetadata.ConfigFilePaths = configFilePaths; - } - - msbuildMetadata.CrossTargeting = crossTargeting; - - if (fallbackFolders != null) - { - msbuildMetadata.FallbackFolders = fallbackFolders; - } - - if (files != null) - { - msbuildMetadata.Files = files; - } - - msbuildMetadata.LegacyPackagesDirectory = legacyPackagesDirectory; - - if (originalTargetFrameworks != null) - { - msbuildMetadata.OriginalTargetFrameworks = originalTargetFrameworks; - } - - msbuildMetadata.OutputPath = outputPath; - msbuildMetadata.PackagesPath = packagesPath; - msbuildMetadata.ProjectJsonPath = projectJsonPath; - msbuildMetadata.ProjectName = projectName; - msbuildMetadata.ProjectPath = projectPath; - - if (projectStyle.HasValue) - { - msbuildMetadata.ProjectStyle = projectStyle.Value; - } - - msbuildMetadata.ProjectUniqueName = projectUniqueName; - - if (restoreLockProperties != null) - { - msbuildMetadata.RestoreLockProperties = restoreLockProperties; - } - - msbuildMetadata.SkipContentFileWrite = skipContentFileWrite; - - if (sources != null) - { - msbuildMetadata.Sources = sources; - } - - if (targetFrameworks != null) - { - msbuildMetadata.TargetFrameworks = targetFrameworks; - } - - msbuildMetadata.ValidateRuntimeAssets = validateRuntimeAssets; - - if (warningProperties != null) - { - msbuildMetadata.ProjectWideWarningProperties = warningProperties; - } - - packageSpec.RestoreMetadata = msbuildMetadata; - } - - private static bool ReadNextTokenAsBoolOrFalse(JsonTextReader jsonReader, string filePath) - { - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.Boolean) - { - try - { - return (bool)jsonReader.Value; - } - catch (Exception ex) - { - throw FileFormatException.Create(ex, jsonReader.LineNumber, jsonReader.LinePosition, filePath); - } - } - - return false; - } - - private static void ReadNuGetLogCodes(JsonTextReader jsonReader, HashSet hashCodes) - { - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) - { - while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) - { - if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) - { - hashCodes.Add(code); - } - } - } - } - - private static List ReadNuGetLogCodesList(JsonTextReader jsonReader) - { - List items = null; - - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) - { - while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) - { - if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) - { - items = items ?? new List(); - - items.Add(code); - } - } - } - - return items; - } - - private static void ReadPackageTypes(PackageSpec packageSpec, JsonTextReader jsonReader) - { - var errorLine = 0; - var errorColumn = 0; - - IReadOnlyList packageTypes = null; - PackageType packageType = null; - - try - { - if (jsonReader.ReadNextToken()) - { - errorLine = jsonReader.LineNumber; - errorColumn = jsonReader.LinePosition; - - switch (jsonReader.TokenType) - { - case JsonToken.String: - packageType = CreatePackageType(jsonReader); - - packageTypes = new[] { packageType }; - break; - - case JsonToken.StartArray: - var types = new List(); - - while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) - { - if (jsonReader.TokenType != JsonToken.String) - { - throw FileFormatException.Create( - string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageType, - PackageSpec.PackageSpecFileName), - errorLine, - errorColumn, - packageSpec.FilePath); - } - - packageType = CreatePackageType(jsonReader); - - types.Add(packageType); - } - - packageTypes = types; - break; - - case JsonToken.Null: - break; - - default: - throw new InvalidCastException(); - } - -#pragma warning disable CS0612 // Type or member is obsolete - if (packageTypes != null) - { - packageSpec.PackOptions.PackageType = packageTypes; - } -#pragma warning restore CS0612 // Type or member is obsolete - } - } - catch (Exception) - { - throw FileFormatException.Create( - string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageType, - PackageSpec.PackageSpecFileName), - errorLine, - errorColumn, - packageSpec.FilePath); - } - } - - [Obsolete] - private static void ReadPackInclude(JsonTextReader jsonReader, PackageSpec packageSpec) - { - jsonReader.ReadObject(propertyName => - { - string propertyValue = jsonReader.ReadAsString(); - - packageSpec.PackInclude.Add(new KeyValuePair(propertyName, propertyValue)); - }); - } - - [Obsolete] - private static void ReadPackOptions(JsonTextReader jsonReader, PackageSpec packageSpec, ref bool isMappingsNull) - { - var wasMappingsRead = false; - - bool isPackOptionsValueAnObject = jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "files": - wasMappingsRead = ReadPackOptionsFiles(packageSpec, jsonReader, wasMappingsRead); - break; - - case "iconUrl": - packageSpec.IconUrl = jsonReader.ReadNextTokenAsString(); - break; - - case "licenseUrl": - packageSpec.LicenseUrl = jsonReader.ReadNextTokenAsString(); - break; - - case "owners": - string[] owners = ReadStringArray(jsonReader); - - if (owners != null) - { - packageSpec.Owners = owners; - } - break; - - case "packageType": - ReadPackageTypes(packageSpec, jsonReader); - break; - - case "projectUrl": - packageSpec.ProjectUrl = jsonReader.ReadNextTokenAsString(); - break; - - case "releaseNotes": - packageSpec.ReleaseNotes = jsonReader.ReadNextTokenAsString(); - break; - - case "requireLicenseAcceptance": - packageSpec.RequireLicenseAcceptance = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "summary": - packageSpec.Summary = jsonReader.ReadNextTokenAsString(); - break; - - case "tags": - string[] tags = ReadStringArray(jsonReader); - - if (tags != null) - { - packageSpec.Tags = tags; - } - break; - } - }); - - isMappingsNull = isPackOptionsValueAnObject && !wasMappingsRead; - } - - [Obsolete] - private static bool ReadPackOptionsFiles(PackageSpec packageSpec, JsonTextReader jsonReader, bool wasMappingsRead) - { - IReadOnlyList excludeFiles = null; - IReadOnlyList exclude = null; - IReadOnlyList includeFiles = null; - IReadOnlyList include = null; - - jsonReader.ReadObject(filesPropertyName => - { - switch (filesPropertyName) - { - case "excludeFiles": - excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "exclude": - exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "includeFiles": - includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "include": - include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "mappings": - jsonReader.ReadObject(mappingsPropertyName => - { - wasMappingsRead = true; - - ReadMappings(jsonReader, mappingsPropertyName, packageSpec.PackOptions.Mappings); - }); - break; - } - }); - - if (include != null || includeFiles != null || exclude != null || excludeFiles != null) - { - packageSpec.PackOptions.IncludeExcludeFiles = new IncludeExcludeFiles() - { - ExcludeFiles = excludeFiles, - Exclude = exclude, - IncludeFiles = includeFiles, - Include = include - }; - } - - return wasMappingsRead; - } - - private static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader jsonReader, string dependencySetName) - { - List dependencies = null; - - jsonReader.ReadObject(propertyName => - { - dependencies ??= new List(); - - var dependency = new RuntimePackageDependency(propertyName, VersionRange.Parse(jsonReader.ReadNextTokenAsString())); - - dependencies.Add(dependency); - }); - - return new RuntimeDependencySet( - dependencySetName, - dependencies); - } - - private static RuntimeDescription ReadRuntimeDescription(JsonTextReader jsonReader, string runtimeName) - { - List inheritedRuntimes = null; - List additionalDependencies = null; - - jsonReader.ReadObject(propertyName => - { - if (propertyName == "#import") - { - inheritedRuntimes = jsonReader.ReadStringArrayAsList(); - } - else - { - additionalDependencies ??= new List(); - - RuntimeDependencySet dependency = ReadRuntimeDependencySet(jsonReader, propertyName); - - additionalDependencies.Add(dependency); - } - }); - - return new RuntimeDescription( - runtimeName, - inheritedRuntimes, - additionalDependencies); - } - - private static List ReadRuntimes(JsonTextReader jsonReader) - { - var runtimeDescriptions = new List(); - - jsonReader.ReadObject(propertyName => - { - RuntimeDescription runtimeDescription = ReadRuntimeDescription(jsonReader, propertyName); - - runtimeDescriptions.Add(runtimeDescription); - }); - - return runtimeDescriptions; - } - - [Obsolete] - private static void ReadScripts(JsonTextReader jsonReader, PackageSpec packageSpec) - { - jsonReader.ReadObject(propertyName => - { - if (jsonReader.ReadNextToken()) - { - if (jsonReader.TokenType == JsonToken.String) - { - packageSpec.Scripts[propertyName] = new string[] { (string)jsonReader.Value }; - } - else if (jsonReader.TokenType == JsonToken.StartArray) - { - var list = new List(); - - while (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.String) - { - list.Add((string)jsonReader.Value); - } - - packageSpec.Scripts[propertyName] = list; - } - else - { - throw FileFormatException.Create( - string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName), - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpec.FilePath); - } - } - }); - } - - private static string[] ReadStringArray(JsonTextReader jsonReader) - { - List list = jsonReader.ReadStringArrayAsList(); - - return list?.ToArray(); - } - - private static List ReadSupports(JsonTextReader jsonReader) - { - var compatibilityProfiles = new List(); - - jsonReader.ReadObject(propertyName => - { - CompatibilityProfile compatibilityProfile = ReadCompatibilityProfile(jsonReader, propertyName); - - compatibilityProfiles.Add(compatibilityProfile); - }); - - return compatibilityProfiles; - } - - private static LibraryDependencyTarget ReadTarget( - JsonTextReader jsonReader, - string packageSpecPath, - LibraryDependencyTarget targetFlagsValue) - { - if (jsonReader.ReadNextToken()) - { - var targetString = (string)jsonReader.Value; - - targetFlagsValue = LibraryDependencyTargetUtils.Parse(targetString); - - // Verify that the value specified is package, project, or external project - if (!ValidateDependencyTarget(targetFlagsValue)) - { - string message = string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidDependencyTarget, - targetString); - - throw FileFormatException.Create( - message, - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - } - - return targetFlagsValue; - } - - private static List ReadTargetFrameworks(JsonTextReader jsonReader) - { - var targetFrameworks = new List(); - - jsonReader.ReadObject(frameworkPropertyName => - { - NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); - var frameworkGroup = new ProjectRestoreMetadataFrameworkInfo(framework); - - jsonReader.ReadObject(propertyName => - { - if (propertyName == "projectReferences") - { - jsonReader.ReadObject(projectReferencePropertyName => - { - string excludeAssets = null; - string includeAssets = null; - string privateAssets = null; - string projectReferenceProjectPath = null; - - jsonReader.ReadObject(projectReferenceObjectPropertyName => - { - switch (projectReferenceObjectPropertyName) - { - case "excludeAssets": - excludeAssets = jsonReader.ReadNextTokenAsString(); - break; - - case "includeAssets": - includeAssets = jsonReader.ReadNextTokenAsString(); - break; - - case "privateAssets": - privateAssets = jsonReader.ReadNextTokenAsString(); - break; - - case "projectPath": - projectReferenceProjectPath = jsonReader.ReadNextTokenAsString(); - break; - } - }); - - frameworkGroup.ProjectReferences.Add(new ProjectRestoreReference() - { - ProjectUniqueName = projectReferencePropertyName, - ProjectPath = projectReferenceProjectPath, - - IncludeAssets = LibraryIncludeFlagUtils.GetFlags( - flags: includeAssets, - defaultFlags: LibraryIncludeFlags.All), - - ExcludeAssets = LibraryIncludeFlagUtils.GetFlags( - flags: excludeAssets, - defaultFlags: LibraryIncludeFlags.None), - - PrivateAssets = LibraryIncludeFlagUtils.GetFlags( - flags: privateAssets, - defaultFlags: LibraryIncludeFlagUtils.DefaultSuppressParent), - }); - }); - } - else if (propertyName == "targetAlias") - { - frameworkGroup.TargetAlias = jsonReader.ReadNextTokenAsString(); - } - }); - - targetFrameworks.Add(frameworkGroup); - }); - - return targetFrameworks; - } - - private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader jsonReader, out int frameworkLine, out int frameworkColumn) - { - frameworkLine = 0; - frameworkColumn = 0; - - NuGetFramework frameworkName = NuGetFramework.Parse((string)jsonReader.Value); - - var targetFrameworkInformation = new TargetFrameworkInformation(); - NuGetFramework secondaryFramework = default; - jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "assetTargetFallback": - targetFrameworkInformation.AssetTargetFallback = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "secondaryFramework": - var secondaryFrameworkString = jsonReader.ReadAsString(); - if (!string.IsNullOrEmpty(secondaryFrameworkString)) - { - secondaryFramework = NuGetFramework.Parse(secondaryFrameworkString); - } - break; - - case "centralPackageVersions": - ReadCentralPackageVersions( - jsonReader, - targetFrameworkInformation.CentralPackageVersions, - packageSpec.FilePath); - break; - - case "dependencies": - ReadDependencies( - jsonReader, - targetFrameworkInformation.Dependencies, - packageSpec.FilePath, - isGacOrFrameworkReference: false); - break; - - case "downloadDependencies": - ReadDownloadDependencies( - jsonReader, - targetFrameworkInformation.DownloadDependencies, - packageSpec.FilePath); - break; - - case "frameworkAssemblies": - ReadDependencies( - jsonReader, - targetFrameworkInformation.Dependencies, - packageSpec.FilePath, - isGacOrFrameworkReference: true); - break; - - case "frameworkReferences": - ReadFrameworkReferences( - jsonReader, - targetFrameworkInformation.FrameworkReferences, - packageSpec.FilePath); - break; - - case "imports": - ReadImports(packageSpec, jsonReader, targetFrameworkInformation); - break; - - case "runtimeIdentifierGraphPath": - targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); - break; - - case "targetAlias": - targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); - break; - - case "warn": - targetFrameworkInformation.Warn = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - } - }, out frameworkLine, out frameworkColumn); - - NuGetFramework updatedFramework = frameworkName; - - if (targetFrameworkInformation.Imports.Count > 0) - { - NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); - - if (targetFrameworkInformation.AssetTargetFallback) - { - updatedFramework = new AssetTargetFallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); - } - else - { - updatedFramework = new FallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); - } - } - else - { - updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); - } - - targetFrameworkInformation.FrameworkName = updatedFramework; - - packageSpec.TargetFrameworks.Add(targetFrameworkInformation); - } - - private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) - { - if (secondaryFramework != default) - { - return new DualCompatibilityFramework(frameworkName, secondaryFramework); - } - - return frameworkName; - } - - private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue) - { - var isValid = false; - - switch (targetValue) - { - case LibraryDependencyTarget.Package: - case LibraryDependencyTarget.Project: - case LibraryDependencyTarget.ExternalProject: - isValid = true; - break; - } - - return isValid; + return NjPackageSpecReader.GetPackageSpec(jsonReader, packageSpecPath); } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs index a03f1607291..b33a2cb1bcd 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs @@ -62,7 +62,9 @@ public LockFile Parse(string lockFileContent, ILogger log, string path) { using (var reader = new StringReader(lockFileContent)) { +#pragma warning disable CS0612 // Type or member is obsolete return Read(reader, log, path); +#pragma warning restore CS0612 // Type or member is obsolete } } @@ -88,15 +90,19 @@ public LockFile Read(Stream stream, ILogger log, string path) { using (var textReader = new StreamReader(stream)) { +#pragma warning disable CS0612 // Type or member is obsolete return Read(textReader, log, path); +#pragma warning restore CS0612 // Type or member is obsolete } } + [Obsolete] public LockFile Read(TextReader reader, string path) { return Read(reader, NullLogger.Instance, path); } + [Obsolete] public LockFile Read(TextReader reader, ILogger log, string path) { try @@ -161,6 +167,7 @@ public string Render(LockFile lockFile) } } + [Obsolete] private static LockFile ReadLockFile(JObject cursor, string path) { var lockFile = new LockFile() @@ -913,6 +920,7 @@ private static void WriteCentralTransitiveDependencyGroup(IObjectWriter writer, writer.WriteObjectEnd(); } + [Obsolete] private static List ReadProjectFileTransitiveDependencyGroup(JObject json, string path) { var results = new List(); @@ -930,7 +938,7 @@ private static List ReadProjectFileTransitiveD NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); var dependencies = new List(); - JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( + NjPackageSpecReader.ReadCentralTransitiveDependencyGroup( jsonReader: jsonReader, results: dependencies, packageSpecPath: path); diff --git a/src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs new file mode 100644 index 00000000000..9df79f0fe08 --- /dev/null +++ b/src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs @@ -0,0 +1,1765 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using NuGet.Common; +using NuGet.Configuration; +using NuGet.Frameworks; +using NuGet.LibraryModel; +using NuGet.Packaging.Core; +using NuGet.RuntimeModel; +using NuGet.Versioning; + +namespace NuGet.ProjectModel +{ + [Obsolete] + internal static class NjPackageSpecReader + { + private static readonly char[] DelimitedStringSeparators = { ' ', ',' }; + private static readonly char[] VersionSeparators = new[] { ';' }; + + internal static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, string snapshotValue = null) + { + using (var stringReader = new StringReader(json)) + using (var jsonReader = new JsonTextReader(stringReader)) + { + return GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); + } + } + + internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string packageSpecPath) + { + return GetPackageSpec(jsonReader, name: null, packageSpecPath, snapshotValue: null); + } + + internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string name, string packageSpecPath, string snapshotValue) + { + var packageSpec = new PackageSpec(); + + List compatibilityProfiles = null; + List runtimeDescriptions = null; + var wasPackOptionsSet = false; + var isMappingsNull = false; + + string filePath = name == null ? null : Path.GetFullPath(packageSpecPath); + + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrWhiteSpace(propertyName)) + { + return; + } + + switch (propertyName) + { +#pragma warning disable CS0612 // Type or member is obsolete + case "authors": + packageSpec.Authors = ReadStringArray(jsonReader) ?? Array.Empty(); + break; + + case "buildOptions": + ReadBuildOptions(jsonReader, packageSpec); + break; + + case "contentFiles": + List contentFiles = jsonReader.ReadStringArrayAsList(); + + if (contentFiles != null) + { + packageSpec.ContentFiles = contentFiles; + } + break; + + case "copyright": + packageSpec.Copyright = jsonReader.ReadNextTokenAsString(); + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "dependencies": + ReadDependencies( + jsonReader, + packageSpec.Dependencies, + filePath, + isGacOrFrameworkReference: false); + break; + +#pragma warning disable CS0612 // Type or member is obsolete + case "description": + packageSpec.Description = jsonReader.ReadNextTokenAsString(); + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "frameworks": + ReadFrameworks(jsonReader, packageSpec); + break; + +#pragma warning disable CS0612 // Type or member is obsolete + case "language": + packageSpec.Language = jsonReader.ReadNextTokenAsString(); + break; + + case "packInclude": + ReadPackInclude(jsonReader, packageSpec); + break; + + case "packOptions": + ReadPackOptions(jsonReader, packageSpec, ref isMappingsNull); + wasPackOptionsSet = true; + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "restore": + ReadMSBuildMetadata(jsonReader, packageSpec); + break; + + case "runtimes": + runtimeDescriptions = ReadRuntimes(jsonReader); + break; + +#pragma warning disable CS0612 // Type or member is obsolete + case "scripts": + ReadScripts(jsonReader, packageSpec); + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "supports": + compatibilityProfiles = ReadSupports(jsonReader); + break; + + case "title": + packageSpec.Title = jsonReader.ReadNextTokenAsString(); + break; + + case "version": + string version = jsonReader.ReadAsString(); + + if (version != null) + { + try + { +#pragma warning disable CS0612 // Type or member is obsolete + packageSpec.HasVersionSnapshot = PackageSpecUtility.IsSnapshotVersion(version); +#pragma warning restore CS0612 // Type or member is obsolete + packageSpec.Version = PackageSpecUtility.SpecifySnapshot(version, snapshotValue); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, version, packageSpec.FilePath); + } + } + break; + } + }); + + packageSpec.Name = name; + packageSpec.FilePath = name == null ? null : Path.GetFullPath(packageSpecPath); + +#pragma warning disable CS0612 // Type or member is obsolete + if (!wasPackOptionsSet) + { + packageSpec.Owners = Array.Empty(); + packageSpec.PackOptions = new PackOptions() + { + PackageType = Array.Empty() + }; + packageSpec.Tags = Array.Empty(); + } + + if (isMappingsNull) + { + packageSpec.PackOptions.Mappings = null; + } +#pragma warning restore CS0612 // Type or member is obsolete + + packageSpec.RuntimeGraph = new RuntimeGraph( + runtimeDescriptions ?? Enumerable.Empty(), + compatibilityProfiles ?? Enumerable.Empty()); + + if (packageSpec.Name == null) + { + packageSpec.Name = packageSpec.RestoreMetadata?.ProjectName; + } + + // Use the project.json path if one is set, otherwise use the project path + if (packageSpec.FilePath == null) + { + packageSpec.FilePath = packageSpec.RestoreMetadata?.ProjectJsonPath + ?? packageSpec.RestoreMetadata?.ProjectPath; + } + + return packageSpec; + } + + + internal static void ReadCentralTransitiveDependencyGroup( + JsonTextReader jsonReader, + IList results, + string packageSpecPath) + { + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrEmpty(propertyName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + if (jsonReader.ReadNextToken()) + { + int dependencyValueLine = jsonReader.LineNumber; + int dependencyValueColumn = jsonReader.LinePosition; + var versionLine = 0; + var versionColumn = 0; + + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + string dependencyVersionValue = null; + + if (jsonReader.TokenType == JsonToken.String) + { + dependencyVersionValue = (string)jsonReader.Value; + } + else if (jsonReader.TokenType == JsonToken.StartObject) + { + jsonReader.ReadProperties(dependenciesPropertyName => + { + IEnumerable values = null; + + switch (dependenciesPropertyName) + { + case "exclude": + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "include": + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "suppressParent": + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "version": + if (jsonReader.ReadNextToken()) + { + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + dependencyVersionValue = (string)jsonReader.Value; + } + break; + + default: + break; + } + }); + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + versionLine, + versionColumn, + packageSpecPath); + } + } + + if (dependencyVersionRange == null) + { + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + dependencyValueLine, + dependencyValueColumn, + packageSpecPath); + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = LibraryDependencyTarget.Package, + VersionRange = dependencyVersionRange + }, + + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + VersionCentrallyManaged = true, + ReferenceType = LibraryDependencyReferenceType.Transitive + }; + + results.Add(libraryDependency); + } + }); + } + + + private static PackageType CreatePackageType(JsonTextReader jsonReader) + { + var name = (string)jsonReader.Value; + + return new PackageType(name, Packaging.Core.PackageType.EmptyVersion); + } + + [Obsolete] + private static void ReadBuildOptions(JsonTextReader jsonReader, PackageSpec packageSpec) + { + packageSpec.BuildOptions = new BuildOptions(); + + jsonReader.ReadObject(buildOptionsPropertyName => + { + if (buildOptionsPropertyName == "outputName") + { + packageSpec.BuildOptions.OutputName = jsonReader.ReadNextTokenAsString(); + } + }); + } + + private static void ReadCentralPackageVersions( + JsonTextReader jsonReader, + IDictionary centralPackageVersions, + string filePath) + { + jsonReader.ReadObject(propertyName => + { + int line = jsonReader.LineNumber; + int column = jsonReader.LinePosition; + + if (string.IsNullOrEmpty(propertyName)) + { + throw FileFormatException.Create( + "Unable to resolve central version ''.", + line, + column, + filePath); + } + + string version = jsonReader.ReadNextTokenAsString(); + + if (string.IsNullOrEmpty(version)) + { + throw FileFormatException.Create( + "The version cannot be null or empty.", + line, + column, + filePath); + } + + centralPackageVersions[propertyName] = new CentralPackageVersion(propertyName, VersionRange.Parse(version)); + }); + } + + private static CompatibilityProfile ReadCompatibilityProfile(JsonTextReader jsonReader, string profileName) + { + List sets = null; + + jsonReader.ReadObject(propertyName => + { + sets = sets ?? new List(); + + IEnumerable profiles = ReadCompatibilitySets(jsonReader, propertyName); + + sets.AddRange(profiles); + }); + + return new CompatibilityProfile(profileName, sets ?? Enumerable.Empty()); + } + + private static IEnumerable ReadCompatibilitySets(JsonTextReader jsonReader, string compatibilitySetName) + { + NuGetFramework framework = NuGetFramework.Parse(compatibilitySetName); + + IReadOnlyList values = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList() ?? Array.Empty(); + + foreach (string value in values) + { + yield return new FrameworkRuntimePair(framework, value); + } + } + + private static void ReadDependencies( + JsonTextReader jsonReader, + IList results, + string packageSpecPath, + bool isGacOrFrameworkReference) + { + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrEmpty(propertyName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + // Support + // "dependencies" : { + // "Name" : "1.0" + // } + + if (jsonReader.ReadNextToken()) + { + int dependencyValueLine = jsonReader.LineNumber; + int dependencyValueColumn = jsonReader.LinePosition; + var versionLine = 0; + var versionColumn = 0; + + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + List noWarn = null; + + // This method handles both the dependencies and framework assembly sections. + // Framework references should be limited to references. + // Dependencies should allow everything but framework references. + LibraryDependencyTarget targetFlagsValue = isGacOrFrameworkReference + ? LibraryDependencyTarget.Reference + : LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference; + + var autoReferenced = false; + var generatePathProperty = false; + var versionCentrallyManaged = false; + string aliases = null; + string dependencyVersionValue = null; + VersionRange versionOverride = null; + + if (jsonReader.TokenType == JsonToken.String) + { + dependencyVersionValue = (string)jsonReader.Value; + } + else if (jsonReader.TokenType == JsonToken.StartObject) + { + jsonReader.ReadProperties(dependenciesPropertyName => + { + IEnumerable values = null; + + switch (dependenciesPropertyName) + { + case "autoReferenced": + autoReferenced = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); + break; + + case "exclude": + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "generatePathProperty": + generatePathProperty = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); + break; + + case "include": + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "noWarn": + noWarn = ReadNuGetLogCodesList(jsonReader); + break; + + case "suppressParent": + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "target": + targetFlagsValue = ReadTarget(jsonReader, packageSpecPath, targetFlagsValue); + break; + + case "version": + if (jsonReader.ReadNextToken()) + { + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + + dependencyVersionValue = (string)jsonReader.Value; + } + break; + case "versionOverride": + if (jsonReader.ReadNextToken()) + { + try + { + versionOverride = VersionRange.Parse((string)jsonReader.Value); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + } + break; + case "versionCentrallyManaged": + versionCentrallyManaged = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); + break; + + case "aliases": + aliases = jsonReader.ReadAsString(); + break; + } + }); + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + versionLine, + versionColumn, + packageSpecPath); + } + } + + // Projects and References may have empty version ranges, Packages may not + if (dependencyVersionRange == null) + { + if ((targetFlagsValue & LibraryDependencyTarget.Package) == LibraryDependencyTarget.Package) + { + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + dependencyValueLine, + dependencyValueColumn, + packageSpecPath); + } + else + { + // Projects and references with no version property allow all versions + dependencyVersionRange = VersionRange.All; + } + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = targetFlagsValue, + VersionRange = dependencyVersionRange + }, + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + AutoReferenced = autoReferenced, + GeneratePathProperty = generatePathProperty, + VersionCentrallyManaged = versionCentrallyManaged, + Aliases = aliases, + // The ReferenceType is not persisted to the assets file + // Default to LibraryDependencyReferenceType.Direct on Read + ReferenceType = LibraryDependencyReferenceType.Direct, + VersionOverride = versionOverride + }; + + if (noWarn != null) + { + libraryDependency.NoWarn = noWarn; + } + + results.Add(libraryDependency); + } + }); + } + + private static void ReadDownloadDependencies( + JsonTextReader jsonReader, + IList downloadDependencies, + string packageSpecPath) + { + var seenIds = new HashSet(); + + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) + { + do + { + string name = null; + string versionValue = null; + var isNameDefined = false; + var isVersionDefined = false; + int line = jsonReader.LineNumber; + int column = jsonReader.LinePosition; + int versionLine = 0; + int versionColumn = 0; + + jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "name": + isNameDefined = true; + name = jsonReader.ReadNextTokenAsString(); + break; + + case "version": + isVersionDefined = true; + versionValue = jsonReader.ReadNextTokenAsString(); + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + break; + } + }, out line, out column); + + if (jsonReader.TokenType == JsonToken.EndArray) + { + break; + } + + if (!isNameDefined) + { + throw FileFormatException.Create( + "Unable to resolve downloadDependency ''.", + line, + column, + packageSpecPath); + } + + if (!seenIds.Add(name)) + { + // package ID already seen, only use first definition. + continue; + } + + if (string.IsNullOrEmpty(versionValue)) + { + throw FileFormatException.Create( + "The version cannot be null or empty", + isVersionDefined ? versionLine : line, + isVersionDefined ? versionColumn : column, + packageSpecPath); + } + + string[] versions = versionValue.Split(VersionSeparators, StringSplitOptions.RemoveEmptyEntries); + + foreach (string singleVersionValue in versions) + { + try + { + VersionRange version = VersionRange.Parse(singleVersionValue); + + downloadDependencies.Add(new DownloadDependency(name, version)); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + isVersionDefined ? versionLine : line, + isVersionDefined ? versionColumn : column, + packageSpecPath); + } + } + } while (jsonReader.TokenType == JsonToken.EndObject); + } + } + + private static IReadOnlyList ReadEnumerableOfString(JsonTextReader jsonReader) + { + string value = jsonReader.ReadNextTokenAsString(); + + return value.Split(DelimitedStringSeparators, StringSplitOptions.RemoveEmptyEntries); + } + + private static void ReadFrameworkReferences( + JsonTextReader jsonReader, + ISet frameworkReferences, + string packageSpecPath) + { + jsonReader.ReadObject(frameworkName => + { + if (string.IsNullOrEmpty(frameworkName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve frameworkReference.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + var privateAssets = FrameworkDependencyFlagsUtils.Default; + + jsonReader.ReadObject(propertyName => + { + if (propertyName == "privateAssets") + { + IEnumerable strings = ReadEnumerableOfString(jsonReader); + + privateAssets = FrameworkDependencyFlagsUtils.GetFlags(strings); + } + }); + + frameworkReferences.Add(new FrameworkDependency(frameworkName, privateAssets)); + }); + } + + private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packageSpec) + { + jsonReader.ReadObject(_ => + { + var frameworkLine = 0; + var frameworkColumn = 0; + + try + { + ReadTargetFrameworks(packageSpec, jsonReader, out frameworkLine, out frameworkColumn); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, frameworkLine, frameworkColumn, packageSpec.FilePath); + } + }); + } + + private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) + { + int lineNumber = jsonReader.LineNumber; + int linePosition = jsonReader.LinePosition; + + IReadOnlyList imports = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + + if (imports != null && imports.Count > 0) + { + foreach (string import in imports.Where(element => !string.IsNullOrEmpty(element))) + { + NuGetFramework framework = NuGetFramework.Parse(import); + + if (!framework.IsSpecificFramework) + { + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.Log_InvalidImportFramework, + import, + PackageSpec.PackageSpecFileName), + lineNumber, + linePosition, + packageSpec.FilePath); + } + + targetFrameworkInformation.Imports.Add(framework); + } + } + } + + private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, IDictionary mappings) + { + if (jsonReader.ReadNextToken()) + { + switch (jsonReader.TokenType) + { + case JsonToken.String: + { + var files = new IncludeExcludeFiles() + { + Include = new[] { (string)jsonReader.Value } + }; + + mappings.Add(mappingKey, files); + } + break; + + case JsonToken.StartArray: + { + IReadOnlyList include = jsonReader.ReadStringArrayAsReadOnlyListFromArrayStart(); + + var files = new IncludeExcludeFiles() + { + Include = include + }; + + mappings.Add(mappingKey, files); + } + break; + + case JsonToken.StartObject: + { + IReadOnlyList excludeFiles = null; + IReadOnlyList exclude = null; + IReadOnlyList includeFiles = null; + IReadOnlyList include = null; + + jsonReader.ReadProperties(filesPropertyName => + { + switch (filesPropertyName) + { + case "excludeFiles": + excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "exclude": + exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "includeFiles": + includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "include": + include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + } + }); + + if (include != null || includeFiles != null || exclude != null || excludeFiles != null) + { + var files = new IncludeExcludeFiles() + { + ExcludeFiles = excludeFiles, + Exclude = exclude, + IncludeFiles = includeFiles, + Include = include + }; + + mappings.Add(mappingKey, files); + } + } + break; + } + } + } + + private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec packageSpec) + { + var centralPackageVersionsManagementEnabled = false; + var centralPackageVersionOverrideDisabled = false; + var CentralPackageTransitivePinningEnabled = false; + List configFilePaths = null; + var crossTargeting = false; + List fallbackFolders = null; + List files = null; + var legacyPackagesDirectory = false; + ProjectRestoreMetadata msbuildMetadata = null; + List originalTargetFrameworks = null; + string outputPath = null; + string packagesConfigPath = null; + string packagesPath = null; + string projectJsonPath = null; + string projectName = null; + string projectPath = null; + ProjectStyle? projectStyle = null; + string projectUniqueName = null; + RestoreLockProperties restoreLockProperties = null; + var skipContentFileWrite = false; + List sources = null; + List targetFrameworks = null; + var validateRuntimeAssets = false; + WarningProperties warningProperties = null; + RestoreAuditProperties auditProperties = null; + + jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "centralPackageVersionsManagementEnabled": + centralPackageVersionsManagementEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "centralPackageVersionOverrideDisabled": + centralPackageVersionOverrideDisabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "CentralPackageTransitivePinningEnabled": + CentralPackageTransitivePinningEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "configFilePaths": + configFilePaths = jsonReader.ReadStringArrayAsList(); + break; + + case "crossTargeting": + crossTargeting = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "fallbackFolders": + fallbackFolders = jsonReader.ReadStringArrayAsList(); + break; + + case "files": + jsonReader.ReadObject(filePropertyName => + { + files = files ?? new List(); + + files.Add(new ProjectRestoreMetadataFile(filePropertyName, jsonReader.ReadNextTokenAsString())); + }); + break; + + case "frameworks": + targetFrameworks = ReadTargetFrameworks(jsonReader); + break; + + case "legacyPackagesDirectory": + legacyPackagesDirectory = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "originalTargetFrameworks": + originalTargetFrameworks = jsonReader.ReadStringArrayAsList(); + break; + + case "outputPath": + outputPath = jsonReader.ReadNextTokenAsString(); + break; + + case "packagesConfigPath": + packagesConfigPath = jsonReader.ReadNextTokenAsString(); + break; + + case "packagesPath": + packagesPath = jsonReader.ReadNextTokenAsString(); + break; + + case "projectJsonPath": + projectJsonPath = jsonReader.ReadNextTokenAsString(); + break; + + case "projectName": + projectName = jsonReader.ReadNextTokenAsString(); + break; + + case "projectPath": + projectPath = jsonReader.ReadNextTokenAsString(); + break; + + case "projectStyle": + string projectStyleString = jsonReader.ReadNextTokenAsString(); + + if (!string.IsNullOrEmpty(projectStyleString) + && Enum.TryParse(projectStyleString, ignoreCase: true, result: out ProjectStyle projectStyleValue)) + { + projectStyle = projectStyleValue; + } + break; + + case "projectUniqueName": + projectUniqueName = jsonReader.ReadNextTokenAsString(); + break; + + case "restoreLockProperties": + string nuGetLockFilePath = null; + var restoreLockedMode = false; + string restorePackagesWithLockFile = null; + + jsonReader.ReadObject(restoreLockPropertiesPropertyName => + { + switch (restoreLockPropertiesPropertyName) + { + case "nuGetLockFilePath": + nuGetLockFilePath = jsonReader.ReadNextTokenAsString(); + break; + + case "restoreLockedMode": + restoreLockedMode = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "restorePackagesWithLockFile": + restorePackagesWithLockFile = jsonReader.ReadNextTokenAsString(); + break; + } + }); + + restoreLockProperties = new RestoreLockProperties(restorePackagesWithLockFile, nuGetLockFilePath, restoreLockedMode); + break; + + case "restoreAuditProperties": + string enableAudit = null, auditLevel = null, auditMode = null; + jsonReader.ReadObject(auditPropertyName => + { + + switch (auditPropertyName) + { + case "enableAudit": + enableAudit = jsonReader.ReadNextTokenAsString(); + break; + + case "auditLevel": + auditLevel = jsonReader.ReadNextTokenAsString(); + break; + + case "auditMode": + auditMode = jsonReader.ReadNextTokenAsString(); + break; + } + }); + auditProperties = new RestoreAuditProperties() + { + EnableAudit = enableAudit, + AuditLevel = auditLevel, + AuditMode = auditMode, + }; + break; + + case "skipContentFileWrite": + skipContentFileWrite = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "sources": + jsonReader.ReadObject(sourcePropertyName => + { + sources = sources ?? new List(); + + sources.Add(new PackageSource(sourcePropertyName)); + }); + break; + + case "validateRuntimeAssets": + validateRuntimeAssets = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "warningProperties": + var allWarningsAsErrors = false; + var noWarn = new HashSet(); + var warnAsError = new HashSet(); + var warningsNotAsErrors = new HashSet(); + + jsonReader.ReadObject(warningPropertiesPropertyName => + { + switch (warningPropertiesPropertyName) + { + case "allWarningsAsErrors": + allWarningsAsErrors = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "noWarn": + ReadNuGetLogCodes(jsonReader, noWarn); + break; + + case "warnAsError": + ReadNuGetLogCodes(jsonReader, warnAsError); + break; + + case "warnNotAsError": + ReadNuGetLogCodes(jsonReader, warningsNotAsErrors); + break; + } + }); + + warningProperties = new WarningProperties(warnAsError, noWarn, allWarningsAsErrors, warningsNotAsErrors); + break; + } + }); + + if (projectStyle == ProjectStyle.PackagesConfig) + { + msbuildMetadata = new PackagesConfigProjectRestoreMetadata() + { + PackagesConfigPath = packagesConfigPath + }; + } + else + { + msbuildMetadata = new ProjectRestoreMetadata(); + } + + msbuildMetadata.CentralPackageVersionsEnabled = centralPackageVersionsManagementEnabled; + msbuildMetadata.CentralPackageVersionOverrideDisabled = centralPackageVersionOverrideDisabled; + msbuildMetadata.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; + msbuildMetadata.RestoreAuditProperties = auditProperties; + + if (configFilePaths != null) + { + msbuildMetadata.ConfigFilePaths = configFilePaths; + } + + msbuildMetadata.CrossTargeting = crossTargeting; + + if (fallbackFolders != null) + { + msbuildMetadata.FallbackFolders = fallbackFolders; + } + + if (files != null) + { + msbuildMetadata.Files = files; + } + + msbuildMetadata.LegacyPackagesDirectory = legacyPackagesDirectory; + + if (originalTargetFrameworks != null) + { + msbuildMetadata.OriginalTargetFrameworks = originalTargetFrameworks; + } + + msbuildMetadata.OutputPath = outputPath; + msbuildMetadata.PackagesPath = packagesPath; + msbuildMetadata.ProjectJsonPath = projectJsonPath; + msbuildMetadata.ProjectName = projectName; + msbuildMetadata.ProjectPath = projectPath; + + if (projectStyle.HasValue) + { + msbuildMetadata.ProjectStyle = projectStyle.Value; + } + + msbuildMetadata.ProjectUniqueName = projectUniqueName; + + if (restoreLockProperties != null) + { + msbuildMetadata.RestoreLockProperties = restoreLockProperties; + } + + msbuildMetadata.SkipContentFileWrite = skipContentFileWrite; + + if (sources != null) + { + msbuildMetadata.Sources = sources; + } + + if (targetFrameworks != null) + { + msbuildMetadata.TargetFrameworks = targetFrameworks; + } + + msbuildMetadata.ValidateRuntimeAssets = validateRuntimeAssets; + + if (warningProperties != null) + { + msbuildMetadata.ProjectWideWarningProperties = warningProperties; + } + + packageSpec.RestoreMetadata = msbuildMetadata; + } + + private static bool ReadNextTokenAsBoolOrFalse(JsonTextReader jsonReader, string filePath) + { + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.Boolean) + { + try + { + return (bool)jsonReader.Value; + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, jsonReader.LineNumber, jsonReader.LinePosition, filePath); + } + } + + return false; + } + + private static void ReadNuGetLogCodes(JsonTextReader jsonReader, HashSet hashCodes) + { + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) + { + while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) + { + if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) + { + hashCodes.Add(code); + } + } + } + } + + private static List ReadNuGetLogCodesList(JsonTextReader jsonReader) + { + List items = null; + + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) + { + while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) + { + if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) + { + items = items ?? new List(); + + items.Add(code); + } + } + } + + return items; + } + + private static void ReadPackageTypes(PackageSpec packageSpec, JsonTextReader jsonReader) + { + var errorLine = 0; + var errorColumn = 0; + + IReadOnlyList packageTypes = null; + PackageType packageType = null; + + try + { + if (jsonReader.ReadNextToken()) + { + errorLine = jsonReader.LineNumber; + errorColumn = jsonReader.LinePosition; + + switch (jsonReader.TokenType) + { + case JsonToken.String: + packageType = CreatePackageType(jsonReader); + + packageTypes = new[] { packageType }; + break; + + case JsonToken.StartArray: + var types = new List(); + + while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) + { + if (jsonReader.TokenType != JsonToken.String) + { + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName), + errorLine, + errorColumn, + packageSpec.FilePath); + } + + packageType = CreatePackageType(jsonReader); + + types.Add(packageType); + } + + packageTypes = types; + break; + + case JsonToken.Null: + break; + + default: + throw new InvalidCastException(); + } + +#pragma warning disable CS0612 // Type or member is obsolete + if (packageTypes != null) + { + packageSpec.PackOptions.PackageType = packageTypes; + } +#pragma warning restore CS0612 // Type or member is obsolete + } + } + catch (Exception) + { + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName), + errorLine, + errorColumn, + packageSpec.FilePath); + } + } + + [Obsolete] + private static void ReadPackInclude(JsonTextReader jsonReader, PackageSpec packageSpec) + { + jsonReader.ReadObject(propertyName => + { + string propertyValue = jsonReader.ReadAsString(); + + packageSpec.PackInclude.Add(new KeyValuePair(propertyName, propertyValue)); + }); + } + + [Obsolete] + private static void ReadPackOptions(JsonTextReader jsonReader, PackageSpec packageSpec, ref bool isMappingsNull) + { + var wasMappingsRead = false; + + bool isPackOptionsValueAnObject = jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "files": + wasMappingsRead = ReadPackOptionsFiles(packageSpec, jsonReader, wasMappingsRead); + break; + + case "iconUrl": + packageSpec.IconUrl = jsonReader.ReadNextTokenAsString(); + break; + + case "licenseUrl": + packageSpec.LicenseUrl = jsonReader.ReadNextTokenAsString(); + break; + + case "owners": + string[] owners = ReadStringArray(jsonReader); + + if (owners != null) + { + packageSpec.Owners = owners; + } + break; + + case "packageType": + ReadPackageTypes(packageSpec, jsonReader); + break; + + case "projectUrl": + packageSpec.ProjectUrl = jsonReader.ReadNextTokenAsString(); + break; + + case "releaseNotes": + packageSpec.ReleaseNotes = jsonReader.ReadNextTokenAsString(); + break; + + case "requireLicenseAcceptance": + packageSpec.RequireLicenseAcceptance = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "summary": + packageSpec.Summary = jsonReader.ReadNextTokenAsString(); + break; + + case "tags": + string[] tags = ReadStringArray(jsonReader); + + if (tags != null) + { + packageSpec.Tags = tags; + } + break; + } + }); + + isMappingsNull = isPackOptionsValueAnObject && !wasMappingsRead; + } + + [Obsolete] + private static bool ReadPackOptionsFiles(PackageSpec packageSpec, JsonTextReader jsonReader, bool wasMappingsRead) + { + IReadOnlyList excludeFiles = null; + IReadOnlyList exclude = null; + IReadOnlyList includeFiles = null; + IReadOnlyList include = null; + + jsonReader.ReadObject(filesPropertyName => + { + switch (filesPropertyName) + { + case "excludeFiles": + excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "exclude": + exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "includeFiles": + includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "include": + include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "mappings": + jsonReader.ReadObject(mappingsPropertyName => + { + wasMappingsRead = true; + + ReadMappings(jsonReader, mappingsPropertyName, packageSpec.PackOptions.Mappings); + }); + break; + } + }); + + if (include != null || includeFiles != null || exclude != null || excludeFiles != null) + { + packageSpec.PackOptions.IncludeExcludeFiles = new IncludeExcludeFiles() + { + ExcludeFiles = excludeFiles, + Exclude = exclude, + IncludeFiles = includeFiles, + Include = include + }; + } + + return wasMappingsRead; + } + + private static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader jsonReader, string dependencySetName) + { + List dependencies = null; + + jsonReader.ReadObject(propertyName => + { + dependencies ??= new List(); + + var dependency = new RuntimePackageDependency(propertyName, VersionRange.Parse(jsonReader.ReadNextTokenAsString())); + + dependencies.Add(dependency); + }); + + return new RuntimeDependencySet( + dependencySetName, + dependencies); + } + + private static RuntimeDescription ReadRuntimeDescription(JsonTextReader jsonReader, string runtimeName) + { + List inheritedRuntimes = null; + List additionalDependencies = null; + + jsonReader.ReadObject(propertyName => + { + if (propertyName == "#import") + { + inheritedRuntimes = jsonReader.ReadStringArrayAsList(); + } + else + { + additionalDependencies ??= new List(); + + RuntimeDependencySet dependency = ReadRuntimeDependencySet(jsonReader, propertyName); + + additionalDependencies.Add(dependency); + } + }); + + return new RuntimeDescription( + runtimeName, + inheritedRuntimes, + additionalDependencies); + } + + private static List ReadRuntimes(JsonTextReader jsonReader) + { + var runtimeDescriptions = new List(); + + jsonReader.ReadObject(propertyName => + { + RuntimeDescription runtimeDescription = ReadRuntimeDescription(jsonReader, propertyName); + + runtimeDescriptions.Add(runtimeDescription); + }); + + return runtimeDescriptions; + } + + [Obsolete] + private static void ReadScripts(JsonTextReader jsonReader, PackageSpec packageSpec) + { + jsonReader.ReadObject(propertyName => + { + if (jsonReader.ReadNextToken()) + { + if (jsonReader.TokenType == JsonToken.String) + { + packageSpec.Scripts[propertyName] = new string[] { (string)jsonReader.Value }; + } + else if (jsonReader.TokenType == JsonToken.StartArray) + { + var list = new List(); + + while (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.String) + { + list.Add((string)jsonReader.Value); + } + + packageSpec.Scripts[propertyName] = list; + } + else + { + throw FileFormatException.Create( + string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName), + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpec.FilePath); + } + } + }); + } + + private static string[] ReadStringArray(JsonTextReader jsonReader) + { + List list = jsonReader.ReadStringArrayAsList(); + + return list?.ToArray(); + } + + private static List ReadSupports(JsonTextReader jsonReader) + { + var compatibilityProfiles = new List(); + + jsonReader.ReadObject(propertyName => + { + CompatibilityProfile compatibilityProfile = ReadCompatibilityProfile(jsonReader, propertyName); + + compatibilityProfiles.Add(compatibilityProfile); + }); + + return compatibilityProfiles; + } + + private static LibraryDependencyTarget ReadTarget( + JsonTextReader jsonReader, + string packageSpecPath, + LibraryDependencyTarget targetFlagsValue) + { + if (jsonReader.ReadNextToken()) + { + var targetString = (string)jsonReader.Value; + + targetFlagsValue = LibraryDependencyTargetUtils.Parse(targetString); + + // Verify that the value specified is package, project, or external project + if (!ValidateDependencyTarget(targetFlagsValue)) + { + string message = string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidDependencyTarget, + targetString); + + throw FileFormatException.Create( + message, + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + } + + return targetFlagsValue; + } + + private static List ReadTargetFrameworks(JsonTextReader jsonReader) + { + var targetFrameworks = new List(); + + jsonReader.ReadObject(frameworkPropertyName => + { + NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); + var frameworkGroup = new ProjectRestoreMetadataFrameworkInfo(framework); + + jsonReader.ReadObject(propertyName => + { + if (propertyName == "projectReferences") + { + jsonReader.ReadObject(projectReferencePropertyName => + { + string excludeAssets = null; + string includeAssets = null; + string privateAssets = null; + string projectReferenceProjectPath = null; + + jsonReader.ReadObject(projectReferenceObjectPropertyName => + { + switch (projectReferenceObjectPropertyName) + { + case "excludeAssets": + excludeAssets = jsonReader.ReadNextTokenAsString(); + break; + + case "includeAssets": + includeAssets = jsonReader.ReadNextTokenAsString(); + break; + + case "privateAssets": + privateAssets = jsonReader.ReadNextTokenAsString(); + break; + + case "projectPath": + projectReferenceProjectPath = jsonReader.ReadNextTokenAsString(); + break; + } + }); + + frameworkGroup.ProjectReferences.Add(new ProjectRestoreReference() + { + ProjectUniqueName = projectReferencePropertyName, + ProjectPath = projectReferenceProjectPath, + + IncludeAssets = LibraryIncludeFlagUtils.GetFlags( + flags: includeAssets, + defaultFlags: LibraryIncludeFlags.All), + + ExcludeAssets = LibraryIncludeFlagUtils.GetFlags( + flags: excludeAssets, + defaultFlags: LibraryIncludeFlags.None), + + PrivateAssets = LibraryIncludeFlagUtils.GetFlags( + flags: privateAssets, + defaultFlags: LibraryIncludeFlagUtils.DefaultSuppressParent), + }); + }); + } + else if (propertyName == "targetAlias") + { + frameworkGroup.TargetAlias = jsonReader.ReadNextTokenAsString(); + } + }); + + targetFrameworks.Add(frameworkGroup); + }); + + return targetFrameworks; + } + + private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader jsonReader, out int frameworkLine, out int frameworkColumn) + { + frameworkLine = 0; + frameworkColumn = 0; + + NuGetFramework frameworkName = NuGetFramework.Parse((string)jsonReader.Value); + + var targetFrameworkInformation = new TargetFrameworkInformation(); + NuGetFramework secondaryFramework = default; + jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "assetTargetFallback": + targetFrameworkInformation.AssetTargetFallback = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "secondaryFramework": + var secondaryFrameworkString = jsonReader.ReadAsString(); + if (!string.IsNullOrEmpty(secondaryFrameworkString)) + { + secondaryFramework = NuGetFramework.Parse(secondaryFrameworkString); + } + break; + + case "centralPackageVersions": + ReadCentralPackageVersions( + jsonReader, + targetFrameworkInformation.CentralPackageVersions, + packageSpec.FilePath); + break; + + case "dependencies": + ReadDependencies( + jsonReader, + targetFrameworkInformation.Dependencies, + packageSpec.FilePath, + isGacOrFrameworkReference: false); + break; + + case "downloadDependencies": + ReadDownloadDependencies( + jsonReader, + targetFrameworkInformation.DownloadDependencies, + packageSpec.FilePath); + break; + + case "frameworkAssemblies": + ReadDependencies( + jsonReader, + targetFrameworkInformation.Dependencies, + packageSpec.FilePath, + isGacOrFrameworkReference: true); + break; + + case "frameworkReferences": + ReadFrameworkReferences( + jsonReader, + targetFrameworkInformation.FrameworkReferences, + packageSpec.FilePath); + break; + + case "imports": + ReadImports(packageSpec, jsonReader, targetFrameworkInformation); + break; + + case "runtimeIdentifierGraphPath": + targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); + break; + + case "targetAlias": + targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); + break; + + case "warn": + targetFrameworkInformation.Warn = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + } + }, out frameworkLine, out frameworkColumn); + + NuGetFramework updatedFramework = frameworkName; + + if (targetFrameworkInformation.Imports.Count > 0) + { + NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); + + if (targetFrameworkInformation.AssetTargetFallback) + { + updatedFramework = new AssetTargetFallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); + } + else + { + updatedFramework = new FallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); + } + } + else + { + updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); + } + + targetFrameworkInformation.FrameworkName = updatedFramework; + + packageSpec.TargetFrameworks.Add(targetFrameworkInformation); + } + + private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) + { + if (secondaryFramework != default) + { + return new DualCompatibilityFramework(frameworkName, secondaryFramework); + } + + return frameworkName; + } + + private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue) + { + var isValid = false; + + switch (targetValue) + { + case LibraryDependencyTarget.Package: + case LibraryDependencyTarget.Project: + case LibraryDependencyTarget.ExternalProject: + isValid = true; + break; + } + + return isValid; + } + } +} diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs new file mode 100644 index 00000000000..7c679142c12 --- /dev/null +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs @@ -0,0 +1,1860 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using NuGet.Common; +using NuGet.Configuration; +using NuGet.Frameworks; +using NuGet.LibraryModel; +using NuGet.Packaging.Core; +using NuGet.RuntimeModel; +using NuGet.Versioning; + +namespace NuGet.ProjectModel +{ + internal static class Utf8JsonStreamPackageSpecReader + { + private static readonly char[] VersionSeparators = new[] { ';' }; + private static readonly byte[] Utf8Authors = Encoding.UTF8.GetBytes("authors"); + private static readonly byte[] BuildOptionsUtf8 = Encoding.UTF8.GetBytes("buildOptions"); + private static readonly byte[] Utf8ContentFiles = Encoding.UTF8.GetBytes("contentFiles"); + private static readonly byte[] Utf8Copyright = Encoding.UTF8.GetBytes("copyright"); + private static readonly byte[] Utf8Dependencies = Encoding.UTF8.GetBytes("dependencies"); + private static readonly byte[] Utf8Description = Encoding.UTF8.GetBytes("description"); + private static readonly byte[] Utf8Language = Encoding.UTF8.GetBytes("language"); + private static readonly byte[] Utf8PackInclude = Encoding.UTF8.GetBytes("packInclude"); + private static readonly byte[] Utf8PackOptions = Encoding.UTF8.GetBytes("packOptions"); + private static readonly byte[] Utf8Scripts = Encoding.UTF8.GetBytes("scripts"); + private static readonly byte[] Utf8Frameworks = Encoding.UTF8.GetBytes("frameworks"); + private static readonly byte[] Utf8Restore = Encoding.UTF8.GetBytes("restore"); + private static readonly byte[] Utf8Runtimes = Encoding.UTF8.GetBytes("runtimes"); + private static readonly byte[] Utf8Supports = Encoding.UTF8.GetBytes("supports"); + private static readonly byte[] Utf8Title = Encoding.UTF8.GetBytes("title"); + private static readonly byte[] Utf8Version = Encoding.UTF8.GetBytes("version"); + private static readonly byte[] Utf8OutputName = Encoding.UTF8.GetBytes("outputName"); + private static readonly byte[] Utf8AutoReferenced = Encoding.UTF8.GetBytes("autoReferenced"); + private static readonly byte[] Utf8Exclude = Encoding.UTF8.GetBytes("exclude"); + private static readonly byte[] Utf8GeneratePathProperty = Encoding.UTF8.GetBytes("generatePathProperty"); + private static readonly byte[] Utf8Include = Encoding.UTF8.GetBytes("include"); + private static readonly byte[] Utf8NoWarn = Encoding.UTF8.GetBytes("noWarn"); + private static readonly byte[] Utf8SuppressParent = Encoding.UTF8.GetBytes("suppressParent"); + private static readonly byte[] Utf8Target = Encoding.UTF8.GetBytes("target"); + private static readonly byte[] Utf8VersionOverride = Encoding.UTF8.GetBytes("versionOverride"); + private static readonly byte[] Utf8VersionCentrallyManaged = Encoding.UTF8.GetBytes("versionCentrallyManaged"); + private static readonly byte[] Utf8Aliases = Encoding.UTF8.GetBytes("aliases"); + private static readonly byte[] Utf8Name = Encoding.UTF8.GetBytes("name"); + private static readonly byte[] Utf8PrivateAssets = Encoding.UTF8.GetBytes("privateAssets"); + private static readonly byte[] Utf8ExcludeFiles = Encoding.UTF8.GetBytes("excludeFiles"); + private static readonly byte[] Utf8IncludeFiles = Encoding.UTF8.GetBytes("includeFiles"); + private static readonly byte[] Utf8CentralPackageVersionsManagementEnabled = Encoding.UTF8.GetBytes("centralPackageVersionsManagementEnabled"); + private static readonly byte[] Utf8CentralPackageVersionOverrideDisabled = Encoding.UTF8.GetBytes("centralPackageVersionOverrideDisabled"); + private static readonly byte[] Utf8CentralPackageTransitivePinningEnabled = Encoding.UTF8.GetBytes("CentralPackageTransitivePinningEnabled"); + private static readonly byte[] Utf8ConfigFilePaths = Encoding.UTF8.GetBytes("configFilePaths"); + private static readonly byte[] Utf8CrossTargeting = Encoding.UTF8.GetBytes("crossTargeting"); + private static readonly byte[] Utf8FallbackFolders = Encoding.UTF8.GetBytes("fallbackFolders"); + private static readonly byte[] Utf8Files = Encoding.UTF8.GetBytes("files"); + private static readonly byte[] Utf8LegacyPackagesDirectory = Encoding.UTF8.GetBytes("legacyPackagesDirectory"); + private static readonly byte[] Utf8OriginalTargetFrameworks = Encoding.UTF8.GetBytes("originalTargetFrameworks"); + private static readonly byte[] Utf8OutputPath = Encoding.UTF8.GetBytes("outputPath"); + private static readonly byte[] Utf8PackagesConfigPath = Encoding.UTF8.GetBytes("packagesConfigPath"); + private static readonly byte[] Utf8PackagesPath = Encoding.UTF8.GetBytes("packagesPath"); + private static readonly byte[] Utf8ProjectJsonPath = Encoding.UTF8.GetBytes("projectJsonPath"); + private static readonly byte[] Utf8ProjectName = Encoding.UTF8.GetBytes("projectName"); + private static readonly byte[] Utf8ProjectPath = Encoding.UTF8.GetBytes("projectPath"); + private static readonly byte[] Utf8ProjectStyle = Encoding.UTF8.GetBytes("projectStyle"); + private static readonly byte[] Utf8ProjectUniqueName = Encoding.UTF8.GetBytes("projectUniqueName"); + private static readonly byte[] Utf8RestoreLockProperties = Encoding.UTF8.GetBytes("restoreLockProperties"); + private static readonly byte[] Utf8NuGetLockFilePath = Encoding.UTF8.GetBytes("nuGetLockFilePath"); + private static readonly byte[] Utf8RestoreLockedMode = Encoding.UTF8.GetBytes("restoreLockedMode"); + private static readonly byte[] Utf8RestorePackagesWithLockFile = Encoding.UTF8.GetBytes("restorePackagesWithLockFile"); + private static readonly byte[] Utf8RestoreAuditProperties = Encoding.UTF8.GetBytes("restoreAuditProperties"); + private static readonly byte[] Utf8EnableAudit = Encoding.UTF8.GetBytes("enableAudit"); + private static readonly byte[] Utf8AuditLevel = Encoding.UTF8.GetBytes("auditLevel"); + private static readonly byte[] Utf8AuditMode = Encoding.UTF8.GetBytes("auditMode"); + private static readonly byte[] Utf8SkipContentFileWrite = Encoding.UTF8.GetBytes("skipContentFileWrite"); + private static readonly byte[] Utf8Sources = Encoding.UTF8.GetBytes("sources"); + private static readonly byte[] Utf8ValidateRuntimeAssets = Encoding.UTF8.GetBytes("validateRuntimeAssets"); + private static readonly byte[] Utf8WarningProperties = Encoding.UTF8.GetBytes("warningProperties"); + private static readonly byte[] Utf8AllWarningsAsErrors = Encoding.UTF8.GetBytes("allWarningsAsErrors"); + private static readonly byte[] Utf8WarnAsError = Encoding.UTF8.GetBytes("warnAsError"); + private static readonly byte[] Utf8WarnNotAsError = Encoding.UTF8.GetBytes("warnNotAsError"); + private static readonly byte[] Utf8ExcludeAssets = Encoding.UTF8.GetBytes("excludeAssets"); + private static readonly byte[] Utf8IncludeAssets = Encoding.UTF8.GetBytes("includeAssets"); + private static readonly byte[] Utf8TargetAlias = Encoding.UTF8.GetBytes("targetAlias"); + private static readonly byte[] Utf8AssetTargetFallback = Encoding.UTF8.GetBytes("assetTargetFallback"); + private static readonly byte[] Utf8SecondaryFramework = Encoding.UTF8.GetBytes("secondaryFramework"); + private static readonly byte[] Utf8CentralPackageVersions = Encoding.UTF8.GetBytes("centralPackageVersions"); + private static readonly byte[] Utf8DownloadDependencies = Encoding.UTF8.GetBytes("downloadDependencies"); + private static readonly byte[] Utf8FrameworkAssemblies = Encoding.UTF8.GetBytes("frameworkAssemblies"); + private static readonly byte[] Utf8FrameworkReferences = Encoding.UTF8.GetBytes("frameworkReferences"); + private static readonly byte[] Utf8Imports = Encoding.UTF8.GetBytes("imports"); + private static readonly byte[] Utf8RuntimeIdentifierGraphPath = Encoding.UTF8.GetBytes("runtimeIdentifierGraphPath"); + private static readonly byte[] Utf8Warn = Encoding.UTF8.GetBytes("warn"); + private static readonly byte[] Utf8IconUrl = Encoding.UTF8.GetBytes("iconUrl"); + private static readonly byte[] Utf8LicenseUrl = Encoding.UTF8.GetBytes("licenseUrl"); + private static readonly byte[] Utf8Owners = Encoding.UTF8.GetBytes("owners"); + private static readonly byte[] Utf8PackageType = Encoding.UTF8.GetBytes("packageType"); + private static readonly byte[] Utf8ProjectUrl = Encoding.UTF8.GetBytes("projectUrl"); + private static readonly byte[] Utf8ReleaseNotes = Encoding.UTF8.GetBytes("releaseNotes"); + private static readonly byte[] Utf8RequireLicenseAcceptance = Encoding.UTF8.GetBytes("requireLicenseAcceptance"); + private static readonly byte[] Utf8Summary = Encoding.UTF8.GetBytes("summary"); + private static readonly byte[] Utf8Tags = Encoding.UTF8.GetBytes("tags"); + private static readonly byte[] Utf8Mappings = Encoding.UTF8.GetBytes("mappings"); + private static readonly byte[] Utf8HashTagImport = Encoding.UTF8.GetBytes("#import"); + private static readonly byte[] Utf8ProjectReferences = Encoding.UTF8.GetBytes("projectReferences"); + private static readonly byte[] Utf8EmptyString = Encoding.UTF8.GetBytes(string.Empty); + + internal static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, string snapshotValue = null) + { + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + { + return GetPackageSpec(stream, name, packageSpecPath, snapshotValue); + } + } + + internal static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue) + { + var reader = new Utf8JsonStreamReader(stream); + PackageSpec packageSpec; + try + { + packageSpec = GetPackageSpec(ref reader, name, packageSpecPath, snapshotValue); + } + catch (JsonException innerException) + { + throw FileFormatException.Create(innerException, packageSpecPath); + } + + if (!string.IsNullOrEmpty(name)) + { + packageSpec.Name = name; + if (!string.IsNullOrEmpty(packageSpecPath)) + { + packageSpec.FilePath = Path.GetFullPath(packageSpecPath); + + } + } + return packageSpec; + } + + internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, string name, string packageSpecPath, string snapshotValue) + { + var packageSpec = new PackageSpec(); + + List compatibilityProfiles = null; + List runtimeDescriptions = null; + var wasPackOptionsSet = false; + var isMappingsNull = false; + string filePath = name == null ? null : Path.GetFullPath(packageSpecPath); + + if (jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8EmptyString)) + { + jsonReader.Skip(); + } +#pragma warning disable CS0612 // Type or member is obsolete + else if (jsonReader.ValueTextEquals(Utf8Authors)) + { + jsonReader.Read(); + if (jsonReader.TokenType == JsonTokenType.StartArray) + { + packageSpec.Authors = jsonReader.ReadStringArrayAsIList()?.ToArray(); + } + if (packageSpec.Authors == null) + { + packageSpec.Authors = Array.Empty(); + } + } + else if (jsonReader.ValueTextEquals(BuildOptionsUtf8)) + { + ReadBuildOptions(ref jsonReader, packageSpec); + } + else if (jsonReader.ValueTextEquals(Utf8ContentFiles)) + { + jsonReader.Read(); + jsonReader.ReadStringArrayAsIList(packageSpec.ContentFiles); + } + else if (jsonReader.ValueTextEquals(Utf8Copyright)) + { + packageSpec.Copyright = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Description)) + { + packageSpec.Description = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Language)) + { + packageSpec.Language = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8PackInclude)) + { + ReadPackInclude(ref jsonReader, packageSpec); + } + else if (jsonReader.ValueTextEquals(Utf8PackOptions)) + { + ReadPackOptions(ref jsonReader, packageSpec, ref isMappingsNull); + wasPackOptionsSet = true; + } + else if (jsonReader.ValueTextEquals(Utf8Scripts)) + { + ReadScripts(ref jsonReader, packageSpec); + } +#pragma warning restore CS0612 // Type or member is + else if (jsonReader.ValueTextEquals(Utf8Dependencies)) + { + ReadDependencies( + ref jsonReader, + packageSpec.Dependencies, + filePath, + isGacOrFrameworkReference: false); + } + else if (jsonReader.ValueTextEquals(Utf8Frameworks)) + { + ReadFrameworks(ref jsonReader, packageSpec); + } + else if (jsonReader.ValueTextEquals(Utf8Restore)) + { + ReadMSBuildMetadata(ref jsonReader, packageSpec); + } + else if (jsonReader.ValueTextEquals(Utf8Runtimes)) + { + runtimeDescriptions = ReadRuntimes(ref jsonReader); + } + else if (jsonReader.ValueTextEquals(Utf8Supports)) + { + compatibilityProfiles = ReadSupports(ref jsonReader); + } + else if (jsonReader.ValueTextEquals(Utf8Title)) + { + packageSpec.Title = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Version)) + { + string version = jsonReader.ReadNextTokenAsString(); + if (version != null) + { + try + { +#pragma warning disable CS0612 // Type or member is obsolete + packageSpec.HasVersionSnapshot = PackageSpecUtility.IsSnapshotVersion(version); +#pragma warning restore CS0612 // Type or member is obsolete + packageSpec.Version = PackageSpecUtility.SpecifySnapshot(version, snapshotValue); + } + catch (Exception ex) + { + throw new JsonException($"Error processing versino property. version: {version}", innerException: ex); + } + } + } + else + { + jsonReader.Skip(); + } + } + } + packageSpec.Name = name; + packageSpec.FilePath = name == null ? null : Path.GetFullPath(packageSpecPath); + +#pragma warning disable CS0612 // Type or member is obsolete + if (!wasPackOptionsSet) + { + packageSpec.Owners = Array.Empty(); + packageSpec.PackOptions = new PackOptions() + { + PackageType = Array.Empty() + }; + packageSpec.Tags = Array.Empty(); + } + + if (isMappingsNull) + { + packageSpec.PackOptions.Mappings = null; + } +#pragma warning restore CS0612 // Type or member is obsolete + + packageSpec.RuntimeGraph = new RuntimeGraph( + runtimeDescriptions ?? Enumerable.Empty(), + compatibilityProfiles ?? Enumerable.Empty()); + + if (packageSpec.Name == null) + { + packageSpec.Name = packageSpec.RestoreMetadata?.ProjectName; + } + + // Use the project.json path if one is set, otherwise use the project path + if (packageSpec.FilePath == null) + { + packageSpec.FilePath = packageSpec.RestoreMetadata?.ProjectJsonPath + ?? packageSpec.RestoreMetadata?.ProjectPath; + } + + return packageSpec; + } + + internal static void ReadCentralTransitiveDependencyGroup( + ref Utf8JsonStreamReader jsonReader, + IList results, + string packageSpecPath) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + if (string.IsNullOrEmpty(propertyName)) + { + var exception = new JsonException("Unable to resolve dependency ''."); + exception.Data.Add(FileFormatException.SurfaceMessage, true); + throw exception; + } + + if (jsonReader.Read()) + { + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + string dependencyVersionValue = null; + + if (jsonReader.TokenType == JsonTokenType.String) + { + dependencyVersionValue = jsonReader.GetString(); + } + else if (jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + IEnumerable values = null; + + if (jsonReader.ValueTextEquals(Utf8Exclude)) + { + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(Utf8Include)) + { + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(Utf8SuppressParent)) + { + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(Utf8Version)) + { + if (jsonReader.Read()) + { + dependencyVersionValue = jsonReader.GetString(); + } + } + else + { + jsonReader.Skip(); + } + } + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw new JsonException(null, ex); + } + } + + if (dependencyVersionRange == null) + { + throw new JsonException(Strings.MissingVersionOnDependency, new ArgumentException(Strings.MissingVersionOnDependency)); + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = LibraryDependencyTarget.Package, + VersionRange = dependencyVersionRange + }, + + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + VersionCentrallyManaged = true, + ReferenceType = LibraryDependencyReferenceType.Transitive + }; + + results.Add(libraryDependency); + } + } + } + } + + private static void ReadDependencies( + ref Utf8JsonStreamReader jsonReader, + IList results, + string packageSpecPath, + bool isGacOrFrameworkReference) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + if (string.IsNullOrEmpty(propertyName)) + { + var exception = new JsonException("Unable to resolve dependency ''."); + exception.Data.Add(FileFormatException.SurfaceMessage, true); + throw exception; + } + + // Support + // "dependencies" : { + // "Name" : "1.0" + // } + + if (jsonReader.Read()) + { + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + List noWarn = null; + + // This method handles both the dependencies and framework assembly sections. + // Framework references should be limited to references. + // Dependencies should allow everything but framework references. + LibraryDependencyTarget targetFlagsValue = isGacOrFrameworkReference + ? LibraryDependencyTarget.Reference + : LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference; + + var autoReferenced = false; + var generatePathProperty = false; + var versionCentrallyManaged = false; + string aliases = null; + string dependencyVersionValue = null; + VersionRange versionOverride = null; + + if (jsonReader.TokenType == JsonTokenType.String) + { + dependencyVersionValue = jsonReader.GetString(); + } + else if (jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + IEnumerable values = null; + if (jsonReader.ValueTextEquals(Utf8AutoReferenced)) + { + autoReferenced = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8Exclude)) + { + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(Utf8GeneratePathProperty)) + { + generatePathProperty = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8Include)) + { + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(Utf8NoWarn)) + { + noWarn = ReadNuGetLogCodesList(ref jsonReader); + } + else if (jsonReader.ValueTextEquals(Utf8SuppressParent)) + { + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(Utf8Target)) + { + targetFlagsValue = ReadTarget(ref jsonReader, packageSpecPath, targetFlagsValue); + } + else if (jsonReader.ValueTextEquals(Utf8Version)) + { + if (jsonReader.Read()) + { + dependencyVersionValue = jsonReader.GetString(); + } + } + else if (jsonReader.ValueTextEquals(Utf8VersionOverride)) + { + if (jsonReader.Read()) + { + var versionPropValue = jsonReader.GetString(); + try + { + versionOverride = VersionRange.Parse(versionPropValue); + } + catch (Exception ex) + { + throw new JsonException(ex.Message, innerException: ex); + } + } + } + else if (jsonReader.ValueTextEquals(Utf8VersionCentrallyManaged)) + { + versionCentrallyManaged = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8Aliases)) + { + aliases = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + } + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw new JsonException(ex.Message, ex); + } + } + + // Projects and References may have empty version ranges, Packages may not + if (dependencyVersionRange == null) + { + if ((targetFlagsValue & LibraryDependencyTarget.Package) == LibraryDependencyTarget.Package) + { + throw new JsonException(Strings.MissingVersionOnDependency, new ArgumentException(Strings.MissingVersionOnDependency)); + } + else + { + // Projects and references with no version property allow all versions + dependencyVersionRange = VersionRange.All; + } + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = targetFlagsValue, + VersionRange = dependencyVersionRange + }, + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + AutoReferenced = autoReferenced, + GeneratePathProperty = generatePathProperty, + VersionCentrallyManaged = versionCentrallyManaged, + Aliases = aliases, + // The ReferenceType is not persisted to the assets file + // Default to LibraryDependencyReferenceType.Direct on Read + ReferenceType = LibraryDependencyReferenceType.Direct, + VersionOverride = versionOverride + }; + + if (noWarn != null) + { + libraryDependency.NoWarn = noWarn; + } + + results.Add(libraryDependency); + } + } + } + } + + private static PackageType CreatePackageType(ref Utf8JsonStreamReader jsonReader) + { + var name = jsonReader.GetString(); + + return new PackageType(name, Packaging.Core.PackageType.EmptyVersion); + } + + [Obsolete] + private static void ReadBuildOptions(ref Utf8JsonStreamReader jsonReader, PackageSpec packageSpec) + { + packageSpec.BuildOptions = new BuildOptions(); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8OutputName)) + { + packageSpec.BuildOptions.OutputName = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + } + } + } + + private static void ReadCentralPackageVersions( + ref Utf8JsonStreamReader jsonReader, + IDictionary centralPackageVersions) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + + if (string.IsNullOrEmpty(propertyName)) + { + var exception = new JsonException("Unable to resolve central version ''."); + throw exception; + } + + string version = jsonReader.ReadNextTokenAsString(); + + if (string.IsNullOrEmpty(version)) + { + var exception = new JsonException("The version cannot be null or empty."); + throw exception; + } + + centralPackageVersions[propertyName] = new CentralPackageVersion(propertyName, VersionRange.Parse(version)); + } + } + } + + private static CompatibilityProfile ReadCompatibilityProfile(ref Utf8JsonStreamReader jsonReader, string profileName) + { + List sets = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + sets = sets ?? new List(); + + IReadOnlyList values = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList() ?? Array.Empty(); + + IEnumerable profiles = ReadCompatibilitySets(values, propertyName); + + sets.AddRange(profiles); + } + } + return new CompatibilityProfile(profileName, sets ?? Enumerable.Empty()); + } + + private static IEnumerable ReadCompatibilitySets(IReadOnlyList values, string compatibilitySetName) + { + NuGetFramework framework = NuGetFramework.Parse(compatibilitySetName); + + foreach (string value in values) + { + yield return new FrameworkRuntimePair(framework, value); + } + } + + private static void ReadDownloadDependencies( + ref Utf8JsonStreamReader jsonReader, + IList downloadDependencies, + string packageSpecPath) + { + var seenIds = new HashSet(); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartArray) + { + do + { + string name = null; + string versionValue = null; + var isNameDefined = false; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8Name)) + { + isNameDefined = true; + name = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Version)) + { + versionValue = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + } + } + + if (jsonReader.TokenType == JsonTokenType.EndArray) + { + break; + } + + if (!isNameDefined) + { + var exception = new JsonException("Unable to resolve downloadDependency ''."); + throw exception; + } + + if (!seenIds.Add(name)) + { + // package ID already seen, only use first definition. + continue; + } + + if (string.IsNullOrEmpty(versionValue)) + { + var exception = new JsonException("The version cannot be null or empty"); + throw exception; + } + + string[] versions = versionValue.Split(VersionSeparators, StringSplitOptions.RemoveEmptyEntries); + + foreach (string singleVersionValue in versions) + { + try + { + VersionRange version = VersionRange.Parse(singleVersionValue); + + downloadDependencies.Add(new DownloadDependency(name, version)); + } + catch (Exception ex) + { + throw new JsonException(ex.Message, ex); + } + } + } while (jsonReader.TokenType == JsonTokenType.EndObject); + } + } + + private static void ReadFrameworkReferences( + ref Utf8JsonStreamReader jsonReader, + ISet frameworkReferences, + string packageSpecPath) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var frameworkName = jsonReader.GetString(); + if (string.IsNullOrEmpty(frameworkName)) + { + var exception = new JsonException("Unable to resolve frameworkReference."); + throw exception; + } + + var privateAssets = FrameworkDependencyFlagsUtils.Default; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8PrivateAssets)) + { + IEnumerable strings = jsonReader.ReadDelimitedString(); + + privateAssets = FrameworkDependencyFlagsUtils.GetFlags(strings); + } + else + { + jsonReader.Skip(); + } + } + } + + frameworkReferences.Add(new FrameworkDependency(frameworkName, privateAssets)); + } + } + } + + private static void ReadFrameworks(ref Utf8JsonStreamReader reader, PackageSpec packageSpec) + { + if (reader.Read() && reader.TokenType == JsonTokenType.StartObject) + { + while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) + { + ReadTargetFrameworks(packageSpec, ref reader); + } + } + } + + private static void ReadImports(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) + { + IReadOnlyList imports = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + + if (imports != null && imports.Count > 0) + { + foreach (string import in imports.Where(element => !string.IsNullOrEmpty(element))) + { + NuGetFramework framework = NuGetFramework.Parse(import); + + if (!framework.IsSpecificFramework) + { + var exception = new JsonException(string.Format( + CultureInfo.CurrentCulture, + Strings.Log_InvalidImportFramework, + import, + PackageSpec.PackageSpecFileName)); + throw exception; + } + + targetFrameworkInformation.Imports.Add(framework); + } + } + } + + private static void ReadMappings(ref Utf8JsonStreamReader jsonReader, string mappingKey, IDictionary mappings) + { + if (jsonReader.Read()) + { + switch (jsonReader.TokenType) + { + case JsonTokenType.String: + { + var files = new IncludeExcludeFiles() + { + Include = new[] { (string)jsonReader.GetString() } + }; + + mappings.Add(mappingKey, files); + } + break; + case JsonTokenType.StartArray: + { + IReadOnlyList include = jsonReader.ReadStringArrayAsReadOnlyListFromArrayStart(); + + var files = new IncludeExcludeFiles() + { + Include = include + }; + + mappings.Add(mappingKey, files); + } + break; + case JsonTokenType.StartObject: + { + IReadOnlyList excludeFiles = null; + IReadOnlyList exclude = null; + IReadOnlyList includeFiles = null; + IReadOnlyList include = null; + + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8ExcludeFiles)) + { + excludeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8Exclude)) + { + exclude = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8IncludeFiles)) + { + includeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8Include)) + { + include = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else + { + jsonReader.Skip(); + } + } + + if (include != null || includeFiles != null || exclude != null || excludeFiles != null) + { + var files = new IncludeExcludeFiles() + { + ExcludeFiles = excludeFiles, + Exclude = exclude, + IncludeFiles = includeFiles, + Include = include + }; + + mappings.Add(mappingKey, files); + } + } + break; + } + } + } + + private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, PackageSpec packageSpec) + { + var centralPackageVersionsManagementEnabled = false; + var centralPackageVersionOverrideDisabled = false; + var CentralPackageTransitivePinningEnabled = false; + List configFilePaths = null; + var crossTargeting = false; + List fallbackFolders = null; + List files = null; + var legacyPackagesDirectory = false; + ProjectRestoreMetadata msbuildMetadata = null; + List originalTargetFrameworks = null; + string outputPath = null; + string packagesConfigPath = null; + string packagesPath = null; + string projectJsonPath = null; + string projectName = null; + string projectPath = null; + ProjectStyle? projectStyle = null; + string projectUniqueName = null; + RestoreLockProperties restoreLockProperties = null; + var skipContentFileWrite = false; + List sources = null; + List targetFrameworks = null; + var validateRuntimeAssets = false; + WarningProperties warningProperties = null; + RestoreAuditProperties auditProperties = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8CentralPackageVersionsManagementEnabled)) + { + centralPackageVersionsManagementEnabled = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8CentralPackageVersionOverrideDisabled)) + { + centralPackageVersionOverrideDisabled = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8CentralPackageTransitivePinningEnabled)) + { + CentralPackageTransitivePinningEnabled = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8ConfigFilePaths)) + { + jsonReader.Read(); + configFilePaths = jsonReader.ReadStringArrayAsIList() as List; + } + else if (jsonReader.ValueTextEquals(Utf8CrossTargeting)) + { + crossTargeting = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8FallbackFolders)) + { + jsonReader.Read(); + fallbackFolders = jsonReader.ReadStringArrayAsIList() as List; + } + else if (jsonReader.ValueTextEquals(Utf8Files)) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var filePropertyName = jsonReader.GetString(); + files = files ?? new List(); + + files.Add(new ProjectRestoreMetadataFile(filePropertyName, jsonReader.ReadNextTokenAsString())); + } + } + } + else if (jsonReader.ValueTextEquals(Utf8Frameworks)) + { + targetFrameworks = ReadTargetFrameworks(ref jsonReader); + } + else if (jsonReader.ValueTextEquals(Utf8LegacyPackagesDirectory)) + { + legacyPackagesDirectory = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8OriginalTargetFrameworks)) + { + jsonReader.Read(); + originalTargetFrameworks = jsonReader.ReadStringArrayAsIList() as List; + } + else if (jsonReader.ValueTextEquals(Utf8OutputPath)) + { + outputPath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8PackagesConfigPath)) + { + packagesConfigPath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8PackagesPath)) + { + packagesPath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8ProjectJsonPath)) + { + projectJsonPath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8ProjectName)) + { + projectName = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8ProjectPath)) + { + projectPath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8ProjectStyle)) + { + string projectStyleString = jsonReader.ReadNextTokenAsString(); + + if (!string.IsNullOrEmpty(projectStyleString) + && Enum.TryParse(projectStyleString, ignoreCase: true, result: out ProjectStyle projectStyleValue)) + { + projectStyle = projectStyleValue; + } + } + else if (jsonReader.ValueTextEquals(Utf8ProjectUniqueName)) + { + projectUniqueName = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8RestoreLockProperties)) + { + string nuGetLockFilePath = null; + var restoreLockedMode = false; + string restorePackagesWithLockFile = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8NuGetLockFilePath)) + { + nuGetLockFilePath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8RestoreLockedMode)) + { + restoreLockedMode = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8RestorePackagesWithLockFile)) + { + restorePackagesWithLockFile = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + } + } + restoreLockProperties = new RestoreLockProperties(restorePackagesWithLockFile, nuGetLockFilePath, restoreLockedMode); + } + else if (jsonReader.ValueTextEquals(Utf8RestoreAuditProperties)) + { + string enableAudit = null, auditLevel = null, auditMode = null; + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8EnableAudit)) + { + enableAudit = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8AuditLevel)) + { + auditLevel = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8AuditMode)) + { + auditMode = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + } + } + auditProperties = new RestoreAuditProperties() + { + EnableAudit = enableAudit, + AuditLevel = auditLevel, + AuditMode = auditMode, + }; + } + else if (jsonReader.ValueTextEquals(Utf8SkipContentFileWrite)) + { + skipContentFileWrite = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8Sources)) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var sourcePropertyName = jsonReader.GetString(); + sources = sources ?? new List(); + + sources.Add(new PackageSource(sourcePropertyName)); + jsonReader.Skip(); + } + } + } + else if (jsonReader.ValueTextEquals(Utf8ValidateRuntimeAssets)) + { + validateRuntimeAssets = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8WarningProperties)) + { + var allWarningsAsErrors = false; + var noWarn = new HashSet(); + var warnAsError = new HashSet(); + var warningsNotAsErrors = new HashSet(); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8AllWarningsAsErrors)) + { + allWarningsAsErrors = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8NoWarn)) + { + ReadNuGetLogCodes(ref jsonReader, noWarn); + } + else if (jsonReader.ValueTextEquals(Utf8WarnAsError)) + { + ReadNuGetLogCodes(ref jsonReader, warnAsError); + } + else if (jsonReader.ValueTextEquals(Utf8WarnNotAsError)) + { + ReadNuGetLogCodes(ref jsonReader, warningsNotAsErrors); + } + else + { + jsonReader.Skip(); + } + } + } + + warningProperties = new WarningProperties(warnAsError, noWarn, allWarningsAsErrors, warningsNotAsErrors); + } + else + { + jsonReader.Skip(); + } + } + } + + if (projectStyle == ProjectStyle.PackagesConfig) + { + msbuildMetadata = new PackagesConfigProjectRestoreMetadata() + { + PackagesConfigPath = packagesConfigPath + }; + } + else + { + msbuildMetadata = new ProjectRestoreMetadata(); + } + + msbuildMetadata.CentralPackageVersionsEnabled = centralPackageVersionsManagementEnabled; + msbuildMetadata.CentralPackageVersionOverrideDisabled = centralPackageVersionOverrideDisabled; + msbuildMetadata.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; + msbuildMetadata.RestoreAuditProperties = auditProperties; + + if (configFilePaths != null) + { + msbuildMetadata.ConfigFilePaths = configFilePaths; + } + + msbuildMetadata.CrossTargeting = crossTargeting; + + if (fallbackFolders != null) + { + msbuildMetadata.FallbackFolders = fallbackFolders; + } + + if (files != null) + { + msbuildMetadata.Files = files; + } + + msbuildMetadata.LegacyPackagesDirectory = legacyPackagesDirectory; + + if (originalTargetFrameworks != null) + { + msbuildMetadata.OriginalTargetFrameworks = originalTargetFrameworks; + } + + msbuildMetadata.OutputPath = outputPath; + msbuildMetadata.PackagesPath = packagesPath; + msbuildMetadata.ProjectJsonPath = projectJsonPath; + msbuildMetadata.ProjectName = projectName; + msbuildMetadata.ProjectPath = projectPath; + + if (projectStyle.HasValue) + { + msbuildMetadata.ProjectStyle = projectStyle.Value; + } + + msbuildMetadata.ProjectUniqueName = projectUniqueName; + + if (restoreLockProperties != null) + { + msbuildMetadata.RestoreLockProperties = restoreLockProperties; + } + + msbuildMetadata.SkipContentFileWrite = skipContentFileWrite; + + if (sources != null) + { + msbuildMetadata.Sources = sources; + } + + if (targetFrameworks != null) + { + msbuildMetadata.TargetFrameworks = targetFrameworks; + } + + msbuildMetadata.ValidateRuntimeAssets = validateRuntimeAssets; + + if (warningProperties != null) + { + msbuildMetadata.ProjectWideWarningProperties = warningProperties; + } + + packageSpec.RestoreMetadata = msbuildMetadata; + } + + private static void ReadNuGetLogCodes(ref Utf8JsonStreamReader jsonReader, HashSet hashCodes) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartArray) + { + while (jsonReader.Read() && jsonReader.TokenType != JsonTokenType.EndArray) + { + if (jsonReader.TokenType == JsonTokenType.String && Enum.TryParse(jsonReader.GetString(), out NuGetLogCode code)) + { + hashCodes.Add(code); + } + } + } + } + + private static List ReadNuGetLogCodesList(ref Utf8JsonStreamReader jsonReader) + { + List items = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartArray) + { + while (jsonReader.Read() && jsonReader.TokenType != JsonTokenType.EndArray) + { + if (jsonReader.TokenType == JsonTokenType.String && Enum.TryParse(jsonReader.GetString(), out NuGetLogCode code)) + { + items = items ?? new List(); + + items.Add(code); + } + } + } + return items; + } + + private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader) + { + IReadOnlyList packageTypes = null; + PackageType packageType = null; + + try + { + if (jsonReader.Read()) + { + switch (jsonReader.TokenType) + { + case JsonTokenType.String: + packageType = CreatePackageType(ref jsonReader); + + packageTypes = new[] { packageType }; + break; + + case JsonTokenType.StartArray: + var types = new List(); + + while (jsonReader.Read() && jsonReader.TokenType != JsonTokenType.EndArray) + { + if (jsonReader.TokenType != JsonTokenType.String) + { + var exception = new JsonException(string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName)); + exception.Data.Add(FileFormatException.SurfaceMessage, true); + throw exception; + } + + packageType = CreatePackageType(ref jsonReader); + + types.Add(packageType); + } + + packageTypes = types; + break; + + case JsonTokenType.Null: + break; + default: + throw new InvalidCastException(); + } + +#pragma warning disable CS0612 // Type or member is obsolete + if (packageTypes != null) + { + packageSpec.PackOptions.PackageType = packageTypes; + } +#pragma warning restore CS0612 // Type or member is obsolete + } + } + catch (Exception) + { + var exception = new JsonException(string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName)); + exception.Data.Add(FileFormatException.SurfaceMessage, true); + throw exception; + } + } + + [Obsolete] + private static void ReadPackInclude(ref Utf8JsonStreamReader jsonReader, PackageSpec packageSpec) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + string propertyName = jsonReader.GetString(); + string propertyValue = jsonReader.ReadNextTokenAsString(); + + packageSpec.PackInclude.Add(new KeyValuePair(propertyName, propertyValue)); + } + } + } + + [Obsolete] + private static void ReadPackOptions(ref Utf8JsonStreamReader jsonReader, PackageSpec packageSpec, ref bool isMappingsNull) + { + var wasMappingsRead = false; + bool isPackOptionsValueAnObject = false; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + isPackOptionsValueAnObject = true; + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8Files)) + { + wasMappingsRead = ReadPackOptionsFiles(packageSpec, ref jsonReader, wasMappingsRead); + } + else if (jsonReader.ValueTextEquals(Utf8IconUrl)) + { + packageSpec.IconUrl = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8LicenseUrl)) + { + packageSpec.LicenseUrl = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Owners)) + { + jsonReader.Read(); + string[] owners = jsonReader.ReadStringArrayAsIList()?.ToArray(); + if (owners != null) + { + packageSpec.Owners = owners; + } + } + else if (jsonReader.ValueTextEquals(Utf8PackageType)) + { + ReadPackageTypes(packageSpec, ref jsonReader); + } + else if (jsonReader.ValueTextEquals(Utf8ProjectUrl)) + { + packageSpec.ProjectUrl = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8ReleaseNotes)) + { + packageSpec.ReleaseNotes = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8RequireLicenseAcceptance)) + { + packageSpec.RequireLicenseAcceptance = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8Summary)) + { + packageSpec.Summary = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Tags)) + { + jsonReader.Read(); + string[] tags = jsonReader.ReadStringArrayAsIList()?.ToArray(); + + if (tags != null) + { + packageSpec.Tags = tags; + } + } + else + { + jsonReader.Skip(); + } + } + } + isMappingsNull = isPackOptionsValueAnObject && !wasMappingsRead; + } + + [Obsolete] + private static bool ReadPackOptionsFiles(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader, bool wasMappingsRead) + { + IReadOnlyList excludeFiles = null; + IReadOnlyList exclude = null; + IReadOnlyList includeFiles = null; + IReadOnlyList include = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var filesPropertyName = jsonReader.GetString(); + if (jsonReader.ValueTextEquals(Utf8ExcludeFiles)) + { + excludeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8Exclude)) + { + exclude = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8IncludeFiles)) + { + includeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8Include)) + { + include = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); + } + else if (jsonReader.ValueTextEquals(Utf8Mappings)) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + wasMappingsRead = true; + var mappingsPropertyName = jsonReader.GetString(); + ReadMappings(ref jsonReader, mappingsPropertyName, packageSpec.PackOptions.Mappings); + } + } + } + else + { + jsonReader.Skip(); + } + } + } + + if (include != null || includeFiles != null || exclude != null || excludeFiles != null) + { + packageSpec.PackOptions.IncludeExcludeFiles = new IncludeExcludeFiles() + { + ExcludeFiles = excludeFiles, + Exclude = exclude, + IncludeFiles = includeFiles, + Include = include + }; + } + + return wasMappingsRead; + } + + private static RuntimeDependencySet ReadRuntimeDependencySet(ref Utf8JsonStreamReader jsonReader, string dependencySetName) + { + List dependencies = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + dependencies ??= new List(); + + var dependency = new RuntimePackageDependency(propertyName, VersionRange.Parse(jsonReader.ReadNextTokenAsString())); + + dependencies.Add(dependency); + } + } + + return new RuntimeDependencySet( + dependencySetName, + dependencies); + } + + private static RuntimeDescription ReadRuntimeDescription(ref Utf8JsonStreamReader jsonReader, string runtimeName) + { + List inheritedRuntimes = null; + List additionalDependencies = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8HashTagImport)) + { + jsonReader.Read(); + inheritedRuntimes = jsonReader.ReadStringArrayAsIList() as List; + } + else + { + var propertyName = jsonReader.GetString(); + additionalDependencies ??= new List(); + + RuntimeDependencySet dependency = ReadRuntimeDependencySet(ref jsonReader, propertyName); + + additionalDependencies.Add(dependency); + } + } + } + + return new RuntimeDescription( + runtimeName, + inheritedRuntimes, + additionalDependencies); + } + + private static List ReadRuntimes(ref Utf8JsonStreamReader jsonReader) + { + var runtimeDescriptions = new List(); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + RuntimeDescription runtimeDescription = ReadRuntimeDescription(ref jsonReader, jsonReader.GetString()); + + runtimeDescriptions.Add(runtimeDescription); + } + } + + return runtimeDescriptions; + } + + [Obsolete] + private static void ReadScripts(ref Utf8JsonStreamReader jsonReader, PackageSpec packageSpec) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + if (jsonReader.Read()) + { + if (jsonReader.TokenType == JsonTokenType.String) + { + packageSpec.Scripts[propertyName] = new string[] { (string)jsonReader.GetString() }; + } + else if (jsonReader.TokenType == JsonTokenType.StartArray) + { + var list = new List(); + + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.String) + { + list.Add(jsonReader.GetString()); + } + + packageSpec.Scripts[propertyName] = list; + } + else + { + var exception = new JsonException(string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName)); + exception.Data.Add(FileFormatException.SurfaceMessage, true); + throw exception; + } + } + } + } + } + + private static List ReadSupports(ref Utf8JsonStreamReader jsonReader) + { + var compatibilityProfiles = new List(); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var propertyName = jsonReader.GetString(); + CompatibilityProfile compatibilityProfile = ReadCompatibilityProfile(ref jsonReader, propertyName); + + compatibilityProfiles.Add(compatibilityProfile); + } + } + return compatibilityProfiles; + } + + private static LibraryDependencyTarget ReadTarget( + ref Utf8JsonStreamReader jsonReader, + string packageSpecPath, + LibraryDependencyTarget targetFlagsValue) + { + if (jsonReader.Read()) + { + var targetString = jsonReader.GetString(); + + targetFlagsValue = LibraryDependencyTargetUtils.Parse(targetString); + + // Verify that the value specified is package, project, or external project + if (!ValidateDependencyTarget(targetFlagsValue)) + { + string message = string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidDependencyTarget, + targetString); + var exception = new JsonException(message); + throw exception; + } + } + + return targetFlagsValue; + } + + private static List ReadTargetFrameworks(ref Utf8JsonStreamReader jsonReader) + { + var targetFrameworks = new List(); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var frameworkPropertyName = jsonReader.GetString(); + NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); + var frameworkGroup = new ProjectRestoreMetadataFrameworkInfo(framework); + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8ProjectReferences)) + { + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + var projectReferencePropertyName = jsonReader.GetString(); + string excludeAssets = null; + string includeAssets = null; + string privateAssets = null; + string projectReferenceProjectPath = null; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8ExcludeAssets)) + { + excludeAssets = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8IncludeAssets)) + { + includeAssets = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8PrivateAssets)) + { + privateAssets = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8ProjectPath)) + { + projectReferenceProjectPath = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + + } + } + + frameworkGroup.ProjectReferences.Add(new ProjectRestoreReference() + { + ProjectUniqueName = projectReferencePropertyName, + ProjectPath = projectReferenceProjectPath, + + IncludeAssets = LibraryIncludeFlagUtils.GetFlags( + flags: includeAssets, + defaultFlags: LibraryIncludeFlags.All), + + ExcludeAssets = LibraryIncludeFlagUtils.GetFlags( + flags: excludeAssets, + defaultFlags: LibraryIncludeFlags.None), + + PrivateAssets = LibraryIncludeFlagUtils.GetFlags( + flags: privateAssets, + defaultFlags: LibraryIncludeFlagUtils.DefaultSuppressParent), + }); + } + } + } + else if (jsonReader.ValueTextEquals(Utf8TargetAlias)) + { + frameworkGroup.TargetAlias = jsonReader.ReadNextTokenAsString(); + } + else + { + jsonReader.Skip(); + } + } + + targetFrameworks.Add(frameworkGroup); + } + } + } + return targetFrameworks; + } + + private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader) + { + var frameworkName = NuGetFramework.Parse(jsonReader.GetString()); + + var targetFrameworkInformation = new TargetFrameworkInformation(); + NuGetFramework secondaryFramework = default; + + if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(Utf8AssetTargetFallback)) + { + targetFrameworkInformation.AssetTargetFallback = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else if (jsonReader.ValueTextEquals(Utf8SecondaryFramework)) + { + var secondaryFrameworkString = jsonReader.ReadNextTokenAsString(); + if (!string.IsNullOrEmpty(secondaryFrameworkString)) + { + secondaryFramework = NuGetFramework.Parse(secondaryFrameworkString); + } + } + else if (jsonReader.ValueTextEquals(Utf8CentralPackageVersions)) + { + ReadCentralPackageVersions( + ref jsonReader, + targetFrameworkInformation.CentralPackageVersions); + } + else if (jsonReader.ValueTextEquals(Utf8Dependencies)) + { + ReadDependencies( + ref jsonReader, + targetFrameworkInformation.Dependencies, + packageSpec.FilePath, + isGacOrFrameworkReference: false); + } + else if (jsonReader.ValueTextEquals(Utf8DownloadDependencies)) + { + ReadDownloadDependencies( + ref jsonReader, + targetFrameworkInformation.DownloadDependencies, + packageSpec.FilePath); + } + else if (jsonReader.ValueTextEquals(Utf8FrameworkAssemblies)) + { + ReadDependencies( + ref jsonReader, + targetFrameworkInformation.Dependencies, + packageSpec.FilePath, + isGacOrFrameworkReference: true); + } + else if (jsonReader.ValueTextEquals(Utf8FrameworkReferences)) + { + ReadFrameworkReferences( + ref jsonReader, + targetFrameworkInformation.FrameworkReferences, + packageSpec.FilePath); + } + else if (jsonReader.ValueTextEquals(Utf8Imports)) + { + ReadImports(packageSpec, ref jsonReader, targetFrameworkInformation); + } + else if (jsonReader.ValueTextEquals(Utf8RuntimeIdentifierGraphPath)) + { + targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8TargetAlias)) + { + targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); + } + else if (jsonReader.ValueTextEquals(Utf8Warn)) + { + targetFrameworkInformation.Warn = jsonReader.ReadNextTokenAsBoolOrFalse(); + } + else + { + jsonReader.Skip(); + } + } + } + + NuGetFramework updatedFramework = frameworkName; + + if (targetFrameworkInformation.Imports.Count > 0) + { + NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); + + if (targetFrameworkInformation.AssetTargetFallback) + { + updatedFramework = new AssetTargetFallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); + } + else + { + updatedFramework = new FallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); + } + } + else + { + updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); + } + + targetFrameworkInformation.FrameworkName = updatedFramework; + + packageSpec.TargetFrameworks.Add(targetFrameworkInformation); + } + + private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) + { + if (secondaryFramework != default) + { + return new DualCompatibilityFramework(frameworkName, secondaryFramework); + } + + return frameworkName; + } + + private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue) + { + var isValid = false; + + switch (targetValue) + { + case LibraryDependencyTarget.Package: + case LibraryDependencyTarget.Project: + case LibraryDependencyTarget.ExternalProject: + isValid = true; + break; + } + + return isValid; + } + } +} diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index 14e73f00898..b3bfdd938b1 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using FluentAssertions; using Newtonsoft.Json; using NuGet.Common; @@ -20,6 +19,7 @@ namespace NuGet.ProjectModel.Test { [UseCulture("")] // Fix tests failing on systems with non-English locales + [Obsolete] public class JsonPackageSpecReaderTests { [Fact] @@ -42,7 +42,7 @@ public void PackageSpecReader_PackageMissingVersion() try { - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); } catch (Exception ex) { @@ -69,7 +69,7 @@ public void PackageSpecReader_ProjectMissingVersion() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); var range = spec.Dependencies.Single().LibraryRange.VersionRange; // Assert @@ -96,7 +96,7 @@ public void PackageSpecReader_PackageEmptyVersion() try { - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); } catch (Exception ex) { @@ -127,7 +127,7 @@ public void PackageSpecReader_PackageWhitespaceVersion() try { - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); } catch (Exception ex) { @@ -153,7 +153,7 @@ public void PackageSpecReader_FrameworkAssemblyEmptyVersion() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); var range = spec.TargetFrameworks.Single().Dependencies.Single().LibraryRange.VersionRange; // Assert @@ -175,7 +175,7 @@ public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform() }"; // Act - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("redist")); @@ -209,7 +209,7 @@ public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform() public void PackageSpecReader_PackOptions_Default(string json) { // Arrange & Act - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert Assert.NotNull(actual.PackOptions); @@ -251,7 +251,7 @@ public void PackageSpecReader_PackOptions_ValidPackageType(string json, string[] .ToArray(); // Act - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert Assert.NotNull(actual.PackOptions); @@ -315,7 +315,7 @@ public void PackageSpecReader_PackOptions_InvalidPackageType(string json) { // Arrange & Act & Assert var actual = Assert.Throws( - () => JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json")); + () => NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json")); Assert.Contains("The pack options package type must be a string or array of strings in 'project.json'.", actual.Message); } @@ -337,7 +337,7 @@ public void PackageSpecReader_PackOptions_Files1() } } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert Assert.NotNull(actual.PackOptions); @@ -379,7 +379,7 @@ public void PackageSpecReader_PackOptions_Files2() } } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert Assert.NotNull(actual.PackOptions); @@ -436,7 +436,7 @@ public void PackageSpecReader_PackOptions_Files2() public void PackageSpecReader_BuildOptions(string json, string expectedValue, bool nullBuildOptions) { // Arrange & Act - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert if (nullBuildOptions) @@ -467,7 +467,7 @@ public void PackageSpecReader_ReadsWithoutRestoreSettings() }, }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert Assert.NotNull(actual); @@ -495,7 +495,7 @@ public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn() }, }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); @@ -525,7 +525,7 @@ public void PackageSpecReader_ReadsDependencyWithSingleNoWarn() }, }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); @@ -553,7 +553,7 @@ public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn() }, }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); @@ -616,7 +616,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningProperties() } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -682,7 +682,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_NoW } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -743,7 +743,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_War } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -806,7 +806,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_All } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -864,7 +864,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithEmptyWarningPropertiesAnd( } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -917,7 +917,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithNoWarningProperties() } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -948,7 +948,7 @@ public void PackageSpecReader_RuntimeIdentifierPathNullIfEmpty() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert Assert.Null(spec.TargetFrameworks.First().RuntimeIdentifierGraphPath); @@ -3477,7 +3477,7 @@ public void PackageSpecReader_ReadsRestoreMetadataWithAliases() } }"; - var actual = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); // Assert var metadata = actual.RestoreMetadata; @@ -3487,7 +3487,6 @@ public void PackageSpecReader_ReadsRestoreMetadataWithAliases() Assert.Equal("alias", metadata.TargetFrameworks.Single().TargetAlias); } - [Fact] public void PackageSpecReader_Read() { @@ -3524,7 +3523,7 @@ public void PackageSpecReader_Read() { var dependencies = new List(); NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); - JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( + NjPackageSpecReader.ReadCentralTransitiveDependencyGroup( jsonReader: jsonReader, results: dependencies, packageSpecPath: "SomePath"); @@ -3598,9 +3597,10 @@ public void GetPackageSpec_WithRestoreAuditProperties_ReturnsRestoreAuditPropert private static PackageSpec GetPackageSpec(string json) { - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + using (var stringReader = new StringReader(json)) + using (var stream = new JsonTextReader(stringReader)) { - return JsonPackageSpecReader.GetPackageSpec(stream, name: null, packageSpecPath: null, snapshotValue: null); + return NjPackageSpecReader.GetPackageSpec(stream, name: null, packageSpecPath: null, snapshotValue: null); } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs new file mode 100644 index 00000000000..4d97217c904 --- /dev/null +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs @@ -0,0 +1,3635 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using FluentAssertions; +using NuGet.Common; +using NuGet.Configuration; +using NuGet.Frameworks; +using NuGet.LibraryModel; +using NuGet.Packaging.Core; +using NuGet.RuntimeModel; +using NuGet.Versioning; +using Xunit; + +namespace NuGet.ProjectModel.Test +{ + [UseCulture("")] // Fix tests failing on systems with non-English locales + public class Utf8JsonStreamPackageSpecReaderTests + { + [Fact] + public void PackageSpecReader_PackageMissingVersion() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""type"": ""build"" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; + + // Act + Exception exception = null; + + try + { + var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + } + catch (Exception ex) + { + exception = ex; + } + + // Assert + Assert.Contains("specify a version range", exception.Message); + } + + [Fact] + public void PackageSpecReader_ProjectMissingVersion() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""project"" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; + + // Act + var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var range = spec.Dependencies.Single().LibraryRange.VersionRange; + + // Assert + Assert.Equal(VersionRange.All, range); + } + + [Fact] + public void PackageSpecReader_PackageEmptyVersion() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": """" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; + + Exception exception = null; + + try + { + var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + } + catch (Exception ex) + { + exception = ex; + } + + // Assert + Assert.Contains("specify a version range", exception.Message); + } + + [Fact] + public void PackageSpecReader_PackageWhitespaceVersion() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": "" "" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; + + Exception exception = null; + + try + { + var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + } + catch (Exception ex) + { + exception = ex; + } + + // Assert + Assert.Contains("not a valid version string", exception.Message); + } + + [Fact] + public void PackageSpecReader_FrameworkAssemblyEmptyVersion() + { + // Arrange + var json = @"{ + ""frameworks"": { + ""net46"": { + ""frameworkAssemblies"": { + ""packageA"": """" + } + } + } + }"; + + // Act + var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var range = spec.TargetFrameworks.Single().Dependencies.Single().LibraryRange.VersionRange; + + // Assert + Assert.Equal(VersionRange.All, range); + } + + [Fact] + public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""redist"": { + ""version"": ""1.0.0"", + ""type"": ""platform"", + ""include"": ""analyzers"" + } + } + }"; + + // Act + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("redist")); + Assert.NotNull(dep); + + var expected = LibraryIncludeFlags.Analyzers; + Assert.Equal(expected, dep.IncludeType); + } + + [Theory] + [InlineData("{}")] + [InlineData(@"{ + ""packOptions"": {} + }")] + [InlineData(@"{ + ""packOptions"": { + ""foo"": [1, 2] + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": null + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [] + } + }")] +#pragma warning disable CS0612 // Type or member is obsolete + public void PackageSpecReader_PackOptions_Default(string json) + { + // Arrange & Act + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + Assert.NotNull(actual.PackOptions); + Assert.NotNull(actual.PackOptions.PackageType); + Assert.Empty(actual.PackOptions.PackageType); + } + + [Theory] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": ""foo"" + } + }", new[] { "foo" })] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": ""foo, bar"" + } + }", new[] { "foo, bar" })] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [ ""foo"" ] + } + }", new[] { "foo" })] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [ ""foo, bar"" ] + } + }", new[] { "foo, bar" })] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [ ""foo"", ""bar"" ] + } + }", new[] { "foo", "bar" })] + public void PackageSpecReader_PackOptions_ValidPackageType(string json, string[] expectedNames) + { + // Arrange + var expected = expectedNames + .Select(n => new PackageType(n, PackageType.EmptyVersion)) + .ToArray(); + + // Act + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + Assert.NotNull(actual.PackOptions); + Assert.NotNull(actual.PackOptions.PackageType); + Assert.Equal(expected, actual.PackOptions.PackageType.ToArray()); + } + + [Theory] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": 1 + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": false + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": 1.0 + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": {} + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": { + ""name"": ""foo"" + } + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [ + { ""name"": ""foo"" }, + { ""name"": ""bar"" } + ] + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [ + ""foo"", + null + ] + } + }")] + [InlineData(@"{ + ""packOptions"": { + ""packageType"": [ + ""foo"", + true + ] + } + }")] + public void PackageSpecReader_PackOptions_InvalidPackageType(string json) + { + // Arrange & Act & Assert + var actual = Assert.Throws( + () => Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json")); + + Assert.Contains("The pack options package type must be a string or array of strings in 'project.json'.", actual.Message); + } + + [Fact] + public void PackageSpecReader_PackOptions_Files1() + { + // Arrange & Act + var json = @"{ + ""packOptions"": { + ""files"": { + ""include"": ""file1"", + ""exclude"": ""file2"", + ""includeFiles"": ""file3"", + ""excludeFiles"": ""file4"", + ""mappings"": { + ""dest/path"": ""./src/path"" + } + } + } + }"; + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + Assert.NotNull(actual.PackOptions); + Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.Include.Count); + Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.Exclude.Count); + Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.IncludeFiles.Count); + Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.Count); + Assert.Equal("file1", actual.PackOptions.IncludeExcludeFiles.Include.First()); + Assert.Equal("file2", actual.PackOptions.IncludeExcludeFiles.Exclude.First()); + Assert.Equal("file3", actual.PackOptions.IncludeExcludeFiles.IncludeFiles.First()); + Assert.Equal("file4", actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.First()); + Assert.NotNull(actual.PackOptions.Mappings); + Assert.Equal(1, actual.PackOptions.Mappings.Count()); + Assert.Equal("dest/path", actual.PackOptions.Mappings.First().Key); + Assert.Equal(1, actual.PackOptions.Mappings.First().Value.Include.Count()); + Assert.Null(actual.PackOptions.Mappings.First().Value.Exclude); + Assert.Null(actual.PackOptions.Mappings.First().Value.IncludeFiles); + Assert.Null(actual.PackOptions.Mappings.First().Value.ExcludeFiles); + Assert.Equal("./src/path", actual.PackOptions.Mappings.First().Value.Include.First()); + } + + [Fact] + public void PackageSpecReader_PackOptions_Files2() + { + // Arrange & Act + var json = @"{ + ""packOptions"": { + ""files"": { + ""include"": [""file1a"", ""file1b""], + ""exclude"": [""file2a"", ""file2b""], + ""includeFiles"": [""file3a"", ""file3b""], + ""excludeFiles"": [""file4a"", ""file4b""], + ""mappings"": { + ""dest/path1"": [""./src/path1"", ""./src/path2""], + ""dest/path2"": { + ""includeFiles"": [""map1a"", ""map1b""], + }, + } + } + } + }"; + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + Assert.NotNull(actual.PackOptions); + Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.Include.Count); + Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.Exclude.Count); + Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.IncludeFiles.Count); + Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.Count); + Assert.Equal("file1a", actual.PackOptions.IncludeExcludeFiles.Include.First()); + Assert.Equal("file2a", actual.PackOptions.IncludeExcludeFiles.Exclude.First()); + Assert.Equal("file3a", actual.PackOptions.IncludeExcludeFiles.IncludeFiles.First()); + Assert.Equal("file4a", actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.First()); + Assert.Equal("file1b", actual.PackOptions.IncludeExcludeFiles.Include.Last()); + Assert.Equal("file2b", actual.PackOptions.IncludeExcludeFiles.Exclude.Last()); + Assert.Equal("file3b", actual.PackOptions.IncludeExcludeFiles.IncludeFiles.Last()); + Assert.Equal("file4b", actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.Last()); + Assert.NotNull(actual.PackOptions.Mappings); + Assert.Equal(2, actual.PackOptions.Mappings.Count()); + Assert.Equal("dest/path1", actual.PackOptions.Mappings.First().Key); + Assert.Equal("dest/path2", actual.PackOptions.Mappings.Last().Key); + Assert.Equal(2, actual.PackOptions.Mappings.First().Value.Include.Count()); + Assert.Null(actual.PackOptions.Mappings.First().Value.Exclude); + Assert.Null(actual.PackOptions.Mappings.First().Value.IncludeFiles); + Assert.Null(actual.PackOptions.Mappings.First().Value.ExcludeFiles); + Assert.Equal("./src/path1", actual.PackOptions.Mappings.First().Value.Include.First()); + Assert.Equal("./src/path2", actual.PackOptions.Mappings.First().Value.Include.Last()); + Assert.Null(actual.PackOptions.Mappings.Last().Value.Include); + Assert.Null(actual.PackOptions.Mappings.Last().Value.Exclude); + Assert.Null(actual.PackOptions.Mappings.Last().Value.ExcludeFiles); + Assert.Equal("map1a", actual.PackOptions.Mappings.Last().Value.IncludeFiles.First()); + Assert.Equal("map1b", actual.PackOptions.Mappings.Last().Value.IncludeFiles.Last()); + } + + [Theory] + [InlineData("{}", null, true)] + [InlineData(@"{ + ""buildOptions"": {} + }", null, false)] + [InlineData(@"{ + ""buildOptions"": { + ""outputName"": ""dllName"" + } + }", "dllName", false)] + [InlineData(@"{ + ""buildOptions"": { + ""outputName"": ""dllName2"", + ""emitEntryPoint"": true + } + }", "dllName2", false)] + [InlineData(@"{ + ""buildOptions"": { + ""outputName"": null + } + }", null, false)] + public void PackageSpecReader_BuildOptions(string json, string expectedValue, bool nullBuildOptions) + { + // Arrange & Act + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + if (nullBuildOptions) + { + Assert.Null(actual.BuildOptions); + } + else + { + Assert.NotNull(actual.BuildOptions); + Assert.Equal(expectedValue, actual.BuildOptions.OutputName); + } + } +#pragma warning restore CS0612 // Type or member is obsolete + + [Fact] + public void PackageSpecReader_ReadsWithoutRestoreSettings() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"" + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + Assert.NotNull(actual); + Assert.NotNull(actual.RestoreSettings); + Assert.False(actual.RestoreSettings.HideWarningsAndErrors); + } + + [Fact] + public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ""NU1500"", + ""NU1107"" + ] + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); + Assert.NotNull(dep); + Assert.NotNull(dep.NoWarn); + Assert.Equal(dep.NoWarn.Count, 2); + Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); + Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1107)); + } + + [Fact] + public void PackageSpecReader_ReadsDependencyWithSingleNoWarn() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ""NU1500"" + ] + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); + Assert.NotNull(dep); + Assert.NotNull(dep.NoWarn); + Assert.Equal(dep.NoWarn.Count, 1); + Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); + } + + [Fact] + public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn() + { + // Arrange + var json = @"{ + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ] + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); + Assert.NotNull(dep); + Assert.NotNull(dep.NoWarn); + Assert.Equal(dep.NoWarn.Count, 0); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningProperties() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""allWarningsAsErrors"": true, + ""noWarn"": [ + ""NU1601"", + ], + ""warnAsError"": [ + ""NU1500"", + ""NU1501"" + ], + ""warnNotAsError"": [ + ""NU1801"", + ""NU1802"" + ] + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.NotNull(warningProperties); + Assert.True(warningProperties.AllWarningsAsErrors); + Assert.Equal(1, warningProperties.NoWarn.Count); + Assert.True(warningProperties.NoWarn.Contains(NuGetLogCode.NU1601)); + Assert.Equal(2, warningProperties.WarningsAsErrors.Count); + Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1500)); + Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); + Assert.Equal(2, warningProperties.WarningsNotAsErrors.Count); + Assert.True(warningProperties.WarningsNotAsErrors.Contains(NuGetLogCode.NU1801)); + Assert.True(warningProperties.WarningsNotAsErrors.Contains(NuGetLogCode.NU1802)); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_NoWarn() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""allWarningsAsErrors"": true, + ""warnAsError"": [ + ""NU1500"", + ""NU1501"" + ] + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.NotNull(warningProperties); + Assert.True(warningProperties.AllWarningsAsErrors); + Assert.Equal(0, warningProperties.NoWarn.Count); + Assert.Equal(2, warningProperties.WarningsAsErrors.Count); + Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1500)); + Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_WarnAsError() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""allWarningsAsErrors"": true, + ""noWarn"": [ + ""NU1601"", + ] + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.NotNull(warningProperties); + Assert.True(warningProperties.AllWarningsAsErrors); + Assert.Equal(1, warningProperties.NoWarn.Count); + Assert.True(warningProperties.NoWarn.Contains(NuGetLogCode.NU1601)); + Assert.Equal(0, warningProperties.WarningsAsErrors.Count); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_AllWarningsAsErrors() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""noWarn"": [ + ""NU1601"", + ], + ""warnAsError"": [ + ""NU1500"", + ""NU1501"" + ] + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.NotNull(warningProperties); + Assert.False(warningProperties.AllWarningsAsErrors); + Assert.Equal(1, warningProperties.NoWarn.Count); + Assert.True(warningProperties.NoWarn.Contains(NuGetLogCode.NU1601)); + Assert.Equal(2, warningProperties.WarningsAsErrors.Count); + Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1500)); + Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithEmptyWarningPropertiesAnd() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.NotNull(warningProperties); + Assert.False(warningProperties.AllWarningsAsErrors); + Assert.Equal(0, warningProperties.NoWarn.Count); + Assert.Equal(0, warningProperties.WarningsAsErrors.Count); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithNoWarningProperties() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.NotNull(warningProperties); + } + + [Fact] + public void PackageSpecReader_RuntimeIdentifierPathNullIfEmpty() + { + // Arrange + var json = @"{ + ""frameworks"": { + ""net46"": { + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ""NU1500"" + ] + } + } + } + } + }"; + + // Act + var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + Assert.Null(spec.TargetFrameworks.First().RuntimeIdentifierGraphPath); + } + +#pragma warning disable CS0612 // Type or member is obsolete + [Fact] + public void GetPackageSpec_WhenAuthorsPropertyIsAbsent_ReturnsEmptyAuthors() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Empty(packageSpec.Authors); + } + + [Fact] + public void GetPackageSpec_WhenAuthorsValueIsNull_ReturnsEmptyAuthors() + { + PackageSpec packageSpec = GetPackageSpec("{\"authors\":null}"); + + Assert.Empty(packageSpec.Authors); + } + + [Fact] + public void GetPackageSpec_WhenAuthorsValueIsString_ReturnsEmptyAuthors() + { + PackageSpec packageSpec = GetPackageSpec("{\"authors\":\"b\"}"); + + Assert.Empty(packageSpec.Authors); + } + + [Theory] + [InlineData("")] + [InlineData("/**/")] + public void GetPackageSpec_WhenAuthorsValueIsEmptyArray_ReturnsEmptyAuthors(string value) + { + PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}"); + + Assert.Empty(packageSpec.Authors); + } + + [Theory] + [InlineData("{}")] + [InlineData("[]")] + public void GetPackageSpec_WhenAuthorsValueElementIsNotConvertibleToString_Throws(string value) + { + var json = $"{{\"authors\":[{value}]}}"; + + Assert.Throws(() => GetPackageSpec(json)); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("true", "True")] + [InlineData("-2", "-2")] + [InlineData("3.14", "3.14")] + public void GetPackageSpec_WhenAuthorsValueElementIsConvertibleToString_ReturnsAuthor(string value, string expectedValue) + { + PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}"); + + Assert.Collection(packageSpec.Authors, author => Assert.Equal(expectedValue, author)); + } + + [Fact] + public void GetPackageSpec_WhenBuildOptionsPropertyIsAbsent_ReturnsNullBuildOptions() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Null(packageSpec.BuildOptions); + } + + [Fact] + public void GetPackageSpec_WhenBuildOptionsValueIsEmptyObject_ReturnsBuildOptions() + { + PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{}}"); + + Assert.NotNull(packageSpec.BuildOptions); + Assert.Null(packageSpec.BuildOptions.OutputName); + } + + [Fact] + public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsNull_ReturnsNullOutputName() + { + PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{\"outputName\":null}}"); + + Assert.Null(packageSpec.BuildOptions.OutputName); + } + + [Fact] + public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsValid_ReturnsOutputName() + { + const string expectedResult = "a"; + + var json = $"{{\"buildOptions\":{{\"outputName\":\"{expectedResult}\"}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.BuildOptions.OutputName); + } + + [Theory] + [InlineData("-2", "-2")] + [InlineData("3.14", "3.14")] + [InlineData("true", "True")] + public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsConvertibleToString_ReturnsOutputName(string outputName, string expectedValue) + { + PackageSpec packageSpec = GetPackageSpec($"{{\"buildOptions\":{{\"outputName\":{outputName}}}}}"); + + Assert.Equal(expectedValue, packageSpec.BuildOptions.OutputName); + } + + [Fact] + public void GetPackageSpec_WhenContentFilesPropertyIsAbsent_ReturnsEmptyContentFiles() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Empty(packageSpec.ContentFiles); + } + + [Fact] + public void GetPackageSpec_WhenContentFilesValueIsNull_ReturnsEmptyContentFiles() + { + PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":null}"); + + Assert.Empty(packageSpec.ContentFiles); + } + + [Fact] + public void GetPackageSpec_WhenContentFilesValueIsString_ReturnsEmptyContentFiles() + { + PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":\"a\"}"); + + Assert.Empty(packageSpec.ContentFiles); + } + + [Theory] + [InlineData("")] + [InlineData("/**/")] + public void GetPackageSpec_WhenContentFilesValueIsEmptyArray_ReturnsEmptyContentFiles(string value) + { + PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}"); + + Assert.Empty(packageSpec.ContentFiles); + } + + [Theory] + [InlineData("{}")] + [InlineData("[]")] + public void GetPackageSpec_WhenContentFilesValueElementIsNotConvertibleToString_Throws(string value) + { + var json = $"{{\"contentFiles\":[{value}]}}"; + + Assert.Throws(() => GetPackageSpec(json)); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("true", "True")] + [InlineData("-2", "-2")] + [InlineData("3.14", "3.14")] + public void GetPackageSpec_WhenContentFilesValueElementIsConvertibleToString_ReturnsContentFile(string value, string expectedValue) + { + PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}"); + + Assert.Collection(packageSpec.ContentFiles, contentFile => Assert.Equal(expectedValue, contentFile)); + } + + [Fact] + public void GetPackageSpec_WhenCopyrightPropertyIsAbsent_ReturnsNullCopyright() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Null(packageSpec.Copyright); + } + + [Fact] + public void GetPackageSpec_WhenCopyrightValueIsNull_ReturnsNullCopyright() + { + PackageSpec packageSpec = GetPackageSpec("{\"copyright\":null}"); + + Assert.Null(packageSpec.Copyright); + } + + [Fact] + public void GetPackageSpec_WhenCopyrightValueIsString_ReturnsCopyright() + { + const string expectedResult = "a"; + + PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":\"{expectedResult}\"}}"); + + Assert.Equal(expectedResult, packageSpec.Copyright); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("true", "True")] + [InlineData("-2", "-2")] + [InlineData("3.14", "3.14")] + public void GetPackageSpec_WhenCopyrightValueIsConvertibleToString_ReturnsCopyright(string value, string expectedValue) + { + PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":{value}}}"); + + Assert.Equal(expectedValue, packageSpec.Copyright); + } +#pragma warning restore CS0612 // Type or member is obsolete + + [Fact] + public void GetPackageSpec_WhenDependenciesPropertyIsAbsent_ReturnsEmptyDependencies() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Empty(packageSpec.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesValueIsNull_ReturnsEmptyDependencies() + { + PackageSpec packageSpec = GetPackageSpec("{\"dependencies\":null}"); + + Assert.Empty(packageSpec.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyNameIsEmptyString_Throws() + { + const string json = "{\"dependencies\":{\"\":{}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Unable to resolve dependency ''.", exception.Message); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange() + { + var expectedResult = new LibraryRange( + name: "a", + new VersionRange(new NuGetVersion("1.2.3")), + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); + var json = $"{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange.ToShortString()}\"}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedResult, dependency.LibraryRange); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange() + { + var expectedResult = new LibraryRange( + name: "a", + new VersionRange(new NuGetVersion("1.2.3"), includeMinVersion: true, new NuGetVersion("4.5.6"), includeMaxVersion: false), + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); + var json = $"{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange}\"}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedResult, dependency.LibraryRange); + } + + [Theory] + [InlineData(LibraryDependencyTarget.None)] + [InlineData(LibraryDependencyTarget.Assembly)] + [InlineData(LibraryDependencyTarget.Reference)] + [InlineData(LibraryDependencyTarget.WinMD)] + [InlineData(LibraryDependencyTarget.All)] + [InlineData(LibraryDependencyTarget.PackageProjectExternal)] + public void GetPackageSpec_WhenDependenciesDependencyTargetIsUnsupported_Throws(LibraryDependencyTarget target) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"version\":\"1.2.3\",\"target\":\"{target}\"}}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal($"Error reading '' : Invalid dependency target value '{target}'.", exception.Message); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced() + { + LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Project\"}}}}}}"); + + Assert.False(dependency.AutoReferenced); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(bool expectedValue) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"autoReferenced\":{expectedValue.ToString().ToLower()},\"target\":\"Project\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedValue, dependency.AutoReferenced); + } + + [Theory] + [InlineData("exclude")] + [InlineData("include")] + [InlineData("suppressParent")] + public void GetPackageSpec_WhenDependenciesDependencyValueIsArray_Throws(string propertyName) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"{propertyName}\":[\"b\"]}}}}}}"; + + var exception = Assert.Throws(() => GetPackageSpec(json)); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(LibraryIncludeFlags.All, dependency.IncludeType); + } + + [Theory] + [InlineData("\"Native\"", LibraryIncludeFlags.Native)] + [InlineData("\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] + public void GetPackageSpec_WhenDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType( + string value, + LibraryIncludeFlags result) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"exclude\":{value},\"version\":\"1.0.0\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(LibraryIncludeFlags.All & ~result, dependency.IncludeType); + } + + [Theory] + [InlineData("\"Native\"", LibraryIncludeFlags.Native)] + [InlineData("\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] + public void GetPackageSpec_WhenDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType( + string value, + LibraryIncludeFlags expectedResult) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"include\":{value},\"version\":\"1.0.0\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedResult, dependency.IncludeType); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType() + { + const string json = "{\"dependencies\":{\"a\":{\"include\":\"ContentFiles\",\"type\":\"BecomesNupkgDependency, SharedFramework\",\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent() + { + const string json = "{\"dependencies\":{\"a\":{\"suppressParent\":\"ContentFiles\",\"type\":\"SharedFramework\",\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.SuppressParent); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(LibraryIncludeFlagUtils.DefaultSuppressParent, dependency.SuppressParent); + } + + [Theory] + [InlineData("\"Compile\"", LibraryIncludeFlags.Compile)] + [InlineData("\"Analyzers, Compile\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Compile)] + public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent( + string value, + LibraryIncludeFlags expectedResult) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"suppressParent\":{value},\"version\":\"1.0.0\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedResult, dependency.SuppressParent); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyVersionValueIsInvalid_Throws() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"b\"}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : 'b' is not a valid version string.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() + { + const string json = "{\"dependencies\":{\"a\":{\"target\":\"Package\"}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() + { + LibraryDependency dependency = GetDependency("{\"dependencies\":{\"a\":{\"target\":\"Project\"}}}"); + + Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Empty(dependency.NoWarn); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns() + { + NuGetLogCode[] expectedResults = { NuGetLogCode.NU1000, NuGetLogCode.NU3000 }; + var json = $"{{\"dependencies\":{{\"a\":{{\"noWarn\":[\"{expectedResults[0].ToString()}\",\"{expectedResults[1].ToString()}\"],\"version\":\"1.0.0\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Collection( + dependency.NoWarn, + noWarn => Assert.Equal(expectedResults[0], noWarn), + noWarn => Assert.Equal(expectedResults[1], noWarn)); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.False(dependency.GeneratePathProperty); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(bool expectedResult) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"generatePathProperty\":{expectedResult.ToString().ToLowerInvariant()},\"version\":\"1.0.0\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedResult, dependency.GeneratePathProperty); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint() + { + const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal( + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, + dependency.LibraryRange.TypeConstraint); + } + + [Fact] + public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged() + { + LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}"); + + Assert.False(dependency.VersionCentrallyManaged); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(bool expectedValue) + { + var json = $"{{\"dependencies\":{{\"a\":{{\"versionCentrallyManaged\":{expectedValue.ToString().ToLower()},\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}"; + + LibraryDependency dependency = GetDependency(json); + + Assert.Equal(expectedValue, dependency.VersionCentrallyManaged); + } + +#pragma warning disable CS0612 // Type or member is obsolete + [Fact] + public void GetPackageSpec_WhenDescriptionPropertyIsAbsent_ReturnsNullDescription() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Null(packageSpec.Description); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("b")] + public void GetPackageSpec_WhenDescriptionValueIsValid_ReturnsDescription(string expectedResult) + { + string description = expectedResult == null ? "null" : $"\"{expectedResult}\""; + PackageSpec packageSpec = GetPackageSpec($"{{\"description\":{description}}}"); + + Assert.Equal(expectedResult, packageSpec.Description); + } + + [Fact] + public void GetPackageSpec_WhenLanguagePropertyIsAbsent_ReturnsNullLanguage() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Null(packageSpec.Language); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("b")] + public void GetPackageSpec_WhenLanguageValueIsValid_ReturnsLanguage(string expectedResult) + { + string language = expectedResult == null ? "null" : $"\"{expectedResult}\""; + PackageSpec packageSpec = GetPackageSpec($"{{\"language\":{language}}}"); + + Assert.Equal(expectedResult, packageSpec.Language); + } +#pragma warning restore CS0612 // Type or member is obsolete + + [Fact] + public void GetPackageSpec_WhenFrameworksPropertyIsAbsent_ReturnsEmptyFrameworks() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Empty(packageSpec.TargetFrameworks); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks() + { + PackageSpec packageSpec = GetPackageSpec("{\"frameworks\":{}}"); + + Assert.Empty(packageSpec.TargetFrameworks); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksAssetTargetFallbackPropertyIsAbsent_ReturnsFalseAssetTargetFallback() + { + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); + + Assert.False(framework.AssetTargetFallback); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenFrameworksAssetTargetFallbackValueIsValid_ReturnsAssetTargetFallback(bool expectedValue) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"assetTargetFallback\":{expectedValue.ToString().ToLowerInvariant()}}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Equal(expectedValue, framework.AssetTargetFallback); + } + + [Fact] + public void GetPackageSpec_WithAssetTargetFallbackAndImportsValues_ReturnsValidAssetTargetFallbackFramework() + { + var json = $"{{\"frameworks\":{{\"net5.0\":{{\"assetTargetFallback\": true, \"imports\": [\"net472\", \"net471\"]}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + framework.AssetTargetFallback.Should().BeTrue(); + var assetTargetFallback = framework.FrameworkName as AssetTargetFallbackFramework; + assetTargetFallback.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); + assetTargetFallback.Fallback.Should().HaveCount(2); + assetTargetFallback.Fallback.First().Should().Be(FrameworkConstants.CommonFrameworks.Net472); + assetTargetFallback.Fallback.Last().Should().Be(FrameworkConstants.CommonFrameworks.Net471); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsPropertyIsAbsent_ReturnsEmptyCentralPackageVersions() + { + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); + + Assert.Empty(framework.CentralPackageVersions); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsValueIsEmptyObject_ReturnsEmptyCentralPackageVersions() + { + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"centralPackageVersions\":{}}}}"); + + Assert.Empty(framework.CentralPackageVersions); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyNameIsEmptyString_Throws() + { + var json = "{\"frameworks\":{\"a\":{\"centralPackageVersions\":{\"\":\"1.0.0\"}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : Unable to resolve central version ''.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Theory] + [InlineData("null")] + [InlineData("\"\"")] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyValueIsNullOrEmptyString_Throws(string value) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"b\":{value}}}}}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal($"Error reading '' : The version cannot be null or empty.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsIsValid_ReturnsCentralPackageVersions() + { + const string expectedPackageId = "b"; + VersionRange expectedVersionRange = VersionRange.Parse("[1.2.3,4.5.6)"); + var expectedCentralPackageVersion = new CentralPackageVersion(expectedPackageId, expectedVersionRange); + var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"{expectedPackageId}\":\"{expectedVersionRange.ToShortString()}\"}}}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Collection( + framework.CentralPackageVersions, + actualResult => + { + Assert.Equal(expectedPackageId, actualResult.Key); + Assert.Equal(expectedCentralPackageVersion, actualResult.Value); + }); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsHasDuplicateKey_LastOneWins() + { + const string expectedPackageId = "b"; + VersionRange unexpectedVersionRange = VersionRange.Parse("1.2.3"); + VersionRange expectedVersionRange = VersionRange.Parse("4.5.6"); + var expectedCentralPackageVersion = new CentralPackageVersion(expectedPackageId, expectedVersionRange); + var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"{expectedPackageId}\":\"{unexpectedVersionRange.ToShortString()}\"," + + $"\"{expectedPackageId}\":\"{expectedVersionRange.ToShortString()}\"}}}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Collection( + framework.CentralPackageVersions, + actualResult => + { + Assert.Equal(expectedPackageId, actualResult.Key); + Assert.Equal(expectedCentralPackageVersion, actualResult.Value); + }); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesPropertyIsAbsent_ReturnsEmptyDependencies() + { + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); + + Assert.Empty(framework.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesValueIsNull_ReturnsEmptyDependencies() + { + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"dependencies\":null}}}"); + + Assert.Empty(framework.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyNameIsEmptyString_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"\":{}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Unable to resolve dependency ''.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange() + { + var expectedResult = new LibraryRange( + name: "b", + new VersionRange(new NuGetVersion("1.2.3")), + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange.ToShortString()}\"}}}}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(expectedResult, dependency.LibraryRange); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange() + { + var expectedResult = new LibraryRange( + name: "b", + new VersionRange(new NuGetVersion("1.2.3"), includeMinVersion: true, new NuGetVersion("4.5.6"), includeMaxVersion: false), + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange}\"}}}}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(expectedResult, dependency.LibraryRange); + } + + [Theory] + [InlineData(LibraryDependencyTarget.None)] + [InlineData(LibraryDependencyTarget.Assembly)] + [InlineData(LibraryDependencyTarget.Reference)] + [InlineData(LibraryDependencyTarget.WinMD)] + [InlineData(LibraryDependencyTarget.All)] + [InlineData(LibraryDependencyTarget.PackageProjectExternal)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsUnsupported_Throws(LibraryDependencyTarget target) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"version\":\"1.2.3\",\"target\":\"{target}\"}}}}}}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal($"Error reading '' : Invalid dependency target value '{target}'.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Project\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.False(dependency.AutoReferenced); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(bool expectedValue) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"autoReferenced\":{expectedValue.ToString().ToLower()},\"target\":\"Project\"}}}}}}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(expectedValue, dependency.AutoReferenced); + } + + [Theory] + [InlineData("exclude")] + [InlineData("include")] + [InlineData("suppressParent")] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsArray_Throws(string propertyName) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"{propertyName}\":[\"c\"]}}}}}}}}}}"; + + // The exception messages will not be the same because the innermost exception in the baseline + // is a Newtonsoft.Json exception, while it's a .NET exception in the improved. + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal($"Error reading '' : Specified cast is not valid.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlags.All, dependency.IncludeType); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"exclude\":\"Native\",\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlags.All & ~LibraryIncludeFlags.Native, dependency.IncludeType); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"include\":\"ContentFiles\",\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"include\":\"ContentFiles\",\"type\":\"BecomesNupkgDependency, SharedFramework\",\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"suppressParent\":\"ContentFiles\",\"type\":\"SharedFramework\",\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.SuppressParent); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlagUtils.DefaultSuppressParent, dependency.SuppressParent); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"suppressParent\":\"Compile\",\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryIncludeFlags.Compile, dependency.SuppressParent); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionValueIsInvalid_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"c\"}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : 'c' is not a valid version string.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal( + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, + dependency.LibraryRange.TypeConstraint); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Package\"}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Project\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Empty(dependency.NoWarn); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns() + { + NuGetLogCode[] expectedResults = { NuGetLogCode.NU1000, NuGetLogCode.NU3000 }; + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"noWarn\":[\"{expectedResults[0].ToString()}\",\"{expectedResults[1].ToString()}\"],\"version\":\"1.0.0\"}}}}}}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Collection( + dependency.NoWarn, + noWarn => Assert.Equal(expectedResults[0], noWarn), + noWarn => Assert.Equal(expectedResults[1], noWarn)); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.False(dependency.GeneratePathProperty); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(bool expectedResult) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"generatePathProperty\":{expectedResult.ToString().ToLowerInvariant()},\"version\":\"1.0.0\"}}}}}}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(expectedResult, dependency.GeneratePathProperty); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal( + LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, + dependency.LibraryRange.TypeConstraint); + } + + + [Fact] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged() + { + const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.False(dependency.VersionCentrallyManaged); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(bool expectedValue) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"versionCentrallyManaged\":{expectedValue.ToString().ToLower()},\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(expectedValue, dependency.VersionCentrallyManaged); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesPropertyIsAbsent_ReturnsEmptyDownloadDependencies() + { + const string json = "{\"frameworks\":{\"a\":{}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.DownloadDependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNull_ReturnsEmptyDownloadDependencies() + { + const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":null}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.DownloadDependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNotArray_ReturnsEmptyDownloadDependencies() + { + const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":\"b\"}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.DownloadDependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsEmptyArray_ReturnsEmptyDownloadDependencies() + { + const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[]}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.DownloadDependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsAbsent_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[{\"version\":\"1.2.3\"}]}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : Unable to resolve downloadDependency ''.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsNull_ReturnsDownloadDependencies() + { + var expectedResult = new DownloadDependency(name: null, new VersionRange(new NuGetVersion("1.2.3"))); + var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":null,\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}]}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + DownloadDependency actualResult = framework.DownloadDependencies.Single(); + + Assert.Equal(expectedResult.Name, actualResult.Name); + Assert.Equal(expectedResult.VersionRange, actualResult.VersionRange); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsAbsent_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[{\"name\":\"b\"}]}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : The version cannot be null or empty", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Theory] + [InlineData("null")] + [InlineData("c")] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsInvalid_Throws(string version) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":\"b\",\"version\":\"{version}\"}}]}}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal($"Error reading '' : '{version}' is not a valid version string.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsValid_ReturnsDownloadDependencies() + { + var expectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("1.2.3"))); + var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":\"{expectedResult.Name}\",\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}]}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Equal(expectedResult, framework.DownloadDependencies.Single()); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueHasDuplicates_PrefersFirstByName() + { + var expectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("1.2.3"))); + var unexpectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("4.5.6"))); + var json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[" + + $"{{\"name\":\"{expectedResult.Name}\",\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}," + + $"{{\"name\":\"{unexpectedResult.Name}\",\"version\":\"{unexpectedResult.VersionRange.ToShortString()}\"}}" + + "]}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Equal(expectedResult, framework.DownloadDependencies.Single()); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesPropertyIsAbsent_ReturnsEmptyDependencies() + { + const string json = "{\"frameworks\":{\"a\":{}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsNull_ReturnsEmptyDependencies() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":null}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsEmptyObject_ReturnsEmptyDependencies() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Dependencies); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetPropertyIsAbsent_ReturnsTarget() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"target\":\"Package\"}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.IsType(exception.InnerException.InnerException); + Assert.Null(exception.InnerException.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"target\":\"Project\"}}}}}"; + + LibraryDependency dependency = GetFrameworksDependency(json); + + Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPropertyIsAbsent_ReturnsEmptyFrameworkReferences() + { + const string json = "{\"frameworks\":{\"a\":{}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.FrameworkReferences); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsNull_ReturnsEmptyFrameworkReferences() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":null}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.FrameworkReferences); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsEmptyObject_ReturnsEmptyFrameworkReferences() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":{}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.FrameworkReferences); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesFrameworkNameIsEmptyString_Throws() + { + const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":{\"\":{}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("Error reading '' : Unable to resolve frameworkReference.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsPropertyIsAbsent_ReturnsNonePrivateAssets() + { + var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.None); + var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{}}}}}}}}}}"; + + FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + + Assert.Equal(expectedResult, dependency); + } + + [Theory] + [InlineData("\"null\"")] + [InlineData("\"\"")] + [InlineData("\"c\"")] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsInvalidValue_ReturnsNonePrivateAssets(string privateAssets) + { + var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.None); + var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":{privateAssets}}}}}}}}}}}"; + + FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + + Assert.Equal(expectedResult, dependency); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidString_ReturnsPrivateAssets() + { + var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.All); + var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":\"{expectedResult.PrivateAssets.ToString().ToLowerInvariant()}\"}}}}}}}}}}"; + + FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + + Assert.Equal(expectedResult, dependency); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidDelimitedString_ReturnsPrivateAssets() + { + var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.All); + var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":\"none,all\"}}}}}}}}}}"; + + FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + + Assert.Equal(expectedResult, dependency); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksImportsPropertyIsAbsent_ReturnsEmptyImports() + { + const string json = "{\"frameworks\":{\"a\":{}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Imports); + } + + [Theory] + [InlineData("null")] + [InlineData("\"\"")] + public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfNullOrEmptyString_ImportIsSkipped(string import) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[{import}]}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Imports); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksImportsValueIsNull_ReturnsEmptyList() + { + const string json = "{\"frameworks\":{\"a\":{\"imports\":null}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Imports); + } + + [Theory] + [InlineData("true")] + [InlineData("-2")] + [InlineData("3.14")] + [InlineData("{}")] + public void GetPackageSpec_WhenFrameworksImportsValueIsInvalidValue_ReturnsEmptyList(string value) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":{value}}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Empty(framework.Imports); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksImportsValueContainsInvalidValue_Throws() + { + const string expectedImport = "b"; + + var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[\"{expectedImport}\"]}}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal( + $"Error reading '' : Imports contains an invalid framework: '{expectedImport}' in 'project.json'.", + exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksImportsValueIsString_ReturnsImport() + { + NuGetFramework expectedResult = NuGetFramework.Parse("net48"); + var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":\"{expectedResult.GetShortFolderName()}\"}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Collection( + framework.Imports, + actualResult => Assert.Equal(expectedResult, actualResult)); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfStrings_ReturnsImports() + { + NuGetFramework[] expectedResults = { NuGetFramework.Parse("net472"), NuGetFramework.Parse("net48") }; + var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[\"{expectedResults[0].GetShortFolderName()}\",\"{expectedResults[1].GetShortFolderName()}\"]}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Collection( + framework.Imports, + actualResult => Assert.Equal(expectedResults[0], actualResult), + actualResult => Assert.Equal(expectedResults[1], actualResult)); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathPropertyIsAbsent_ReturnsRuntimeIdentifierGraphPath() + { + const string json = "{\"frameworks\":{\"a\":{}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Null(framework.RuntimeIdentifierGraphPath); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("b")] + public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathValueIsString_ReturnsRuntimeIdentifierGraphPath(string expectedResult) + { + string runtimeIdentifierGraphPath = expectedResult == null ? "null" : $"\"{expectedResult}\""; + var json = $"{{\"frameworks\":{{\"a\":{{\"runtimeIdentifierGraphPath\":{runtimeIdentifierGraphPath}}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Equal(expectedResult, framework.RuntimeIdentifierGraphPath); + } + + [Fact] + public void GetPackageSpec_WhenFrameworksWarnPropertyIsAbsent_ReturnsWarn() + { + const string json = "{\"frameworks\":{\"a\":{}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.False(framework.Warn); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void GetPackageSpec_WhenFrameworksWarnValueIsValid_ReturnsWarn(bool expectedResult) + { + var json = $"{{\"frameworks\":{{\"a\":{{\"warn\":{expectedResult.ToString().ToLowerInvariant()}}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + + Assert.Equal(expectedResult, framework.Warn); + } + +#pragma warning disable CS0612 // Type or member is obsolete + [Fact] + public void GetPackageSpec_WhenPackIncludePropertyIsAbsent_ReturnsEmptyPackInclude() + { + PackageSpec packageSpec = GetPackageSpec("{}"); + + Assert.Empty(packageSpec.PackInclude); + } + + [Fact] + public void GetPackageSpec_WhenPackIncludePropertyIsValid_ReturnsPackInclude() + { + var expectedResults = new List>() { new KeyValuePair("a", "b"), new KeyValuePair("c", "d") }; + var json = $"{{\"packInclude\":{{\"{expectedResults[0].Key}\":\"{expectedResults[0].Value}\",\"{expectedResults[1].Key}\":\"{expectedResults[1].Value}\"}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Collection( + packageSpec.PackInclude, + actualResult => Assert.Equal(expectedResults[0], actualResult), + actualResult => Assert.Equal(expectedResults[1], actualResult)); + } + + [Theory] + [InlineData("{}")] + [InlineData("{\"packOptions\":null}")] + public void GetPackageSpec_WhenPackOptionsPropertyIsAbsentOrValueIsNull_ReturnsPackOptions(string json) + { + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.NotNull(packageSpec.PackOptions); + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + Assert.Empty(packageSpec.PackOptions.Mappings); + Assert.Empty(packageSpec.PackOptions.PackageType); + + Assert.Null(packageSpec.IconUrl); + Assert.Null(packageSpec.LicenseUrl); + Assert.Empty(packageSpec.Owners); + Assert.Null(packageSpec.ProjectUrl); + Assert.Null(packageSpec.ReleaseNotes); + Assert.False(packageSpec.RequireLicenseAcceptance); + Assert.Null(packageSpec.Summary); + Assert.Empty(packageSpec.Tags); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsPropertyIsAbsent_OwnersAndTagsAreEmpty() + { + const string json = "{\"owners\":[\"a\"],\"tags\":[\"b\"]}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.Owners); + Assert.Empty(packageSpec.Tags); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsPropertyIsEmptyObject_ReturnsPackOptions() + { + string json = "{\"packOptions\":{}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.NotNull(packageSpec.PackOptions); + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + Assert.Null(packageSpec.PackOptions.Mappings); + Assert.Empty(packageSpec.PackOptions.PackageType); + + Assert.Null(packageSpec.IconUrl); + Assert.Null(packageSpec.LicenseUrl); + Assert.Empty(packageSpec.Owners); + Assert.Null(packageSpec.ProjectUrl); + Assert.Null(packageSpec.ReleaseNotes); + Assert.False(packageSpec.RequireLicenseAcceptance); + Assert.Null(packageSpec.Summary); + Assert.Empty(packageSpec.Tags); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsValueIsValid_ReturnsPackOptions() + { + const string iconUrl = "a"; + const string licenseUrl = "b"; + string[] owners = { "c", "d" }; + const string projectUrl = "e"; + const string releaseNotes = "f"; + const bool requireLicenseAcceptance = true; + const string summary = "g"; + string[] tags = { "h", "i" }; + + var json = $"{{\"packOptions\":{{\"iconUrl\":\"{iconUrl}\",\"licenseUrl\":\"{licenseUrl}\",\"owners\":[{string.Join(",", owners.Select(owner => $"\"{owner}\""))}]," + + $"\"projectUrl\":\"{projectUrl}\",\"releaseNotes\":\"{releaseNotes}\",\"requireLicenseAcceptance\":{requireLicenseAcceptance.ToString().ToLowerInvariant()}," + + $"\"summary\":\"{summary}\",\"tags\":[{string.Join(",", tags.Select(tag => $"\"{tag}\""))}]}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.NotNull(packageSpec.PackOptions); + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + Assert.Null(packageSpec.PackOptions.Mappings); + Assert.Empty(packageSpec.PackOptions.PackageType); + Assert.Equal(iconUrl, packageSpec.IconUrl); + Assert.Equal(licenseUrl, packageSpec.LicenseUrl); + Assert.Equal(owners, packageSpec.Owners); + Assert.Equal(projectUrl, packageSpec.ProjectUrl); + Assert.Equal(releaseNotes, packageSpec.ReleaseNotes); + Assert.Equal(requireLicenseAcceptance, packageSpec.RequireLicenseAcceptance); + Assert.Equal(summary, packageSpec.Summary); + Assert.Equal(tags, packageSpec.Tags); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsNull_ReturnsEmptyPackageTypes() + { + const string json = "{\"packOptions\":{\"packageType\":null}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.PackOptions.PackageType); + } + + [Theory] + [InlineData("true")] + [InlineData("-2")] + [InlineData("3.14")] + [InlineData("{}")] + [InlineData("[true]")] + [InlineData("[-2]")] + [InlineData("[3.14]")] + [InlineData("[null]")] + [InlineData("[{}]")] + [InlineData("[[]]")] + public void GetPackageSpec_WhenPackOptionsPackageTypeIsInvalid_Throws(string value) + { + var json = $"{{\"packOptions\":{{\"packageType\":{value}}}}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("The pack options package type must be a string or array of strings in 'project.json'.", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("\"a,b\"", "a,b")] + [InlineData("[\"a\"]", "a")] + [InlineData("[\"a b\"]", "a b")] + public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsValid_ReturnsPackageTypes(string value, string expectedName) + { + var expectedResult = new PackageType(expectedName, PackageType.EmptyVersion); + var json = $"{{\"packOptions\":{{\"packageType\":{value}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Collection( + packageSpec.PackOptions.PackageType, + actualResult => Assert.Equal(expectedResult, actualResult)); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesValueIsNull_ReturnsNullInclude() + { + const string json = "{\"packOptions\":{\"files\":null}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesValueIsEmptyObject_ReturnsNullInclude() + { + const string json = "{\"packOptions\":{\"files\":{}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsNull_ReturnsNullIncludeExcludeFiles() + { + const string json = "{\"packOptions\":{\"files\":{\"include\":null}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsEmptyArray_ReturnsEmptyInclude() + { + const string json = "{\"packOptions\":{\"files\":{\"include\":[]}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.Include); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("\"a, b\"", "a, b")] + [InlineData("[null]", null)] + [InlineData("[\"\"]", "")] + [InlineData("[\"a\"]", "a")] + [InlineData("[\"a, b\"]", "a, b")] + [InlineData("[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsValid_ReturnsInclude(string value, params string[] expectedResults) + { + expectedResults = expectedResults ?? new string[] { null }; + + var json = $"{{\"packOptions\":{{\"files\":{{\"include\":{value}}}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.Include); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles() + { + const string json = "{\"packOptions\":{\"files\":{\"includeFiles\":null}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsEmptyArray_ReturnsEmptyIncludeFiles() + { + const string json = "{\"packOptions\":{\"files\":{\"includeFiles\":[]}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.IncludeFiles); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("\"a, b\"", "a, b")] + [InlineData("[null]", null)] + [InlineData("[\"\"]", "")] + [InlineData("[\"a\"]", "a")] + [InlineData("[\"a, b\"]", "a, b")] + [InlineData("[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsValid_ReturnsIncludeFiles(string value, params string[] expectedResults) + { + expectedResults = expectedResults ?? new string[] { null }; + + var json = $"{{\"packOptions\":{{\"files\":{{\"includeFiles\":{value}}}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.IncludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsNull_ReturnsNullIncludeExcludeFiles() + { + const string json = "{\"packOptions\":{\"files\":{\"exclude\":null}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsEmptyArray_ReturnsEmptyExclude() + { + const string json = "{\"packOptions\":{\"files\":{\"exclude\":[]}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.Exclude); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("\"a, b\"", "a, b")] + [InlineData("[null]", null)] + [InlineData("[\"\"]", "")] + [InlineData("[\"a\"]", "a")] + [InlineData("[\"a, b\"]", "a, b")] + [InlineData("[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsValid_ReturnsExclude(string value, params string[] expectedResults) + { + expectedResults = expectedResults ?? new string[] { null }; + + var json = $"{{\"packOptions\":{{\"files\":{{\"exclude\":{value}}}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.Exclude); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles() + { + const string json = "{\"packOptions\":{\"files\":{\"excludeFiles\":null}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsEmptyArray_ReturnsEmptyExcludeFiles() + { + const string json = "{\"packOptions\":{\"files\":{\"excludeFiles\":[]}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.ExcludeFiles); + } + + [Theory] + [InlineData("\"a\"", "a")] + [InlineData("\"a, b\"", "a, b")] + [InlineData("[null]", null)] + [InlineData("[\"\"]", "")] + [InlineData("[\"a\"]", "a")] + [InlineData("[\"a, b\"]", "a, b")] + [InlineData("[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsValid_ReturnsExcludeFiles(string value, params string[] expectedResults) + { + expectedResults = expectedResults ?? new string[] { null }; + + var json = $"{{\"packOptions\":{{\"files\":{{\"excludeFiles\":{value}}}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.ExcludeFiles); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesMappingsPropertyIsAbsent_ReturnsNullMappings() + { + const string json = "{\"packOptions\":{\"files\":{}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.Mappings); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsNull_ReturnsNullMappings() + { + const string json = "{\"packOptions\":{\"files\":{\"mappings\":null}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.PackOptions.Mappings); + } + + [Theory] + [InlineData("\"b\"", "b")] + [InlineData("\"b,c\"", "b,c")] + [InlineData("[\"b\", \"c\"]", "b", "c")] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsValid_ReturnsMappings(string value, params string[] expectedIncludes) + { + var expectedResults = new Dictionary() + { + { "a", new IncludeExcludeFiles() { Include = expectedIncludes } } + }; + var json = $"{{\"packOptions\":{{\"files\":{{\"mappings\":{{\"a\":{value}}}}}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasMultipleMappings_ReturnsMappings() + { + var expectedResults = new Dictionary() + { + { "a", new IncludeExcludeFiles() { Include = new[] { "b" } } }, + { "c", new IncludeExcludeFiles() { Include = new[] { "d", "e" } } } + }; + const string json = "{\"packOptions\":{\"files\":{\"mappings\":{\"a\":\"b\",\"c\":[\"d\", \"e\"]}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); + } + + [Fact] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasFiles_ReturnsMappings() + { + var expectedResults = new Dictionary() + { + { + "a", + new IncludeExcludeFiles() + { + Include = new [] { "b" }, + IncludeFiles = new [] { "c" }, + Exclude = new [] { "d" }, + ExcludeFiles = new [] { "e" } + } + } + }; + const string json = "{\"packOptions\":{\"files\":{\"mappings\":{\"a\":{\"include\":\"b\",\"includeFiles\":\"c\",\"exclude\":\"d\",\"excludeFiles\":\"e\"}}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); + } +#pragma warning restore CS0612 // Type or member is obsolete + + [Fact] + public void GetPackageSpec_WhenRestorePropertyIsAbsent_ReturnsNullRestoreMetadata() + { + const string json = "{}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Null(packageSpec.RestoreMetadata); + } + + [Fact] + public void GetPackageSpec_WhenRestoreValueIsEmptyObject_ReturnsRestoreMetadata() + { + const string json = "{\"restore\":{}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.NotNull(packageSpec.RestoreMetadata); + } + + [Theory] + [InlineData("null")] + [InlineData("\"\"")] + [InlineData("\"a\"")] + public void GetPackageSpec_WhenRestoreProjectStyleValueIsInvalid_ReturnsProjectStyle(string value) + { + var json = $"{{\"restore\":{{\"projectStyle\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(ProjectStyle.Unknown, packageSpec.RestoreMetadata.ProjectStyle); + } + + [Fact] + public void GetPackageSpec_WhenRestoreProjectStyleValueIsValid_ReturnsProjectStyle() + { + const ProjectStyle expectedResult = ProjectStyle.PackageReference; + + var json = $"{{\"restore\":{{\"projectStyle\":\"{expectedResult.ToString().ToLowerInvariant()}\"}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectStyle); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestoreProjectUniqueNameValueIsValid_ReturnsProjectUniqueName( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"projectUniqueName\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectUniqueName); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestoreOutputPathValueIsValid_ReturnsOutputPath( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"outputPath\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.OutputPath); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestorePackagesPathValueIsValid_ReturnsPackagesPath( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"packagesPath\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.PackagesPath); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestoreProjectJsonPathValueIsValid_ReturnsProjectJsonPath( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"projectJsonPath\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectJsonPath); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestoreProjectNameValueIsValid_ReturnsProjectName( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"projectName\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectName); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestoreProjectPathValueIsValid_ReturnsProjectPath( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"projectPath\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectPath); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenCrossTargetingValueIsValid_ReturnsCrossTargeting( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"crossTargeting\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CrossTargeting); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenLegacyPackagesDirectoryValueIsValid_ReturnsLegacyPackagesDirectory( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"legacyPackagesDirectory\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.LegacyPackagesDirectory); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenValidateRuntimeAssetsValueIsValid_ReturnsValidateRuntimeAssets( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"validateRuntimeAssets\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ValidateRuntimeAssets); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenSkipContentFileWriteValueIsValid_ReturnsSkipContentFileWrite( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"skipContentFileWrite\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.SkipContentFileWrite); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenCentralPackageVersionsManagementEnabledValueIsValid_ReturnsCentralPackageVersionsManagementEnabled( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"centralPackageVersionsManagementEnabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageVersionsEnabled); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenCentralPackageVersionOverrideDisabledValueIsValid_ReturnsCentralPackageVersionOverrideDisabled( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"centralPackageVersionOverrideDisabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageVersionOverrideDisabled); + } + + [Theory] + [InlineData(null, false)] + [InlineData(true, true)] + [InlineData(false, false)] + public void GetPackageSpec_WhenCentralPackageTransitivePinningEnabledValueIsValid_ReturnsCentralPackageTransitivePinningEnabled( + bool? value, + bool expectedValue) + { + var json = $"{{\"restore\":{{\"CentralPackageTransitivePinningEnabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageTransitivePinningEnabled); + } + + [Fact] + public void GetPackageSpec_WhenSourcesValueIsEmptyObject_ReturnsEmptySources() + { + const string json = "{\"restore\":{\"sources\":{}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.RestoreMetadata.Sources); + } + + [Fact] + public void GetPackageSpec_WhenSourcesValueIsValid_ReturnsSources() + { + PackageSource[] expectedResults = { new PackageSource(source: "a"), new PackageSource(source: "b") }; + string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult.Name}\":{{}}")); + var json = $"{{\"restore\":{{\"sources\":{{{values}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.RestoreMetadata.Sources); + } + + [Fact] + public void GetPackageSpec_WhenFilesValueIsEmptyObject_ReturnsEmptyFiles() + { + const string json = "{\"restore\":{\"files\":{}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.RestoreMetadata.Files); + } + + [Fact] + public void GetPackageSpec_WhenFilesValueIsValid_ReturnsFiles() + { + ProjectRestoreMetadataFile[] expectedResults = + { + new ProjectRestoreMetadataFile(packagePath: "a", absolutePath: "b"), + new ProjectRestoreMetadataFile(packagePath: "c", absolutePath:"d") + }; + string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult.PackagePath}\":\"{expectedResult.AbsolutePath}\"")); + var json = $"{{\"restore\":{{\"files\":{{{values}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.RestoreMetadata.Files); + } + + [Fact] + public void GetPackageSpec_WhenRestoreFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks() + { + const string json = "{\"restore\":{\"frameworks\":{}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.RestoreMetadata.TargetFrameworks); + } + + [Fact] + public void GetPackageSpec_WhenRestoreFrameworksFrameworkNameValueIsValid_ReturnsFrameworks() + { + var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); + var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{}}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Collection( + packageSpec.RestoreMetadata.TargetFrameworks, + actualResult => Assert.Equal(expectedResult, actualResult)); + } + + [Fact] + public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithoutAssets_ReturnsFrameworks() + { + var projectReference = new ProjectRestoreReference() + { + ProjectUniqueName = "a", + ProjectPath = "b" + }; + var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); + + expectedResult.ProjectReferences.Add(projectReference); + + var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{\"projectReferences\":{{" + + $"\"{projectReference.ProjectUniqueName}\":{{\"projectPath\":\"{projectReference.ProjectPath}\"}}}}}}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Collection( + packageSpec.RestoreMetadata.TargetFrameworks, + actualResult => Assert.Equal(expectedResult, actualResult)); + } + + [Fact] + public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithAssets_ReturnsFrameworks() + { + var projectReference = new ProjectRestoreReference() + { + ProjectUniqueName = "a", + ProjectPath = "b", + IncludeAssets = LibraryIncludeFlags.Analyzers, + ExcludeAssets = LibraryIncludeFlags.Native, + PrivateAssets = LibraryIncludeFlags.Runtime + }; + var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); + + expectedResult.ProjectReferences.Add(projectReference); + + var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{\"projectReferences\":{{" + + $"\"{projectReference.ProjectUniqueName}\":{{\"projectPath\":\"{projectReference.ProjectPath}\"," + + $"\"includeAssets\":\"{projectReference.IncludeAssets}\",\"excludeAssets\":\"{projectReference.ExcludeAssets}\"," + + $"\"privateAssets\":\"{projectReference.PrivateAssets}\"}}}}}}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Collection( + packageSpec.RestoreMetadata.TargetFrameworks, + actualResult => Assert.Equal(expectedResult, actualResult)); + } + + [Fact] + public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsEmptyArray_ReturnsEmptyConfigFilePaths() + { + const string json = "{\"restore\":{\"configFilePaths\":[]}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.RestoreMetadata.ConfigFilePaths); + } + + [Fact] + public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsValid_ReturnsConfigFilePaths() + { + string[] expectedResults = { "a", "b" }; + string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); + var json = $"{{\"restore\":{{\"configFilePaths\":[{values}]}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.RestoreMetadata.ConfigFilePaths); + } + + [Fact] + public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsEmptyArray_ReturnsEmptyFallbackFolders() + { + const string json = "{\"restore\":{\"fallbackFolders\":[]}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.RestoreMetadata.FallbackFolders); + } + + [Fact] + public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsValid_ReturnsConfigFilePaths() + { + string[] expectedResults = { "a", "b" }; + string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); + var json = $"{{\"restore\":{{\"fallbackFolders\":[{values}]}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.RestoreMetadata.FallbackFolders); + } + + [Fact] + public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsEmptyArray_ReturnsEmptyOriginalTargetFrameworks() + { + const string json = "{\"restore\":{\"originalTargetFrameworks\":[]}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.RestoreMetadata.OriginalTargetFrameworks); + } + + [Fact] + public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsValid_ReturnsOriginalTargetFrameworks() + { + string[] expectedResults = { "a", "b" }; + string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); + var json = $"{{\"restore\":{{\"originalTargetFrameworks\":[{values}]}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResults, packageSpec.RestoreMetadata.OriginalTargetFrameworks); + } + + [Fact] + public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsEmptyObject_ReturnsWarningProperties() + { + var expectedResult = new WarningProperties(); + const string json = "{\"restore\":{\"warningProperties\":{}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectWideWarningProperties); + } + + [Fact] + public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsValid_ReturnsWarningProperties() + { + var expectedResult = new WarningProperties( + new HashSet() { NuGetLogCode.NU3000 }, + new HashSet() { NuGetLogCode.NU3001 }, + allWarningsAsErrors: true, + new HashSet()); + var json = $"{{\"restore\":{{\"warningProperties\":{{\"allWarningsAsErrors\":{expectedResult.AllWarningsAsErrors.ToString().ToLowerInvariant()}," + + $"\"warnAsError\":[\"{expectedResult.WarningsAsErrors.Single()}\"],\"noWarn\":[\"{expectedResult.NoWarn.Single()}\"]}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectWideWarningProperties); + } + + [Fact] + public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsEmptyObject_ReturnsRestoreLockProperties() + { + var expectedResult = new RestoreLockProperties(); + const string json = "{\"restore\":{\"restoreLockProperties\":{}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RestoreMetadata.RestoreLockProperties); + } + + [Fact] + public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsValid_ReturnsRestoreLockProperties() + { + var expectedResult = new RestoreLockProperties( + restorePackagesWithLockFile: "a", + nuGetLockFilePath: "b", + restoreLockedMode: true); ; + var json = $"{{\"restore\":{{\"restoreLockProperties\":{{\"restoreLockedMode\":{expectedResult.RestoreLockedMode.ToString().ToLowerInvariant()}," + + $"\"restorePackagesWithLockFile\":\"{expectedResult.RestorePackagesWithLockFile}\"," + + $"\"nuGetLockFilePath\":\"{expectedResult.NuGetLockFilePath}\"}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RestoreMetadata.RestoreLockProperties); + } + + [Theory] + [InlineData("null")] + [InlineData("\"\"")] + [InlineData("\"a\"")] + public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsNotPackagesConfig_DoesNotReturnPackagesConfigPath( + string value) + { + var json = $"{{\"restore\":{{\"projectStyle\":\"PackageReference\",\"packagesConfigPath\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.IsNotType(packageSpec.RestoreMetadata); + } + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsPackagesConfig_ReturnsPackagesConfigPath( + string value, + string expectedValue) + { + var json = $"{{\"restore\":{{\"projectStyle\":\"PackagesConfig\",\"packagesConfigPath\":{value}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.IsType(packageSpec.RestoreMetadata); + Assert.Equal(expectedValue, ((PackagesConfigProjectRestoreMetadata)packageSpec.RestoreMetadata).PackagesConfigPath); + } + + [Fact] + public void GetPackageSpec_WhenRestoreSettingsValueIsEmptyObject_ReturnsRestoreSettings() + { + var expectedResult = new ProjectRestoreSettings(); + const string json = "{\"restoreSettings\":{}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RestoreSettings); + } + + [Fact] + public void GetPackageSpec_WhenRuntimesValueIsEmptyObject_ReturnsRuntimes() + { + var expectedResult = RuntimeGraph.Empty; + const string json = "{\"runtimes\":{}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + + [Fact] + public void GetPackageSpec_WhenRuntimesValueIsValidWithImports_ReturnsRuntimes() + { + var runtimeDescription = new RuntimeDescription( + runtimeIdentifier: "a", + inheritedRuntimes: new[] { "b", "c" }, + Enumerable.Empty()); + var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); + var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"#import\":[" + + $"{string.Join(",", runtimeDescription.InheritedRuntimes.Select(runtime => $"\"{runtime}\""))}]}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + + [Fact] + public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySet_ReturnsRuntimes() + { + var dependencySet = new RuntimeDependencySet(id: "b"); + var runtimeDescription = new RuntimeDescription( + runtimeIdentifier: "a", + inheritedRuntimes: Enumerable.Empty(), + runtimeDependencySets: new[] { dependencySet }); + var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); + var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"{dependencySet.Id}\":{{}}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + + [Fact] + public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySetWithDependency_ReturnsRuntimes() + { + var dependency = new RuntimePackageDependency("c", VersionRange.Parse("[1.2.3,4.5.6)")); + var dependencySet = new RuntimeDependencySet(id: "b", new[] { dependency }); + var runtimeDescription = new RuntimeDescription( + runtimeIdentifier: "a", + inheritedRuntimes: Enumerable.Empty(), + runtimeDependencySets: new[] { dependencySet }); + var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); + var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"{dependencySet.Id}\":{{" + + $"\"{dependency.Id}\":\"{dependency.VersionRange.ToLegacyString()}\"}}}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + + [Fact] + public void GetPackageSpec_WhenSupportsValueIsEmptyObject_ReturnsSupports() + { + var expectedResult = RuntimeGraph.Empty; + const string json = "{\"supports\":{}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + + [Fact] + public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfiles_ReturnsSupports() + { + var profile = new CompatibilityProfile(name: "a"); + var expectedResult = new RuntimeGraph(new[] { profile }); + var json = $"{{\"supports\":{{\"{profile.Name}\":{{}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + + [Fact] + public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfilesAndFrameworkRuntimePairs_ReturnsSupports() + { + FrameworkRuntimePair[] restoreContexts = new[] + { + new FrameworkRuntimePair(NuGetFramework.Parse("net472"), "b"), + new FrameworkRuntimePair(NuGetFramework.Parse("net48"), "c") + }; + var profile = new CompatibilityProfile(name: "a", restoreContexts); + var expectedResult = new RuntimeGraph(new[] { profile }); + var json = $"{{\"supports\":{{\"{profile.Name}\":{{" + + $"\"{restoreContexts[0].Framework.GetShortFolderName()}\":\"{restoreContexts[0].RuntimeIdentifier}\"," + + $"\"{restoreContexts[1].Framework.GetShortFolderName()}\":[\"{restoreContexts[1].RuntimeIdentifier}\"]}}}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.RuntimeGraph); + } + +#pragma warning disable CS0612 // Type or member is obsolete + [Fact] + public void GetPackageSpec_WhenScriptsValueIsEmptyObject_ReturnsScripts() + { + const string json = "{\"scripts\":{}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Empty(packageSpec.Scripts); + } + + [Fact] + public void GetPackageSpec_WhenScriptsValueIsInvalid_Throws() + { + var json = "{\"scripts\":{\"a\":0}}"; + + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + + Assert.Equal("The value of a script in 'project.json' can only be a string or an array of strings", exception.Message); + Assert.IsType(exception.InnerException); + Assert.Null(exception.InnerException.InnerException); + + } + + [Fact] + public void GetPackageSpec_WhenScriptsValueIsValid_ReturnsScripts() + { + const string name0 = "a"; + const string name1 = "b"; + const string script0 = "c"; + const string script1 = "d"; + const string script2 = "e"; + + var json = $"{{\"scripts\":{{\"{name0}\":\"{script0}\",\"{name1}\":[\"{script1}\",\"{script2}\"]}}}}"; + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Collection( + packageSpec.Scripts, + actualResult => + { + Assert.Equal(name0, actualResult.Key); + Assert.Collection( + actualResult.Value, + actualScript => Assert.Equal(script0, actualScript)); + }, + actualResult => + { + Assert.Equal(name1, actualResult.Key); + Assert.Collection( + actualResult.Value, + actualScript => Assert.Equal(script1, actualScript), + actualScript => Assert.Equal(script2, actualScript)); + }); + } +#pragma warning restore CS0612 // Type or member is obsolete + + [Theory] + [InlineData("null", null)] + [InlineData("\"\"", "")] + [InlineData("\"a\"", "a")] + public void GetPackageSpec_WhenTitleValueIsValid_ReturnsTitle(string value, string expectedResult) + { + var json = $"{{\"title\":{value}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.Title); + } + + [Fact] + public void GetPackageSpec_WhenNameIsNull_RestoreMetadataProvidesFallbackName() + { + const string expectedResult = "a"; + var json = $"{{\"restore\":{{\"projectName\":\"{expectedResult}\"}}}}"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.Name); + } + + [Theory] + [InlineData("{\"restore\":{\"projectJsonPath\":\"a\"}}")] + [InlineData("{\"restore\":{\"projectPath\":\"a\"}}")] + [InlineData("{\"restore\":{\"projectJsonPath\":\"a\",\"projectPath\":\"b\"}}")] + public void GetPackageSpec_WhenFilePathIsNull_RestoreMetadataProvidesFallbackFilePath(string json) + { + const string expectedResult = "a"; + + PackageSpec packageSpec = GetPackageSpec(json); + + Assert.Equal(expectedResult, packageSpec.FilePath); + } + + [Fact] + public void GetTargetFrameworkInformation_WithAnAlias() + { + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"net46\":{ \"targetAlias\" : \"alias\"}}}"); + + Assert.Equal("alias", framework.TargetAlias); + } + + [Fact] + public void PackageSpecReader_ReadsRestoreMetadataWithAliases() + { + // Arrange + var json = @"{ + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""targetAlias"" : ""alias"", + ""projectReferences"": {} + } + }, + ""warningProperties"": { + } + } +}"; + + var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + + // Assert + var metadata = actual.RestoreMetadata; + var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; + + Assert.NotNull(metadata); + Assert.Equal("alias", metadata.TargetFrameworks.Single().TargetAlias); + } + + [Fact] + public void PackageSpecReader_Read() + { + // Arrange + var json = @"{ + ""centralTransitiveDependencyGroups"": { + "".NETCoreApp,Version=v3.1"": { + ""Foo"": { + ""exclude"": ""Native"", + ""include"": ""Build"", + ""suppressParent"": ""All"", + ""version"": ""1.0.0"" + } + }, + "".NETCoreApp,Version=v3.0"": { + ""Bar"": { + ""exclude"": ""Native"", + ""include"": ""Build"", + ""suppressParent"": ""All"", + ""version"": ""2.0.0"" + } + } + } + }"; + + // Act + var results = new List(); + using Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + var reader = new Utf8JsonStreamReader(stream); + + if (reader.TokenType == JsonTokenType.StartObject) + { + while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) + { + if (reader.Read() && reader.TokenType == JsonTokenType.StartObject) + { + while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) + { + var frameworkPropertyName = reader.GetString(); + NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); + var dependencies = new List(); + + Utf8JsonStreamPackageSpecReader.ReadCentralTransitiveDependencyGroup( + jsonReader: ref reader, + results: dependencies, + packageSpecPath: "SomePath"); + results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); + } + } + } + } + + // Assert + Assert.Equal(2, results.Count); + Assert.Equal(".NETCoreApp,Version=v3.1", results.ElementAt(0).FrameworkName); + var firstGroup = results.ElementAt(0); + Assert.Equal(1, firstGroup.TransitiveDependencies.Count()); + Assert.Equal("Build", firstGroup.TransitiveDependencies.First().IncludeType.ToString()); + Assert.Equal("All", firstGroup.TransitiveDependencies.First().SuppressParent.ToString()); + Assert.Equal("[1.0.0, )", firstGroup.TransitiveDependencies.First().LibraryRange.VersionRange.ToNormalizedString()); + Assert.True(firstGroup.TransitiveDependencies.First().VersionCentrallyManaged); + + var secondGroup = results.ElementAt(1); + Assert.Equal(1, secondGroup.TransitiveDependencies.Count()); + Assert.Equal("Build", secondGroup.TransitiveDependencies.First().IncludeType.ToString()); + Assert.Equal("All", secondGroup.TransitiveDependencies.First().SuppressParent.ToString()); + Assert.Equal("[2.0.0, )", secondGroup.TransitiveDependencies.First().LibraryRange.VersionRange.ToNormalizedString()); + Assert.True(secondGroup.TransitiveDependencies.First().VersionCentrallyManaged); + } + + [Fact] + public void GetPackageSpec_WithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework() + { + var json = $"{{\"frameworks\":{{\"net5.0\":{{\"secondaryFramework\": \"native\"}}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + framework.FrameworkName.Should().BeOfType(); + var dualCompatibilityFramework = framework.FrameworkName as DualCompatibilityFramework; + dualCompatibilityFramework.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); + dualCompatibilityFramework.SecondaryFramework.Should().Be(FrameworkConstants.CommonFrameworks.Native); + } + + [Fact] + public void GetPackageSpec_WithAssetTargetFallbackAndWithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework() + { + var json = $"{{\"frameworks\":{{\"net5.0\":{{\"assetTargetFallback\": true, \"imports\": [\"net472\", \"net471\"], \"secondaryFramework\": \"native\" }}}}}}"; + + TargetFrameworkInformation framework = GetFramework(json); + framework.FrameworkName.Should().BeOfType(); + framework.AssetTargetFallback.Should().BeTrue(); + var assetTargetFallbackFramework = framework.FrameworkName as AssetTargetFallbackFramework; + assetTargetFallbackFramework.RootFramework.Should().BeOfType(); + var dualCompatibilityFramework = assetTargetFallbackFramework.RootFramework as DualCompatibilityFramework; + dualCompatibilityFramework.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); + dualCompatibilityFramework.SecondaryFramework.Should().Be(FrameworkConstants.CommonFrameworks.Native); + assetTargetFallbackFramework.Fallback.Should().HaveCount(2); + assetTargetFallbackFramework.Fallback.First().Should().Be(FrameworkConstants.CommonFrameworks.Net472); + assetTargetFallbackFramework.Fallback.Last().Should().Be(FrameworkConstants.CommonFrameworks.Net471); + } + + [Fact] + public void GetPackageSpec_WithRestoreAuditProperties_ReturnsRestoreAuditProperties() + { + // Arrange + var json = $"{{\"restore\":{{\"restoreAuditProperties\":{{\"enableAudit\": \"a\", \"auditLevel\": \"b\", \"auditMode\": \"c\"}}}}}}"; + + // Act + PackageSpec packageSpec = GetPackageSpec(json); + + // Assert + packageSpec.RestoreMetadata.RestoreAuditProperties.EnableAudit.Should().Be("a"); + packageSpec.RestoreMetadata.RestoreAuditProperties.AuditLevel.Should().Be("b"); + packageSpec.RestoreMetadata.RestoreAuditProperties.AuditMode.Should().Be("c"); + } + + private static PackageSpec GetPackageSpec(string json) + { + using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + { + return Utf8JsonStreamPackageSpecReader.GetPackageSpec(stream, name: null, packageSpecPath: null, snapshotValue: null); + } + } + + private static LibraryDependency GetDependency(string json) + { + PackageSpec packageSpec = GetPackageSpec(json); + + return packageSpec.Dependencies.Single(); + } + + private static TargetFrameworkInformation GetFramework(string json) + { + PackageSpec packageSpec = GetPackageSpec(json); + + return packageSpec.TargetFrameworks.Single(); + } + + private static LibraryDependency GetFrameworksDependency(string json) + { + TargetFrameworkInformation framework = GetFramework(json); + + return framework.Dependencies.Single(); + } + + private static FrameworkDependency GetFrameworksFrameworkReference(string json) + { + TargetFrameworkInformation framework = GetFramework(json); + + return framework.FrameworkReferences.Single(); + } + } +} diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs index 3193f43c4f5..e744202d028 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs @@ -820,6 +820,20 @@ public void ReadStringArrayAsReadOnlyListFromArrayStart_WhenValuesAreNotConverti Assert.Equal(expectedToken, tokenType); } + [Theory] + [InlineData("value")] + [InlineData("")] + public void ValueTextEquals_WithValidData_ReturnTrue(string value) + { + var json = $"{{ \"{value}\":\"property\"}}"; + var encodedBytes = Encoding.UTF8.GetBytes(json); + var utf8Bytes = Encoding.UTF8.GetBytes(value); + using var stream = new MemoryStream(encodedBytes); + using var reader = new Utf8JsonStreamReader(stream); + reader.Read(); + Assert.True(reader.ValueTextEquals(utf8Bytes)); + } + private Mock> SetupMockArrayBuffer() { Mock> mock = new Mock>(); From e6219c5233e5271e91727421e4113f158689cd33 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Tue, 12 Dec 2023 11:53:05 -0800 Subject: [PATCH 03/20] Remoce surface message param --- .../NuGet.ProjectModel/FileFormatException.cs | 8 +------- .../Utf8JsonStreamPackageSpecReader.cs | 20 +++++-------------- .../Utf8JsonStreamPackageSpecReaderTests.cs | 9 ++++----- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs index 7998fcb790b..f9946e200cf 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs @@ -10,8 +10,6 @@ namespace NuGet.ProjectModel { public class FileFormatException : Exception { - static internal string SurfaceMessage = "SurfaceMessage"; - public FileFormatException(string message) : base(message) { @@ -128,11 +126,7 @@ internal static FileFormatException Create(JsonReaderException exception, string internal static FileFormatException Create(System.Text.Json.JsonException exception, string path) { string message; - if (exception.Data.Contains(SurfaceMessage)) - { - message = exception.Message; - } - else if (exception.BytePositionInLine is not null && exception.LineNumber is not null) + if (exception.BytePositionInLine is not null && exception.LineNumber is not null) { message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorReadingProjectJsonWithLocation, diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs index 7c679142c12..aadf09b926e 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs @@ -312,9 +312,7 @@ internal static void ReadCentralTransitiveDependencyGroup( var propertyName = jsonReader.GetString(); if (string.IsNullOrEmpty(propertyName)) { - var exception = new JsonException("Unable to resolve dependency ''."); - exception.Data.Add(FileFormatException.SurfaceMessage, true); - throw exception; + throw new JsonException("Unable to resolve dependency ''."); } if (jsonReader.Read()) @@ -418,9 +416,7 @@ private static void ReadDependencies( var propertyName = jsonReader.GetString(); if (string.IsNullOrEmpty(propertyName)) { - var exception = new JsonException("Unable to resolve dependency ''."); - exception.Data.Add(FileFormatException.SurfaceMessage, true); - throw exception; + throw new JsonException("Unable to resolve dependency ''."); } // Support @@ -1292,12 +1288,10 @@ private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStream { if (jsonReader.TokenType != JsonTokenType.String) { - var exception = new JsonException(string.Format( + throw new JsonException(string.Format( CultureInfo.CurrentCulture, Strings.InvalidPackageType, PackageSpec.PackageSpecFileName)); - exception.Data.Add(FileFormatException.SurfaceMessage, true); - throw exception; } packageType = CreatePackageType(ref jsonReader); @@ -1324,12 +1318,10 @@ private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStream } catch (Exception) { - var exception = new JsonException(string.Format( + throw new JsonException(string.Format( CultureInfo.CurrentCulture, Strings.InvalidPackageType, PackageSpec.PackageSpecFileName)); - exception.Data.Add(FileFormatException.SurfaceMessage, true); - throw exception; } } @@ -1579,9 +1571,7 @@ private static void ReadScripts(ref Utf8JsonStreamReader jsonReader, PackageSpec } else { - var exception = new JsonException(string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName)); - exception.Data.Add(FileFormatException.SurfaceMessage, true); - throw exception; + throw new JsonException(string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName)); } } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs index 4d97217c904..5e65c57d60e 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs @@ -1176,8 +1176,7 @@ public void GetPackageSpec_WhenDependenciesDependencyNameIsEmptyString_Throws() const string json = "{\"dependencies\":{\"\":{}}}"; FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Unable to resolve dependency ''.", exception.Message); + Assert.Equal("Error reading '' : Unable to resolve dependency ''.", exception.Message); } [Fact] @@ -1660,7 +1659,7 @@ public void GetPackageSpec_WhenFrameworksDependenciesDependencyNameIsEmptyString FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - Assert.Equal("Unable to resolve dependency ''.", exception.Message); + Assert.Equal("Error reading '' : Unable to resolve dependency ''.", exception.Message); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); } @@ -2493,7 +2492,7 @@ public void GetPackageSpec_WhenPackOptionsPackageTypeIsInvalid_Throws(string val FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - Assert.Equal("The pack options package type must be a string or array of strings in 'project.json'.", exception.Message); + Assert.Equal("Error reading '' : The pack options package type must be a string or array of strings in 'project.json'.", exception.Message); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); } @@ -3363,7 +3362,7 @@ public void GetPackageSpec_WhenScriptsValueIsInvalid_Throws() FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - Assert.Equal("The value of a script in 'project.json' can only be a string or an array of strings", exception.Message); + Assert.Equal("Error reading '' : The value of a script in 'project.json' can only be a string or an array of strings", exception.Message); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); From b3c8f8595db04b367d72a0c59e75e60132f59caf Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Wed, 13 Dec 2023 10:10:25 -0800 Subject: [PATCH 04/20] Updated tests --- .../NuGet.ProjectModel/FileFormatException.cs | 18 + .../JsonPackageSpecReader.cs | 36 +- .../Utf8JsonStreamPackageSpecReader.cs | 111 +- .../Utf8JsonStreamReader.cs | 3 +- .../JsonPackageSpecReaderTests.cs | 3290 ++++++++------- .../Utf8JsonStreamPackageSpecReaderTests.cs | 3634 ----------------- .../TestEnvironmentVariableReader.cs | 14 +- 7 files changed, 1966 insertions(+), 5140 deletions(-) delete mode 100644 test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs diff --git a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs index f9946e200cf..0dd5de270cd 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs @@ -93,6 +93,18 @@ internal static FileFormatException Create(Exception exception, int line, int co return ex.WithFilePath(path).WithLineInfo(line, column); } + internal static FileFormatException Create(Exception exception, string path) + { + var message = string.Format(CultureInfo.CurrentCulture, + Strings.Log_ErrorReadingProjectJson, + path, + exception.Message); + + var ex = new FileFormatException(message, exception); + + return ex.WithFilePath(path); + } + public static FileFormatException Create(string message, JToken value, string path) { var lineInfo = (IJsonLineInfo)value; @@ -123,6 +135,12 @@ internal static FileFormatException Create(JsonReaderException exception, string .WithLineInfo(exception); } + internal static FileFormatException Create(string message, string path) + { + return new FileFormatException(message) + .WithFilePath(path); + } + internal static FileFormatException Create(System.Text.Json.JsonException exception, string path) { string message; diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index 122803d8bf5..94e1041bc83 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -39,22 +39,7 @@ public static PackageSpec GetPackageSpec(string json, string name, string packag public static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue) { - var useNj = EnvironmentVariableWrapper.Instance.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"); - if (string.IsNullOrEmpty(useNj) || useNj.Equals("false", StringComparison.OrdinalIgnoreCase)) - { - return Utf8JsonStreamPackageSpecReader.GetPackageSpec(stream, name, packageSpecPath, snapshotValue); - } - else - { - using (var textReader = new StreamReader(stream)) - using (var jsonReader = new JsonTextReader(textReader)) - { -#pragma warning disable CS0612 // Type or member is obsolete - return GetPackageSpec(jsonReader, packageSpecPath); -#pragma warning restore CS0612 // Type or member is obsolete - } - } - + return GetPackageSpec(stream, name, packageSpecPath, snapshotValue, EnvironmentVariableWrapper.Instance); } [Obsolete("This method is obsolete and will be removed in a future release.")] @@ -78,5 +63,24 @@ internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string pac { return NjPackageSpecReader.GetPackageSpec(jsonReader, packageSpecPath); } + + internal static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue, IEnvironmentVariableReader environmentVariableReader) + { + var useNj = environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"); + if (string.IsNullOrEmpty(useNj) || useNj.Equals("false", StringComparison.OrdinalIgnoreCase)) + { + return Utf8JsonStreamPackageSpecReader.GetPackageSpec(stream, name, packageSpecPath, snapshotValue); + } + else + { + using (var textReader = new StreamReader(stream)) + using (var jsonReader = new JsonTextReader(textReader)) + { +#pragma warning disable CS0612 // Type or member is obsolete + return GetPackageSpec(jsonReader, packageSpecPath); +#pragma warning restore CS0612 // Type or member is obsolete + } + } + } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs index aadf09b926e..86a1ffc27e9 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs @@ -122,14 +122,7 @@ internal static PackageSpec GetPackageSpec(Stream stream, string name, string pa { var reader = new Utf8JsonStreamReader(stream); PackageSpec packageSpec; - try - { - packageSpec = GetPackageSpec(ref reader, name, packageSpecPath, snapshotValue); - } - catch (JsonException innerException) - { - throw FileFormatException.Create(innerException, packageSpecPath); - } + packageSpec = GetPackageSpec(ref reader, name, packageSpecPath, snapshotValue); if (!string.IsNullOrEmpty(name)) { @@ -251,7 +244,7 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, } catch (Exception ex) { - throw new JsonException($"Error processing versino property. version: {version}", innerException: ex); + throw FileFormatException.Create(ex, version, packageSpec.FilePath); } } } @@ -312,7 +305,9 @@ internal static void ReadCentralTransitiveDependencyGroup( var propertyName = jsonReader.GetString(); if (string.IsNullOrEmpty(propertyName)) { - throw new JsonException("Unable to resolve dependency ''."); + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + packageSpecPath); } if (jsonReader.Read()) @@ -371,13 +366,17 @@ internal static void ReadCentralTransitiveDependencyGroup( } catch (Exception ex) { - throw new JsonException(null, ex); + throw FileFormatException.Create( + ex, + packageSpecPath); } } if (dependencyVersionRange == null) { - throw new JsonException(Strings.MissingVersionOnDependency, new ArgumentException(Strings.MissingVersionOnDependency)); + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + packageSpecPath); } // the dependency flags are: Include flags - Exclude flags @@ -416,7 +415,7 @@ private static void ReadDependencies( var propertyName = jsonReader.GetString(); if (string.IsNullOrEmpty(propertyName)) { - throw new JsonException("Unable to resolve dependency ''."); + throw FileFormatException.Create("Unable to resolve dependency ''.", packageSpecPath); } // Support @@ -503,7 +502,7 @@ private static void ReadDependencies( } catch (Exception ex) { - throw new JsonException(ex.Message, innerException: ex); + throw FileFormatException.Create(ex, packageSpecPath); } } } @@ -532,7 +531,9 @@ private static void ReadDependencies( } catch (Exception ex) { - throw new JsonException(ex.Message, ex); + throw FileFormatException.Create( + ex, + packageSpecPath); } } @@ -541,7 +542,9 @@ private static void ReadDependencies( { if ((targetFlagsValue & LibraryDependencyTarget.Package) == LibraryDependencyTarget.Package) { - throw new JsonException(Strings.MissingVersionOnDependency, new ArgumentException(Strings.MissingVersionOnDependency)); + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + packageSpecPath); } else { @@ -613,7 +616,8 @@ private static void ReadBuildOptions(ref Utf8JsonStreamReader jsonReader, Packag private static void ReadCentralPackageVersions( ref Utf8JsonStreamReader jsonReader, - IDictionary centralPackageVersions) + IDictionary centralPackageVersions, + string filePath) { if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) { @@ -623,16 +627,14 @@ private static void ReadCentralPackageVersions( if (string.IsNullOrEmpty(propertyName)) { - var exception = new JsonException("Unable to resolve central version ''."); - throw exception; + throw FileFormatException.Create("Unable to resolve central version ''.", filePath); } string version = jsonReader.ReadNextTokenAsString(); if (string.IsNullOrEmpty(version)) { - var exception = new JsonException("The version cannot be null or empty."); - throw exception; + throw FileFormatException.Create("The version cannot be null or empty.", filePath); } centralPackageVersions[propertyName] = new CentralPackageVersion(propertyName, VersionRange.Parse(version)); @@ -713,8 +715,9 @@ private static void ReadDownloadDependencies( if (!isNameDefined) { - var exception = new JsonException("Unable to resolve downloadDependency ''."); - throw exception; + throw FileFormatException.Create( + "Unable to resolve downloadDependency ''.", + packageSpecPath); } if (!seenIds.Add(name)) @@ -725,8 +728,9 @@ private static void ReadDownloadDependencies( if (string.IsNullOrEmpty(versionValue)) { - var exception = new JsonException("The version cannot be null or empty"); - throw exception; + throw FileFormatException.Create( + "The version cannot be null or empty", + packageSpecPath); } string[] versions = versionValue.Split(VersionSeparators, StringSplitOptions.RemoveEmptyEntries); @@ -741,7 +745,9 @@ private static void ReadDownloadDependencies( } catch (Exception ex) { - throw new JsonException(ex.Message, ex); + throw FileFormatException.Create( + ex, + packageSpecPath); } } } while (jsonReader.TokenType == JsonTokenType.EndObject); @@ -760,8 +766,9 @@ private static void ReadFrameworkReferences( var frameworkName = jsonReader.GetString(); if (string.IsNullOrEmpty(frameworkName)) { - var exception = new JsonException("Unable to resolve frameworkReference."); - throw exception; + throw FileFormatException.Create( + "Unable to resolve frameworkReference.", + packageSpecPath); } var privateAssets = FrameworkDependencyFlagsUtils.Default; @@ -794,7 +801,14 @@ private static void ReadFrameworks(ref Utf8JsonStreamReader reader, PackageSpec { while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) { - ReadTargetFrameworks(packageSpec, ref reader); + try + { + ReadTargetFrameworks(packageSpec, ref reader); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, packageSpec.FilePath); + } } } } @@ -811,12 +825,13 @@ private static void ReadImports(PackageSpec packageSpec, ref Utf8JsonStreamReade if (!framework.IsSpecificFramework) { - var exception = new JsonException(string.Format( + throw FileFormatException.Create( + string.Format( CultureInfo.CurrentCulture, Strings.Log_InvalidImportFramework, import, - PackageSpec.PackageSpecFileName)); - throw exception; + PackageSpec.PackageSpecFileName), + packageSpec.FilePath); } targetFrameworkInformation.Imports.Add(framework); @@ -1288,10 +1303,12 @@ private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStream { if (jsonReader.TokenType != JsonTokenType.String) { - throw new JsonException(string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageType, - PackageSpec.PackageSpecFileName)); + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName), + packageSpec.FilePath); } packageType = CreatePackageType(ref jsonReader); @@ -1318,10 +1335,12 @@ private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStream } catch (Exception) { - throw new JsonException(string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageType, - PackageSpec.PackageSpecFileName)); + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName), + packageSpec.FilePath); } } @@ -1571,7 +1590,9 @@ private static void ReadScripts(ref Utf8JsonStreamReader jsonReader, PackageSpec } else { - throw new JsonException(string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName)); + throw FileFormatException.Create( + string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName), + packageSpec.FilePath); } } } @@ -1613,8 +1634,9 @@ private static LibraryDependencyTarget ReadTarget( CultureInfo.CurrentCulture, Strings.InvalidDependencyTarget, targetString); - var exception = new JsonException(message); - throw exception; + throw FileFormatException.Create( + message, + packageSpecPath); } } @@ -1741,7 +1763,8 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt { ReadCentralPackageVersions( ref jsonReader, - targetFrameworkInformation.CentralPackageVersions); + targetFrameworkInformation.CentralPackageVersions, + packageSpec.FilePath); } else if (jsonReader.ValueTextEquals(Utf8Dependencies)) { diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs index 0dc89846b86..96b6c1f4c69 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamReader.cs @@ -146,8 +146,7 @@ internal IReadOnlyList ReadDelimitedString() return value.Split(DelimitedStringDelimiters, StringSplitOptions.RemoveEmptyEntries); default: - var invalidCastException = new InvalidCastException(); - throw new JsonException(invalidCastException.Message, invalidCastException); + throw new InvalidCastException(); } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index b3bfdd938b1..ed0c252d3d1 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using FluentAssertions; using Newtonsoft.Json; using NuGet.Common; @@ -15,6 +16,8 @@ using NuGet.RuntimeModel; using NuGet.Versioning; using Xunit; +using System.Text.Json; +using Test.Utility; namespace NuGet.ProjectModel.Test { @@ -22,8 +25,9 @@ namespace NuGet.ProjectModel.Test [Obsolete] public class JsonPackageSpecReaderTests { - [Fact] - public void PackageSpecReader_PackageMissingVersion() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_PackageMissingVersion(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -42,7 +46,7 @@ public void PackageSpecReader_PackageMissingVersion() try { - var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); } catch (Exception ex) { @@ -53,50 +57,53 @@ public void PackageSpecReader_PackageMissingVersion() Assert.Contains("specify a version range", exception.Message); } - [Fact] - public void PackageSpecReader_ProjectMissingVersion() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ProjectMissingVersion(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""project"" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; + ""dependencies"": { + ""packageA"": { + ""target"": ""project"" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; // Act - var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + var spec = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); var range = spec.Dependencies.Single().LibraryRange.VersionRange; // Assert Assert.Equal(VersionRange.All, range); } - [Fact] - public void PackageSpecReader_PackageEmptyVersion() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_PackageEmptyVersion(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": """" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": """" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; Exception exception = null; try { - var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); } catch (Exception ex) { @@ -107,27 +114,28 @@ public void PackageSpecReader_PackageEmptyVersion() Assert.Contains("specify a version range", exception.Message); } - [Fact] - public void PackageSpecReader_PackageWhitespaceVersion() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_PackageWhitespaceVersion(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": "" "" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": "" "" + } + }, + ""frameworks"": { + ""net46"": {} + } + }"; Exception exception = null; try { - var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); } catch (Exception ex) { @@ -138,44 +146,46 @@ public void PackageSpecReader_PackageWhitespaceVersion() Assert.Contains("not a valid version string", exception.Message); } - [Fact] - public void PackageSpecReader_FrameworkAssemblyEmptyVersion() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_FrameworkAssemblyEmptyVersion(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""frameworks"": { - ""net46"": { - ""frameworkAssemblies"": { - ""packageA"": """" + ""frameworks"": { + ""net46"": { + ""frameworkAssemblies"": { + ""packageA"": """" + } + } } - } - } - }"; + }"; // Act - var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); var range = spec.TargetFrameworks.Single().Dependencies.Single().LibraryRange.VersionRange; // Assert Assert.Equal(VersionRange.All, range); } - [Fact] - public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""redist"": { - ""version"": ""1.0.0"", - ""type"": ""platform"", - ""include"": ""analyzers"" - } - } - }"; + ""dependencies"": { + ""redist"": { + ""version"": ""1.0.0"", + ""type"": ""platform"", + ""include"": ""analyzers"" + } + } + }"; // Act - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("redist")); @@ -186,30 +196,31 @@ public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform() } [Theory] - [InlineData("{}")] - [InlineData(@"{ - ""packOptions"": {} - }")] - [InlineData(@"{ - ""packOptions"": { - ""foo"": [1, 2] - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": null - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [] - } - }")] + [MemberData(nameof(TestEnvironmentVariableReader), "{}")] + [MemberData(nameof(TestEnvironmentVariableReader), "{}")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": {} + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""foo"": [1, 2] + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": null + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [] + } + }")] #pragma warning disable CS0612 // Type or member is obsolete - public void PackageSpecReader_PackOptions_Default(string json) + public void PackageSpecReader_PackOptions_Default(IEnvironmentVariableReader environmentVariableReader, string json) { // Arrange & Act - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert Assert.NotNull(actual.PackOptions); @@ -218,32 +229,32 @@ public void PackageSpecReader_PackOptions_Default(string json) } [Theory] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": ""foo"" - } - }", new[] { "foo" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": ""foo, bar"" - } - }", new[] { "foo, bar" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ ""foo"" ] - } - }", new[] { "foo" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ ""foo, bar"" ] - } - }", new[] { "foo, bar" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ ""foo"", ""bar"" ] - } - }", new[] { "foo", "bar" })] - public void PackageSpecReader_PackOptions_ValidPackageType(string json, string[] expectedNames) + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": ""foo"" + } + }", new[] { "foo" })] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": ""foo, bar"" + } + }", new[] { "foo, bar" })] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [ ""foo"" ] + } + }", new[] { "foo" })] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [ ""foo, bar"" ] + } + }", new[] { "foo, bar" })] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [ ""foo"", ""bar"" ] + } + }", new[] { "foo", "bar" })] + public void PackageSpecReader_PackOptions_ValidPackageType(IEnvironmentVariableReader environmentVariableReader, string json, string[] expectedNames) { // Arrange var expected = expectedNames @@ -251,7 +262,7 @@ public void PackageSpecReader_PackOptions_ValidPackageType(string json, string[] .ToArray(); // Act - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert Assert.NotNull(actual.PackOptions); @@ -260,84 +271,85 @@ public void PackageSpecReader_PackOptions_ValidPackageType(string json, string[] } [Theory] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": 1 - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": false - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": 1.0 - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": {} - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": { - ""name"": ""foo"" - } - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ - { ""name"": ""foo"" }, - { ""name"": ""bar"" } - ] - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ - ""foo"", - null - ] - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ - ""foo"", - true - ] - } - }")] - public void PackageSpecReader_PackOptions_InvalidPackageType(string json) + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": 1 + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": false + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": 1.0 + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": {} + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": { + ""name"": ""foo"" + } + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [ + { ""name"": ""foo"" }, + { ""name"": ""bar"" } + ] + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [ + ""foo"", + null + ] + } + }")] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""packOptions"": { + ""packageType"": [ + ""foo"", + true + ] + } + }")] + public void PackageSpecReader_PackOptions_InvalidPackageType(IEnvironmentVariableReader environmentVariableReader, string json) { // Arrange & Act & Assert var actual = Assert.Throws( - () => NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json")); + () => GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader)); Assert.Contains("The pack options package type must be a string or array of strings in 'project.json'.", actual.Message); } - [Fact] - public void PackageSpecReader_PackOptions_Files1() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_PackOptions_Files1(IEnvironmentVariableReader environmentVariableReader) { // Arrange & Act var json = @"{ - ""packOptions"": { - ""files"": { - ""include"": ""file1"", - ""exclude"": ""file2"", - ""includeFiles"": ""file3"", - ""excludeFiles"": ""file4"", - ""mappings"": { - ""dest/path"": ""./src/path"" - } - } - } - }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + ""packOptions"": { + ""files"": { + ""include"": ""file1"", + ""exclude"": ""file2"", + ""includeFiles"": ""file3"", + ""excludeFiles"": ""file4"", + ""mappings"": { + ""dest/path"": ""./src/path"" + } + } + } + }"; + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert Assert.NotNull(actual.PackOptions); @@ -359,27 +371,28 @@ public void PackageSpecReader_PackOptions_Files1() Assert.Equal("./src/path", actual.PackOptions.Mappings.First().Value.Include.First()); } - [Fact] - public void PackageSpecReader_PackOptions_Files2() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_PackOptions_Files2(IEnvironmentVariableReader environmentVariableReader) { // Arrange & Act var json = @"{ - ""packOptions"": { - ""files"": { - ""include"": [""file1a"", ""file1b""], - ""exclude"": [""file2a"", ""file2b""], - ""includeFiles"": [""file3a"", ""file3b""], - ""excludeFiles"": [""file4a"", ""file4b""], - ""mappings"": { - ""dest/path1"": [""./src/path1"", ""./src/path2""], - ""dest/path2"": { - ""includeFiles"": [""map1a"", ""map1b""], - }, - } - } - } - }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + ""packOptions"": { + ""files"": { + ""include"": [""file1a"", ""file1b""], + ""exclude"": [""file2a"", ""file2b""], + ""includeFiles"": [""file3a"", ""file3b""], + ""excludeFiles"": [""file4a"", ""file4b""], + ""mappings"": { + ""dest/path1"": [""./src/path1"", ""./src/path2""], + ""dest/path2"": { + ""includeFiles"": [""map1a"", ""map1b""], + }, + } + } + } + }"; + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert Assert.NotNull(actual.PackOptions); @@ -413,30 +426,30 @@ public void PackageSpecReader_PackOptions_Files2() } [Theory] - [InlineData("{}", null, true)] - [InlineData(@"{ - ""buildOptions"": {} - }", null, false)] - [InlineData(@"{ - ""buildOptions"": { - ""outputName"": ""dllName"" - } - }", "dllName", false)] - [InlineData(@"{ - ""buildOptions"": { - ""outputName"": ""dllName2"", - ""emitEntryPoint"": true - } - }", "dllName2", false)] - [InlineData(@"{ - ""buildOptions"": { - ""outputName"": null - } - }", null, false)] - public void PackageSpecReader_BuildOptions(string json, string expectedValue, bool nullBuildOptions) + [MemberData(nameof(TestEnvironmentVariableReader), "{}", null, true)] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""buildOptions"": {} + }", null, false)] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""buildOptions"": { + ""outputName"": ""dllName"" + } + }", "dllName", false)] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""buildOptions"": { + ""outputName"": ""dllName2"", + ""emitEntryPoint"": true + } + }", "dllName2", false)] + [MemberData(nameof(TestEnvironmentVariableReader), @"{ + ""buildOptions"": { + ""outputName"": null + } + }", null, false)] + public void PackageSpecReader_BuildOptions(IEnvironmentVariableReader environmentVariableReader, string json, string expectedValue, bool nullBuildOptions) { // Arrange & Act - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert if (nullBuildOptions) @@ -451,23 +464,24 @@ public void PackageSpecReader_BuildOptions(string json, string expectedValue, bo } #pragma warning restore CS0612 // Type or member is obsolete - [Fact] - public void PackageSpecReader_ReadsWithoutRestoreSettings() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsWithoutRestoreSettings(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"" - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"" + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert Assert.NotNull(actual); @@ -475,27 +489,28 @@ public void PackageSpecReader_ReadsWithoutRestoreSettings() Assert.False(actual.RestoreSettings.HideWarningsAndErrors); } - [Fact] - public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ""NU1500"", - ""NU1107"" - ] - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ""NU1500"", + ""NU1107"" + ] + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); @@ -506,26 +521,27 @@ public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn() Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1107)); } - [Fact] - public void PackageSpecReader_ReadsDependencyWithSingleNoWarn() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsDependencyWithSingleNoWarn(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ""NU1500"" - ] - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ""NU1500"" + ] + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); @@ -535,25 +551,26 @@ public void PackageSpecReader_ReadsDependencyWithSingleNoWarn() Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); } - [Fact] - public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ] - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ] + } + }, + ""frameworks"": { + ""net46"": {} + }, + }"; + + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); @@ -562,61 +579,62 @@ public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn() Assert.Equal(dep.NoWarn.Count, 0); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningProperties(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""allWarningsAsErrors"": true, - ""noWarn"": [ - ""NU1601"", - ], - ""warnAsError"": [ - ""NU1500"", - ""NU1501"" - ], - ""warnNotAsError"": [ - ""NU1801"", - ""NU1802"" - ] - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""allWarningsAsErrors"": true, + ""noWarn"": [ + ""NU1601"", + ], + ""warnAsError"": [ + ""NU1500"", + ""NU1501"" + ], + ""warnNotAsError"": [ + ""NU1801"", + ""NU1802"" + ] + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -635,54 +653,55 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningProperties() Assert.True(warningProperties.WarningsNotAsErrors.Contains(NuGetLogCode.NU1802)); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_NoWarn() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_NoWarn(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""allWarningsAsErrors"": true, - ""warnAsError"": [ - ""NU1500"", - ""NU1501"" - ] - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""allWarningsAsErrors"": true, + ""warnAsError"": [ + ""NU1500"", + ""NU1501"" + ] + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -697,53 +716,54 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_NoW Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_WarnAsError() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_WarnAsError(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""allWarningsAsErrors"": true, - ""noWarn"": [ - ""NU1601"", - ] - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""allWarningsAsErrors"": true, + ""noWarn"": [ + ""NU1601"", + ] + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -757,56 +777,57 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_War Assert.Equal(0, warningProperties.WarningsAsErrors.Count); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_AllWarningsAsErrors() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_AllWarningsAsErrors(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""noWarn"": [ - ""NU1601"", - ], - ""warnAsError"": [ - ""NU1500"", - ""NU1501"" - ] - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + ""noWarn"": [ + ""NU1601"", + ], + ""warnAsError"": [ + ""NU1500"", + ""NU1501"" + ] + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -822,49 +843,50 @@ public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_All Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithEmptyWarningPropertiesAnd() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithEmptyWarningPropertiesAnd(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + }, + ""warningProperties"": { + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -877,47 +899,48 @@ public void PackageSpecReader_ReadsRestoreMetadataWithEmptyWarningPropertiesAnd( Assert.Equal(0, warningProperties.WarningsAsErrors.Count); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithNoWarningProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithNoWarningProperties(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""configFilePaths"": [ + ""b"", + ""a"", + ""c"" + ], + ""fallbackFolders"": [ + ""b"", + ""a"", + ""c"" + ], + ""originalTargetFrameworks"": [ + ""b"", + ""a"", + ""c"" + ], + ""sources"": { + ""source"": {} + }, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""projectReferences"": {} + } + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -927,264 +950,285 @@ public void PackageSpecReader_ReadsRestoreMetadataWithNoWarningProperties() Assert.NotNull(warningProperties); } - [Fact] - public void PackageSpecReader_RuntimeIdentifierPathNullIfEmpty() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_RuntimeIdentifierPathNullIfEmpty(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""frameworks"": { - ""net46"": { - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ""NU1500"" - ] - } - } - } - } - }"; + ""frameworks"": { + ""net46"": { + ""dependencies"": { + ""packageA"": { + ""target"": ""package"", + ""version"": ""1.0.0"", + ""noWarn"": [ + ""NU1500"" + ] + } + } + } + } + }"; // Act - var spec = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert Assert.Null(spec.TargetFrameworks.First().RuntimeIdentifierGraphPath); } #pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenAuthorsPropertyIsAbsent_ReturnsEmptyAuthors() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenAuthorsPropertyIsAbsent_ReturnsEmptyAuthors(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Empty(packageSpec.Authors); } - [Fact] - public void GetPackageSpec_WhenAuthorsValueIsNull_ReturnsEmptyAuthors() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenAuthorsValueIsNull_ReturnsEmptyAuthors(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"authors\":null}"); + PackageSpec packageSpec = GetPackageSpec("{\"authors\":null}", environmentVariableReader); Assert.Empty(packageSpec.Authors); } - [Fact] - public void GetPackageSpec_WhenAuthorsValueIsString_ReturnsEmptyAuthors() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenAuthorsValueIsString_ReturnsEmptyAuthors(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"authors\":\"b\"}"); + PackageSpec packageSpec = GetPackageSpec("{\"authors\":\"b\"}", environmentVariableReader); Assert.Empty(packageSpec.Authors); } [Theory] - [InlineData("")] - [InlineData("/**/")] - public void GetPackageSpec_WhenAuthorsValueIsEmptyArray_ReturnsEmptyAuthors(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "")] + [MemberData(nameof(TestEnvironmentVariableReader), "/**/")] + public void GetPackageSpec_WhenAuthorsValueIsEmptyArray_ReturnsEmptyAuthors(IEnvironmentVariableReader environmentVariableReader, string value) { - PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}", environmentVariableReader); Assert.Empty(packageSpec.Authors); } [Theory] - [InlineData("{}")] - [InlineData("[]")] - public void GetPackageSpec_WhenAuthorsValueElementIsNotConvertibleToString_Throws(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "{}")] + [MemberData(nameof(TestEnvironmentVariableReader), "[]")] + public void GetPackageSpec_WhenAuthorsValueElementIsNotConvertibleToString_Throws(IEnvironmentVariableReader environmentVariableReader, string value) { var json = $"{{\"authors\":[{value}]}}"; - Assert.Throws(() => GetPackageSpec(json)); + Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("true", "True")] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - public void GetPackageSpec_WhenAuthorsValueElementIsConvertibleToString_ReturnsAuthor(string value, string expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "true", "True")] + [MemberData(nameof(TestEnvironmentVariableReader), "-2", "-2")] + [MemberData(nameof(TestEnvironmentVariableReader), "3.14", "3.14")] + public void GetPackageSpec_WhenAuthorsValueElementIsConvertibleToString_ReturnsAuthor(IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { - PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}", environmentVariableReader); Assert.Collection(packageSpec.Authors, author => Assert.Equal(expectedValue, author)); } - [Fact] - public void GetPackageSpec_WhenBuildOptionsPropertyIsAbsent_ReturnsNullBuildOptions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenBuildOptionsPropertyIsAbsent_ReturnsNullBuildOptions(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Null(packageSpec.BuildOptions); } - [Fact] - public void GetPackageSpec_WhenBuildOptionsValueIsEmptyObject_ReturnsBuildOptions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenBuildOptionsValueIsEmptyObject_ReturnsBuildOptions(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{}}"); + PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{}}", environmentVariableReader); Assert.NotNull(packageSpec.BuildOptions); Assert.Null(packageSpec.BuildOptions.OutputName); } - [Fact] - public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsNull_ReturnsNullOutputName() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsNull_ReturnsNullOutputName(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{\"outputName\":null}}"); + PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{\"outputName\":null}}", environmentVariableReader); Assert.Null(packageSpec.BuildOptions.OutputName); } - [Fact] - public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsValid_ReturnsOutputName() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsValid_ReturnsOutputName(IEnvironmentVariableReader environmentVariableReader) { const string expectedResult = "a"; var json = $"{{\"buildOptions\":{{\"outputName\":\"{expectedResult}\"}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.BuildOptions.OutputName); } [Theory] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - [InlineData("true", "True")] - public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsConvertibleToString_ReturnsOutputName(string outputName, string expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), "-2", "-2")] + [MemberData(nameof(TestEnvironmentVariableReader), "3.14", "3.14")] + [MemberData(nameof(TestEnvironmentVariableReader), "true", "True")] + public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsConvertibleToString_ReturnsOutputName(IEnvironmentVariableReader environmentVariableReader, string outputName, string expectedValue) { - PackageSpec packageSpec = GetPackageSpec($"{{\"buildOptions\":{{\"outputName\":{outputName}}}}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"buildOptions\":{{\"outputName\":{outputName}}}}}", environmentVariableReader); Assert.Equal(expectedValue, packageSpec.BuildOptions.OutputName); } - [Fact] - public void GetPackageSpec_WhenContentFilesPropertyIsAbsent_ReturnsEmptyContentFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenContentFilesPropertyIsAbsent_ReturnsEmptyContentFiles(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Empty(packageSpec.ContentFiles); } - [Fact] - public void GetPackageSpec_WhenContentFilesValueIsNull_ReturnsEmptyContentFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenContentFilesValueIsNull_ReturnsEmptyContentFiles(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":null}"); + PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":null}", environmentVariableReader); Assert.Empty(packageSpec.ContentFiles); } - [Fact] - public void GetPackageSpec_WhenContentFilesValueIsString_ReturnsEmptyContentFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenContentFilesValueIsString_ReturnsEmptyContentFiles(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":\"a\"}"); + PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":\"a\"}", environmentVariableReader); Assert.Empty(packageSpec.ContentFiles); } [Theory] - [InlineData("")] - [InlineData("/**/")] - public void GetPackageSpec_WhenContentFilesValueIsEmptyArray_ReturnsEmptyContentFiles(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "")] + [MemberData(nameof(TestEnvironmentVariableReader), "/**/")] + public void GetPackageSpec_WhenContentFilesValueIsEmptyArray_ReturnsEmptyContentFiles(IEnvironmentVariableReader environmentVariableReader, string value) { - PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}", environmentVariableReader); Assert.Empty(packageSpec.ContentFiles); } [Theory] - [InlineData("{}")] - [InlineData("[]")] - public void GetPackageSpec_WhenContentFilesValueElementIsNotConvertibleToString_Throws(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "{}")] + [MemberData(nameof(TestEnvironmentVariableReader), "[]")] + public void GetPackageSpec_WhenContentFilesValueElementIsNotConvertibleToString_Throws(IEnvironmentVariableReader environmentVariableReader, string value) { var json = $"{{\"contentFiles\":[{value}]}}"; - Assert.Throws(() => GetPackageSpec(json)); + Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("true", "True")] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - public void GetPackageSpec_WhenContentFilesValueElementIsConvertibleToString_ReturnsContentFile(string value, string expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "true", "True")] + [MemberData(nameof(TestEnvironmentVariableReader), "-2", "-2")] + [MemberData(nameof(TestEnvironmentVariableReader), "3.14", "3.14")] + public void GetPackageSpec_WhenContentFilesValueElementIsConvertibleToString_ReturnsContentFile(IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { - PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}", environmentVariableReader); Assert.Collection(packageSpec.ContentFiles, contentFile => Assert.Equal(expectedValue, contentFile)); } - [Fact] - public void GetPackageSpec_WhenCopyrightPropertyIsAbsent_ReturnsNullCopyright() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenCopyrightPropertyIsAbsent_ReturnsNullCopyright(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Null(packageSpec.Copyright); } - [Fact] - public void GetPackageSpec_WhenCopyrightValueIsNull_ReturnsNullCopyright() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenCopyrightValueIsNull_ReturnsNullCopyright(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"copyright\":null}"); + PackageSpec packageSpec = GetPackageSpec("{\"copyright\":null}", environmentVariableReader); Assert.Null(packageSpec.Copyright); } - [Fact] - public void GetPackageSpec_WhenCopyrightValueIsString_ReturnsCopyright() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenCopyrightValueIsString_ReturnsCopyright(IEnvironmentVariableReader environmentVariableReader) { const string expectedResult = "a"; - PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":\"{expectedResult}\"}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":\"{expectedResult}\"}}", environmentVariableReader); Assert.Equal(expectedResult, packageSpec.Copyright); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("true", "True")] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - public void GetPackageSpec_WhenCopyrightValueIsConvertibleToString_ReturnsCopyright(string value, string expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "true", "True")] + [MemberData(nameof(TestEnvironmentVariableReader), "-2", "-2")] + [MemberData(nameof(TestEnvironmentVariableReader), "3.14", "3.14")] + public void GetPackageSpec_WhenCopyrightValueIsConvertibleToString_ReturnsCopyright(IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { - PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":{value}}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":{value}}}", environmentVariableReader); Assert.Equal(expectedValue, packageSpec.Copyright); } #pragma warning restore CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenDependenciesPropertyIsAbsent_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesPropertyIsAbsent_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Empty(packageSpec.Dependencies); } - [Fact] - public void GetPackageSpec_WhenDependenciesValueIsNull_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesValueIsNull_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"dependencies\":null}"); + PackageSpec packageSpec = GetPackageSpec("{\"dependencies\":null}", environmentVariableReader); Assert.Empty(packageSpec.Dependencies); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyNameIsEmptyString_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyNameIsEmptyString_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"\":{}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); Assert.Equal("Unable to resolve dependency ''.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(21, exception.Column); Assert.Null(exception.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(1, exception.Line); + Assert.Equal(21, exception.Column); + } } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new LibraryRange( name: "a", @@ -1192,13 +1236,14 @@ public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionString_Return LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); var json = $"{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange.ToShortString()}\"}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.LibraryRange); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new LibraryRange( name: "a", @@ -1206,207 +1251,238 @@ public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionRangeString_R LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); var json = $"{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange}\"}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.LibraryRange); } [Theory] - [InlineData(LibraryDependencyTarget.None)] - [InlineData(LibraryDependencyTarget.Assembly)] - [InlineData(LibraryDependencyTarget.Reference)] - [InlineData(LibraryDependencyTarget.WinMD)] - [InlineData(LibraryDependencyTarget.All)] - [InlineData(LibraryDependencyTarget.PackageProjectExternal)] - public void GetPackageSpec_WhenDependenciesDependencyTargetIsUnsupported_Throws(LibraryDependencyTarget target) + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.None)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.Assembly)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.Reference)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.WinMD)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.All)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.PackageProjectExternal)] + public void GetPackageSpec_WhenDependenciesDependencyTargetIsUnsupported_Throws(IEnvironmentVariableReader environmentVariableReader, LibraryDependencyTarget target) { var json = $"{{\"dependencies\":{{\"a\":{{\"version\":\"1.2.3\",\"target\":\"{target}\"}}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); Assert.Equal($"Invalid dependency target value '{target}'.", exception.Message); - Assert.Equal(1, exception.Line); - // The position is after the target name, which is of variable length. - Assert.Equal(json.IndexOf(target.ToString()) + target.ToString().Length + 1, exception.Column); Assert.Null(exception.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(1, exception.Line); + // The position is after the target name, which is of variable length. + Assert.Equal(json.IndexOf(target.ToString()) + target.ToString().Length + 1, exception.Column); + } } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced(IEnvironmentVariableReader environmentVariableReader) { - LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Project\"}}}}}}"); + LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Project\"}}}}}}", environmentVariableReader); Assert.False(dependency.AutoReferenced); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(bool expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(IEnvironmentVariableReader environmentVariableReader, bool expectedValue) { var json = $"{{\"dependencies\":{{\"a\":{{\"autoReferenced\":{expectedValue.ToString().ToLower()},\"target\":\"Project\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedValue, dependency.AutoReferenced); } [Theory] - [InlineData("exclude")] - [InlineData("include")] - [InlineData("suppressParent")] - public void GetPackageSpec_WhenDependenciesDependencyValueIsArray_Throws(string propertyName) + [MemberData(nameof(TestEnvironmentVariableReader), "exclude")] + [MemberData(nameof(TestEnvironmentVariableReader), "include")] + [MemberData(nameof(TestEnvironmentVariableReader), "suppressParent")] + public void GetPackageSpec_WhenDependenciesDependencyValueIsArray_Throws(IEnvironmentVariableReader environmentVariableReader, string propertyName) { var json = $"{{\"dependencies\":{{\"a\":{{\"{propertyName}\":[\"b\"]}}}}}}"; - Assert.Throws(() => GetPackageSpec(json)); + Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.All, dependency.IncludeType); } [Theory] - [InlineData("\"Native\"", LibraryIncludeFlags.Native)] - [InlineData("\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"Native\"", LibraryIncludeFlags.Native)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] public void GetPackageSpec_WhenDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType( + IEnvironmentVariableReader environmentVariableReader, string value, LibraryIncludeFlags result) { var json = $"{{\"dependencies\":{{\"a\":{{\"exclude\":{value},\"version\":\"1.0.0\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.All & ~result, dependency.IncludeType); } [Theory] - [InlineData("\"Native\"", LibraryIncludeFlags.Native)] - [InlineData("\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"Native\"", LibraryIncludeFlags.Native)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] public void GetPackageSpec_WhenDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType( + IEnvironmentVariableReader environmentVariableReader, string value, LibraryIncludeFlags expectedResult) { var json = $"{{\"dependencies\":{{\"a\":{{\"include\":{value},\"version\":\"1.0.0\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.IncludeType); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"include\":\"ContentFiles\",\"type\":\"BecomesNupkgDependency, SharedFramework\",\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"suppressParent\":\"ContentFiles\",\"type\":\"SharedFramework\",\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.SuppressParent); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlagUtils.DefaultSuppressParent, dependency.SuppressParent); } [Theory] - [InlineData("\"Compile\"", LibraryIncludeFlags.Compile)] - [InlineData("\"Analyzers, Compile\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Compile)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"Compile\"", LibraryIncludeFlags.Compile)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"Analyzers, Compile\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Compile)] public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent( + IEnvironmentVariableReader environmentVariableReader, string value, - LibraryIncludeFlags expectedResult) + LibraryIncludeFlags expectedResult + ) { var json = $"{{\"dependencies\":{{\"a\":{{\"suppressParent\":{value},\"version\":\"1.0.0\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.SuppressParent); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyVersionValueIsInvalid_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyVersionValueIsInvalid_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"b\"}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 35 : 'b' is not a valid version string.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(35, exception.Column); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 35 : 'b' is not a valid version string.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(35, exception.Column); + } + else + { + Assert.Equal("Error reading '' : 'b' is not a valid version string.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"target\":\"Package\"}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' at line 1 column 22 : Package dependencies must specify a version range.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(22, exception.Column); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 22 : Package dependencies must specify a version range.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(22, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange(IEnvironmentVariableReader environmentVariableReader) { - LibraryDependency dependency = GetDependency("{\"dependencies\":{\"a\":{\"target\":\"Project\"}}}"); + LibraryDependency dependency = GetDependency("{\"dependencies\":{\"a\":{\"target\":\"Project\"}}}", environmentVariableReader); Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Empty(dependency.NoWarn); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns(IEnvironmentVariableReader environmentVariableReader) { NuGetLogCode[] expectedResults = { NuGetLogCode.NU1000, NuGetLogCode.NU3000 }; var json = $"{{\"dependencies\":{{\"a\":{{\"noWarn\":[\"{expectedResults[0].ToString()}\",\"{expectedResults[1].ToString()}\"],\"version\":\"1.0.0\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Collection( dependency.NoWarn, @@ -1414,144 +1490,153 @@ public void GetPackageSpec_WhenDependenciesDependencyNoWarnValueIsValid_ReturnsN noWarn => Assert.Equal(expectedResults[1], noWarn)); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.False(dependency.GeneratePathProperty); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(bool expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(IEnvironmentVariableReader environmentVariableReader, bool expectedResult) { var json = $"{{\"dependencies\":{{\"a\":{{\"generatePathProperty\":{expectedResult.ToString().ToLowerInvariant()},\"version\":\"1.0.0\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.GeneratePathProperty); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal( LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged(IEnvironmentVariableReader environmentVariableReader) { - LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}"); + LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}", environmentVariableReader); Assert.False(dependency.VersionCentrallyManaged); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(bool expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(IEnvironmentVariableReader environmentVariableReader, bool expectedValue) { var json = $"{{\"dependencies\":{{\"a\":{{\"versionCentrallyManaged\":{expectedValue.ToString().ToLower()},\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}"; - LibraryDependency dependency = GetDependency(json); + LibraryDependency dependency = GetDependency(json, environmentVariableReader); Assert.Equal(expectedValue, dependency.VersionCentrallyManaged); } #pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenDescriptionPropertyIsAbsent_ReturnsNullDescription() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenDescriptionPropertyIsAbsent_ReturnsNullDescription(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Null(packageSpec.Description); } [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("b")] - public void GetPackageSpec_WhenDescriptionValueIsValid_ReturnsDescription(string expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), null)] + [MemberData(nameof(TestEnvironmentVariableReader), "")] + [MemberData(nameof(TestEnvironmentVariableReader), "b")] + public void GetPackageSpec_WhenDescriptionValueIsValid_ReturnsDescription(IEnvironmentVariableReader environmentVariableReader, string expectedResult) { string description = expectedResult == null ? "null" : $"\"{expectedResult}\""; - PackageSpec packageSpec = GetPackageSpec($"{{\"description\":{description}}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"description\":{description}}}", environmentVariableReader); Assert.Equal(expectedResult, packageSpec.Description); } - [Fact] - public void GetPackageSpec_WhenLanguagePropertyIsAbsent_ReturnsNullLanguage() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenLanguagePropertyIsAbsent_ReturnsNullLanguage(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Null(packageSpec.Language); } [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("b")] - public void GetPackageSpec_WhenLanguageValueIsValid_ReturnsLanguage(string expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), null)] + [MemberData(nameof(TestEnvironmentVariableReader), "")] + [MemberData(nameof(TestEnvironmentVariableReader), "b")] + public void GetPackageSpec_WhenLanguageValueIsValid_ReturnsLanguage(IEnvironmentVariableReader environmentVariableReader, string expectedResult) { string language = expectedResult == null ? "null" : $"\"{expectedResult}\""; - PackageSpec packageSpec = GetPackageSpec($"{{\"language\":{language}}}"); + PackageSpec packageSpec = GetPackageSpec($"{{\"language\":{language}}}", environmentVariableReader); Assert.Equal(expectedResult, packageSpec.Language); } #pragma warning restore CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenFrameworksPropertyIsAbsent_ReturnsEmptyFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksPropertyIsAbsent_ReturnsEmptyFrameworks(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Empty(packageSpec.TargetFrameworks); } - [Fact] - public void GetPackageSpec_WhenFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{\"frameworks\":{}}"); + PackageSpec packageSpec = GetPackageSpec("{\"frameworks\":{}}", environmentVariableReader); Assert.Empty(packageSpec.TargetFrameworks); } - [Fact] - public void GetPackageSpec_WhenFrameworksAssetTargetFallbackPropertyIsAbsent_ReturnsFalseAssetTargetFallback() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksAssetTargetFallbackPropertyIsAbsent_ReturnsFalseAssetTargetFallback(IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}", environmentVariableReader); Assert.False(framework.AssetTargetFallback); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksAssetTargetFallbackValueIsValid_ReturnsAssetTargetFallback(bool expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenFrameworksAssetTargetFallbackValueIsValid_ReturnsAssetTargetFallback(IEnvironmentVariableReader environmentVariableReader, bool expectedValue) { var json = $"{{\"frameworks\":{{\"a\":{{\"assetTargetFallback\":{expectedValue.ToString().ToLowerInvariant()}}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Equal(expectedValue, framework.AssetTargetFallback); } - [Fact] - public void GetPackageSpec_WithAssetTargetFallbackAndImportsValues_ReturnsValidAssetTargetFallbackFramework() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WithAssetTargetFallbackAndImportsValues_ReturnsValidAssetTargetFallbackFramework(IEnvironmentVariableReader environmentVariableReader) { var json = $"{{\"frameworks\":{{\"net5.0\":{{\"assetTargetFallback\": true, \"imports\": [\"net472\", \"net471\"]}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); framework.AssetTargetFallback.Should().BeTrue(); var assetTargetFallback = framework.FrameworkName as AssetTargetFallbackFramework; @@ -1561,61 +1646,81 @@ public void GetPackageSpec_WithAssetTargetFallbackAndImportsValues_ReturnsValidA assetTargetFallback.Fallback.Last().Should().Be(FrameworkConstants.CommonFrameworks.Net471); } - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsPropertyIsAbsent_ReturnsEmptyCentralPackageVersions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsPropertyIsAbsent_ReturnsEmptyCentralPackageVersions(IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}", environmentVariableReader); Assert.Empty(framework.CentralPackageVersions); } - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsValueIsEmptyObject_ReturnsEmptyCentralPackageVersions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsValueIsEmptyObject_ReturnsEmptyCentralPackageVersions(IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"centralPackageVersions\":{}}}}"); + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"centralPackageVersions\":{}}}}", environmentVariableReader); Assert.Empty(framework.CentralPackageVersions); } - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyNameIsEmptyString_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyNameIsEmptyString_Throws(IEnvironmentVariableReader environmentVariableReader) { var json = "{\"frameworks\":{\"a\":{\"centralPackageVersions\":{\"\":\"1.0.0\"}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve central version ''.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve central version ''.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Unable to resolve central version ''.", exception.Message); + } } [Theory] - [InlineData("null")] - [InlineData("\"\"")] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyValueIsNullOrEmptyString_Throws(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "null")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"")] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyValueIsNullOrEmptyString_Throws(IEnvironmentVariableReader environmentVariableReader, string value) { var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"b\":{value}}}}}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : The version cannot be null or empty.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : The version cannot be null or empty.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : The version cannot be null or empty.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsIsValid_ReturnsCentralPackageVersions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsIsValid_ReturnsCentralPackageVersions(IEnvironmentVariableReader environmentVariableReader) { const string expectedPackageId = "b"; VersionRange expectedVersionRange = VersionRange.Parse("[1.2.3,4.5.6)"); var expectedCentralPackageVersion = new CentralPackageVersion(expectedPackageId, expectedVersionRange); var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"{expectedPackageId}\":\"{expectedVersionRange.ToShortString()}\"}}}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Collection( framework.CentralPackageVersions, @@ -1626,8 +1731,9 @@ public void GetPackageSpec_WhenFrameworksCentralPackageVersionsIsValid_ReturnsCe }); } - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsHasDuplicateKey_LastOneWins() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksCentralPackageVersionsHasDuplicateKey_LastOneWins(IEnvironmentVariableReader environmentVariableReader) { const string expectedPackageId = "b"; VersionRange unexpectedVersionRange = VersionRange.Parse("1.2.3"); @@ -1636,7 +1742,7 @@ public void GetPackageSpec_WhenFrameworksCentralPackageVersionsHasDuplicateKey_L var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"{expectedPackageId}\":\"{unexpectedVersionRange.ToShortString()}\"," + $"\"{expectedPackageId}\":\"{expectedVersionRange.ToShortString()}\"}}}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Collection( framework.CentralPackageVersions, @@ -1647,38 +1753,49 @@ public void GetPackageSpec_WhenFrameworksCentralPackageVersionsHasDuplicateKey_L }); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesPropertyIsAbsent_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesPropertyIsAbsent_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}", environmentVariableReader); Assert.Empty(framework.Dependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesValueIsNull_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesValueIsNull_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"dependencies\":null}}}"); + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"dependencies\":null}}}", environmentVariableReader); Assert.Empty(framework.Dependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyNameIsEmptyString_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyNameIsEmptyString_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"\":{}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve dependency ''.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve dependency ''.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Unable to resolve dependency ''.", exception.Message); + } Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new LibraryRange( name: "b", @@ -1686,13 +1803,14 @@ public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionStr LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange.ToShortString()}\"}}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.LibraryRange); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new LibraryRange( name: "b", @@ -1700,211 +1818,257 @@ public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionRan LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange}\"}}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.LibraryRange); } [Theory] - [InlineData(LibraryDependencyTarget.None)] - [InlineData(LibraryDependencyTarget.Assembly)] - [InlineData(LibraryDependencyTarget.Reference)] - [InlineData(LibraryDependencyTarget.WinMD)] - [InlineData(LibraryDependencyTarget.All)] - [InlineData(LibraryDependencyTarget.PackageProjectExternal)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsUnsupported_Throws(LibraryDependencyTarget target) + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.None)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.Assembly)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.Reference)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.WinMD)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.All)] + [MemberData(nameof(TestEnvironmentVariableReader), LibraryDependencyTarget.PackageProjectExternal)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsUnsupported_Throws(IEnvironmentVariableReader environmentVariableReader, LibraryDependencyTarget target) { var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"version\":\"1.2.3\",\"target\":\"{target}\"}}}}}}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal($"Error reading '' at line 1 column 20 : Invalid dependency target value '{target}'.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal($"Error reading '' at line 1 column 20 : Invalid dependency target value '{target}'.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal($"Error reading '' : Invalid dependency target value '{target}'.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Project\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.False(dependency.AutoReferenced); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(bool expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(IEnvironmentVariableReader environmentVariableReader, bool expectedValue) { var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"autoReferenced\":{expectedValue.ToString().ToLower()},\"target\":\"Project\"}}}}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(expectedValue, dependency.AutoReferenced); } [Theory] - [InlineData("exclude")] - [InlineData("include")] - [InlineData("suppressParent")] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsArray_Throws(string propertyName) + [MemberData(nameof(TestEnvironmentVariableReader), "exclude")] + [MemberData(nameof(TestEnvironmentVariableReader), "include")] + [MemberData(nameof(TestEnvironmentVariableReader), "suppressParent")] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsArray_Throws(IEnvironmentVariableReader environmentVariableReader, string propertyName) { var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"{propertyName}\":[\"c\"]}}}}}}}}}}"; // The exception messages will not be the same because the innermost exception in the baseline // is a Newtonsoft.Json exception, while it's a .NET exception in the improved. - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Specified cast is not valid.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Specified cast is not valid.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Specified cast is not valid.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.All, dependency.IncludeType); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"exclude\":\"Native\",\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.All & ~LibraryIncludeFlags.Native, dependency.IncludeType); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"include\":\"ContentFiles\",\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"include\":\"ContentFiles\",\"type\":\"BecomesNupkgDependency, SharedFramework\",\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"suppressParent\":\"ContentFiles\",\"type\":\"SharedFramework\",\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.SuppressParent); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlagUtils.DefaultSuppressParent, dependency.SuppressParent); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"suppressParent\":\"Compile\",\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryIncludeFlags.Compile, dependency.SuppressParent); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionValueIsInvalid_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionValueIsInvalid_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"c\"}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Error reading '' at line 1 column 54 : 'c' is not a valid version string.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.IsType(exception.InnerException.InnerException); Assert.Null(exception.InnerException.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Error reading '' at line 1 column 54 : 'c' is not a valid version string.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Error reading '' : 'c' is not a valid version string.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal( LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Package\"}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Error reading '' at line 1 column 41 : Package dependencies must specify a version range.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.IsType(exception.InnerException.InnerException); Assert.Null(exception.InnerException.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Error reading '' at line 1 column 41 : Package dependencies must specify a version range.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Error reading '' : Package dependencies must specify a version range.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Project\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Empty(dependency.NoWarn); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns(IEnvironmentVariableReader environmentVariableReader) { NuGetLogCode[] expectedResults = { NuGetLogCode.NU1000, NuGetLogCode.NU3000 }; var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"noWarn\":[\"{expectedResults[0].ToString()}\",\"{expectedResults[1].ToString()}\"],\"version\":\"1.0.0\"}}}}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Collection( dependency.NoWarn, @@ -1912,34 +2076,36 @@ public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnValueIsVali noWarn => Assert.Equal(expectedResults[1], noWarn)); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.False(dependency.GeneratePathProperty); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(bool expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(IEnvironmentVariableReader environmentVariableReader, bool expectedResult) { var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"generatePathProperty\":{expectedResult.ToString().ToLowerInvariant()},\"version\":\"1.0.0\"}}}}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(expectedResult, dependency.GeneratePathProperty); } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal( LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, @@ -1947,89 +2113,103 @@ public void GetPackageSpec_WhenFrameworksDependenciesDependencyTypePropertyIsAbs } - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.False(dependency.VersionCentrallyManaged); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(bool expectedValue) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(IEnvironmentVariableReader environmentVariableReader, bool expectedValue) { var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"versionCentrallyManaged\":{expectedValue.ToString().ToLower()},\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(expectedValue, dependency.VersionCentrallyManaged); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesPropertyIsAbsent_ReturnsEmptyDownloadDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesPropertyIsAbsent_ReturnsEmptyDownloadDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.DownloadDependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNull_ReturnsEmptyDownloadDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNull_ReturnsEmptyDownloadDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":null}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.DownloadDependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNotArray_ReturnsEmptyDownloadDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNotArray_ReturnsEmptyDownloadDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":\"b\"}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.DownloadDependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsEmptyArray_ReturnsEmptyDownloadDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsEmptyArray_ReturnsEmptyDownloadDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[]}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.DownloadDependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsAbsent_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsAbsent_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[{\"version\":\"1.2.3\"}]}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve downloadDependency ''.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve downloadDependency ''.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Unable to resolve downloadDependency ''.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsNull_ReturnsDownloadDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsNull_ReturnsDownloadDependencies(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new DownloadDependency(name: null, new VersionRange(new NuGetVersion("1.2.3"))); var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":null,\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}]}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); DownloadDependency actualResult = framework.DownloadDependencies.Single(); @@ -2037,52 +2217,70 @@ public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsNul Assert.Equal(expectedResult.VersionRange, actualResult.VersionRange); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsAbsent_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsAbsent_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[{\"name\":\"b\"}]}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : The version cannot be null or empty", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : The version cannot be null or empty", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : The version cannot be null or empty", exception.Message); + } } [Theory] - [InlineData("null")] - [InlineData("c")] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsInvalid_Throws(string version) + [MemberData(nameof(TestEnvironmentVariableReader), "null")] + [MemberData(nameof(TestEnvironmentVariableReader), "c")] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsInvalid_Throws(IEnvironmentVariableReader environmentVariableReader, string version) { var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":\"b\",\"version\":\"{version}\"}}]}}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); int expectedColumn = json.IndexOf($"\"{version}\"") + version.Length + 2; - Assert.Equal($"Error reading '' at line 1 column 20 : Error reading '' at line 1 column {expectedColumn} : '{version}' is not a valid version string.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.IsType(exception.InnerException.InnerException); Assert.Null(exception.InnerException.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal($"Error reading '' at line 1 column 20 : Error reading '' at line 1 column {expectedColumn} : '{version}' is not a valid version string.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal($"Error reading '' : Error reading '' : '{version}' is not a valid version string.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsValid_ReturnsDownloadDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsValid_ReturnsDownloadDependencies(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("1.2.3"))); var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":\"{expectedResult.Name}\",\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}]}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Equal(expectedResult, framework.DownloadDependencies.Single()); } - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueHasDuplicates_PrefersFirstByName() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueHasDuplicates_PrefersFirstByName(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("1.2.3"))); var unexpectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("4.5.6"))); @@ -2091,251 +2289,295 @@ public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueHasDuplicates_ $"{{\"name\":\"{unexpectedResult.Name}\",\"version\":\"{unexpectedResult.VersionRange.ToShortString()}\"}}" + "]}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Equal(expectedResult, framework.DownloadDependencies.Single()); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesPropertyIsAbsent_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesPropertyIsAbsent_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Dependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsNull_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsNull_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":null}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Dependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsEmptyObject_ReturnsEmptyDependencies() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsEmptyObject_ReturnsEmptyDependencies(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Dependencies); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetPropertyIsAbsent_ReturnsTarget() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetPropertyIsAbsent_ReturnsTarget(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"target\":\"Package\"}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Error reading '' at line 1 column 48 : Package dependencies must specify a version range.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.IsType(exception.InnerException.InnerException); Assert.Null(exception.InnerException.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Error reading '' at line 1 column 48 : Package dependencies must specify a version range.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Error reading '' : Package dependencies must specify a version range.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"target\":\"Project\"}}}}}"; - LibraryDependency dependency = GetFrameworksDependency(json); + LibraryDependency dependency = GetFrameworksDependency(json, environmentVariableReader); Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPropertyIsAbsent_ReturnsEmptyFrameworkReferences() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPropertyIsAbsent_ReturnsEmptyFrameworkReferences(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.FrameworkReferences); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsNull_ReturnsEmptyFrameworkReferences() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsNull_ReturnsEmptyFrameworkReferences(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":null}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.FrameworkReferences); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsEmptyObject_ReturnsEmptyFrameworkReferences() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsEmptyObject_ReturnsEmptyFrameworkReferences(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":{}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.FrameworkReferences); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesFrameworkNameIsEmptyString_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesFrameworkNameIsEmptyString_Throws(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":{\"\":{}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve frameworkReference.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal("Error reading '' at line 1 column 20 : Unable to resolve frameworkReference.", exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal("Error reading '' : Unable to resolve frameworkReference.", exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsPropertyIsAbsent_ReturnsNonePrivateAssets() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsPropertyIsAbsent_ReturnsNonePrivateAssets(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.None); var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{}}}}}}}}}}"; - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + FrameworkDependency dependency = GetFrameworksFrameworkReference(json, environmentVariableReader); Assert.Equal(expectedResult, dependency); } [Theory] - [InlineData("\"null\"")] - [InlineData("\"\"")] - [InlineData("\"c\"")] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsInvalidValue_ReturnsNonePrivateAssets(string privateAssets) + [MemberData(nameof(TestEnvironmentVariableReader), "\"null\"")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"c\"")] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsInvalidValue_ReturnsNonePrivateAssets(IEnvironmentVariableReader environmentVariableReader, string privateAssets) { var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.None); var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":{privateAssets}}}}}}}}}}}"; - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + FrameworkDependency dependency = GetFrameworksFrameworkReference(json, environmentVariableReader); Assert.Equal(expectedResult, dependency); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidString_ReturnsPrivateAssets() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidString_ReturnsPrivateAssets(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.All); var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":\"{expectedResult.PrivateAssets.ToString().ToLowerInvariant()}\"}}}}}}}}}}"; - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + FrameworkDependency dependency = GetFrameworksFrameworkReference(json, environmentVariableReader); Assert.Equal(expectedResult, dependency); } - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidDelimitedString_ReturnsPrivateAssets() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidDelimitedString_ReturnsPrivateAssets(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.All); var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":\"none,all\"}}}}}}}}}}"; - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); + FrameworkDependency dependency = GetFrameworksFrameworkReference(json, environmentVariableReader); Assert.Equal(expectedResult, dependency); } - [Fact] - public void GetPackageSpec_WhenFrameworksImportsPropertyIsAbsent_ReturnsEmptyImports() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksImportsPropertyIsAbsent_ReturnsEmptyImports(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Imports); } [Theory] - [InlineData("null")] - [InlineData("\"\"")] - public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfNullOrEmptyString_ImportIsSkipped(string import) + [MemberData(nameof(TestEnvironmentVariableReader), "null")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"")] + public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfNullOrEmptyString_ImportIsSkipped(IEnvironmentVariableReader environmentVariableReader, string import) { var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[{import}]}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Imports); } - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueIsNull_ReturnsEmptyList() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksImportsValueIsNull_ReturnsEmptyList(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{\"imports\":null}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Imports); } [Theory] - [InlineData("true")] - [InlineData("-2")] - [InlineData("3.14")] - [InlineData("{}")] - public void GetPackageSpec_WhenFrameworksImportsValueIsInvalidValue_ReturnsEmptyList(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "true")] + [MemberData(nameof(TestEnvironmentVariableReader), "-2")] + [MemberData(nameof(TestEnvironmentVariableReader), "3.14")] + [MemberData(nameof(TestEnvironmentVariableReader), "{}")] + public void GetPackageSpec_WhenFrameworksImportsValueIsInvalidValue_ReturnsEmptyList(IEnvironmentVariableReader environmentVariableReader, string value) { var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":{value}}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Empty(framework.Imports); } - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueContainsInvalidValue_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksImportsValueContainsInvalidValue_Throws(IEnvironmentVariableReader environmentVariableReader) { const string expectedImport = "b"; var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[\"{expectedImport}\"]}}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal( - $"Error reading '' at line 1 column 20 : Imports contains an invalid framework: '{expectedImport}' in 'project.json'.", - exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(20, exception.Column); Assert.IsType(exception.InnerException); Assert.Null(exception.InnerException.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal( + $"Error reading '' at line 1 column 20 : Imports contains an invalid framework: '{expectedImport}' in 'project.json'.", + exception.Message); + Assert.Equal(1, exception.Line); + Assert.Equal(20, exception.Column); + } + else + { + Assert.Equal( + $"Error reading '' : Imports contains an invalid framework: '{expectedImport}' in 'project.json'.", + exception.Message); + } } - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueIsString_ReturnsImport() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksImportsValueIsString_ReturnsImport(IEnvironmentVariableReader environmentVariableReader) { NuGetFramework expectedResult = NuGetFramework.Parse("net48"); var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":\"{expectedResult.GetShortFolderName()}\"}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Collection( framework.Imports, actualResult => Assert.Equal(expectedResult, actualResult)); } - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfStrings_ReturnsImports() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfStrings_ReturnsImports(IEnvironmentVariableReader environmentVariableReader) { NuGetFramework[] expectedResults = { NuGetFramework.Parse("net472"), NuGetFramework.Parse("net48") }; var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[\"{expectedResults[0].GetShortFolderName()}\",\"{expectedResults[1].GetShortFolderName()}\"]}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Collection( framework.Imports, @@ -2343,68 +2585,72 @@ public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfStrings_ReturnsImp actualResult => Assert.Equal(expectedResults[1], actualResult)); } - [Fact] - public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathPropertyIsAbsent_ReturnsRuntimeIdentifierGraphPath() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathPropertyIsAbsent_ReturnsRuntimeIdentifierGraphPath(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Null(framework.RuntimeIdentifierGraphPath); } [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("b")] - public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathValueIsString_ReturnsRuntimeIdentifierGraphPath(string expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), null)] + [MemberData(nameof(TestEnvironmentVariableReader), "")] + [MemberData(nameof(TestEnvironmentVariableReader), "b")] + public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathValueIsString_ReturnsRuntimeIdentifierGraphPath(IEnvironmentVariableReader environmentVariableReader, string expectedResult) { string runtimeIdentifierGraphPath = expectedResult == null ? "null" : $"\"{expectedResult}\""; var json = $"{{\"frameworks\":{{\"a\":{{\"runtimeIdentifierGraphPath\":{runtimeIdentifierGraphPath}}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Equal(expectedResult, framework.RuntimeIdentifierGraphPath); } - [Fact] - public void GetPackageSpec_WhenFrameworksWarnPropertyIsAbsent_ReturnsWarn() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFrameworksWarnPropertyIsAbsent_ReturnsWarn(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"frameworks\":{\"a\":{}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.False(framework.Warn); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksWarnValueIsValid_ReturnsWarn(bool expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), true)] + [MemberData(nameof(TestEnvironmentVariableReader), false)] + public void GetPackageSpec_WhenFrameworksWarnValueIsValid_ReturnsWarn(IEnvironmentVariableReader environmentVariableReader, bool expectedResult) { var json = $"{{\"frameworks\":{{\"a\":{{\"warn\":{expectedResult.ToString().ToLowerInvariant()}}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); Assert.Equal(expectedResult, framework.Warn); } #pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenPackIncludePropertyIsAbsent_ReturnsEmptyPackInclude() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackIncludePropertyIsAbsent_ReturnsEmptyPackInclude(IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec("{}"); + PackageSpec packageSpec = GetPackageSpec("{}", environmentVariableReader); Assert.Empty(packageSpec.PackInclude); } - [Fact] - public void GetPackageSpec_WhenPackIncludePropertyIsValid_ReturnsPackInclude() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackIncludePropertyIsValid_ReturnsPackInclude(IEnvironmentVariableReader environmentVariableReader) { var expectedResults = new List>() { new KeyValuePair("a", "b"), new KeyValuePair("c", "d") }; var json = $"{{\"packInclude\":{{\"{expectedResults[0].Key}\":\"{expectedResults[0].Value}\",\"{expectedResults[1].Key}\":\"{expectedResults[1].Value}\"}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Collection( packageSpec.PackInclude, @@ -2413,11 +2659,11 @@ public void GetPackageSpec_WhenPackIncludePropertyIsValid_ReturnsPackInclude() } [Theory] - [InlineData("{}")] - [InlineData("{\"packOptions\":null}")] - public void GetPackageSpec_WhenPackOptionsPropertyIsAbsentOrValueIsNull_ReturnsPackOptions(string json) + [MemberData(nameof(TestEnvironmentVariableReader), "{}")] + [MemberData(nameof(TestEnvironmentVariableReader), "{\"packOptions\":null}")] + public void GetPackageSpec_WhenPackOptionsPropertyIsAbsentOrValueIsNull_ReturnsPackOptions(IEnvironmentVariableReader environmentVariableReader, string json) { - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.NotNull(packageSpec.PackOptions); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); @@ -2434,23 +2680,25 @@ public void GetPackageSpec_WhenPackOptionsPropertyIsAbsentOrValueIsNull_ReturnsP Assert.Empty(packageSpec.Tags); } - [Fact] - public void GetPackageSpec_WhenPackOptionsPropertyIsAbsent_OwnersAndTagsAreEmpty() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsPropertyIsAbsent_OwnersAndTagsAreEmpty(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"owners\":[\"a\"],\"tags\":[\"b\"]}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.Owners); Assert.Empty(packageSpec.Tags); } - [Fact] - public void GetPackageSpec_WhenPackOptionsPropertyIsEmptyObject_ReturnsPackOptions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsPropertyIsEmptyObject_ReturnsPackOptions(IEnvironmentVariableReader environmentVariableReader) { string json = "{\"packOptions\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.NotNull(packageSpec.PackOptions); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); @@ -2467,8 +2715,9 @@ public void GetPackageSpec_WhenPackOptionsPropertyIsEmptyObject_ReturnsPackOptio Assert.Empty(packageSpec.Tags); } - [Fact] - public void GetPackageSpec_WhenPackOptionsValueIsValid_ReturnsPackOptions() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsValueIsValid_ReturnsPackOptions(IEnvironmentVariableReader environmentVariableReader) { const string iconUrl = "a"; const string licenseUrl = "b"; @@ -2483,7 +2732,7 @@ public void GetPackageSpec_WhenPackOptionsValueIsValid_ReturnsPackOptions() $"\"projectUrl\":\"{projectUrl}\",\"releaseNotes\":\"{releaseNotes}\",\"requireLicenseAcceptance\":{requireLicenseAcceptance.ToString().ToLowerInvariant()}," + $"\"summary\":\"{summary}\",\"tags\":[{string.Join(",", tags.Select(tag => $"\"{tag}\""))}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.NotNull(packageSpec.PackOptions); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); @@ -2499,570 +2748,610 @@ public void GetPackageSpec_WhenPackOptionsValueIsValid_ReturnsPackOptions() Assert.Equal(tags, packageSpec.Tags); } - [Fact] - public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsNull_ReturnsEmptyPackageTypes() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsNull_ReturnsEmptyPackageTypes(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"packageType\":null}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.PackOptions.PackageType); } [Theory] - [InlineData("true", 34)] - [InlineData("-2", 32)] - [InlineData("3.14", 34)] - [InlineData("{}", 31)] - [InlineData("[true]", 31)] - [InlineData("[-2]", 31)] - [InlineData("[3.14]", 31)] - [InlineData("[null]", 31)] - [InlineData("[{}]", 31)] - [InlineData("[[]]", 31)] - public void GetPackageSpec_WhenPackOptionsPackageTypeIsInvalid_Throws(string value, int expectedColumn) + [MemberData(nameof(TestEnvironmentVariableReader), "true", 34)] + [MemberData(nameof(TestEnvironmentVariableReader), "-2", 32)] + [MemberData(nameof(TestEnvironmentVariableReader), "3.14", 34)] + [MemberData(nameof(TestEnvironmentVariableReader), "{}", 31)] + [MemberData(nameof(TestEnvironmentVariableReader), "[true]", 31)] + [MemberData(nameof(TestEnvironmentVariableReader), "[-2]", 31)] + [MemberData(nameof(TestEnvironmentVariableReader), "[3.14]", 31)] + [MemberData(nameof(TestEnvironmentVariableReader), "[null]", 31)] + [MemberData(nameof(TestEnvironmentVariableReader), "[{}]", 31)] + [MemberData(nameof(TestEnvironmentVariableReader), "[[]]", 31)] + public void GetPackageSpec_WhenPackOptionsPackageTypeIsInvalid_Throws(IEnvironmentVariableReader environmentVariableReader, string value, int expectedColumn) { var json = $"{{\"packOptions\":{{\"packageType\":{value}}}}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); - Assert.Equal("The pack options package type must be a string or array of strings in 'project.json'.", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(expectedColumn, exception.Column); Assert.Null(exception.InnerException); + Assert.Equal("The pack options package type must be a string or array of strings in 'project.json'.", exception.Message); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(1, exception.Line); + Assert.Equal(expectedColumn, exception.Column); + } } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a,b\"", "a,b")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a b\"]", "a b")] - public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsValid_ReturnsPackageTypes(string value, string expectedName) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a,b\"", "a,b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\"]", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a b\"]", "a b")] + public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsValid_ReturnsPackageTypes(IEnvironmentVariableReader environmentVariableReader, string value, string expectedName) { var expectedResult = new PackageType(expectedName, PackageType.EmptyVersion); var json = $"{{\"packOptions\":{{\"packageType\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Collection( packageSpec.PackOptions.PackageType, actualResult => Assert.Equal(expectedResult, actualResult)); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesValueIsNull_ReturnsNullInclude() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesValueIsNull_ReturnsNullInclude(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":null}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesValueIsEmptyObject_ReturnsNullInclude() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesValueIsEmptyObject_ReturnsNullInclude(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsNull_ReturnsNullIncludeExcludeFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsNull_ReturnsNullIncludeExcludeFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"include\":null}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsEmptyArray_ReturnsEmptyInclude() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsEmptyArray_ReturnsEmptyInclude(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"include\":[]}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.Include); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsValid_ReturnsInclude(string value, params string[] expectedResults) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a, b\"", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[null]", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"\"]", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\"]", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a, b\"]", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsValid_ReturnsInclude(IEnvironmentVariableReader environmentVariableReader, string value, params string[] expectedResults) { expectedResults = expectedResults ?? new string[] { null }; var json = $"{{\"packOptions\":{{\"files\":{{\"include\":{value}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.Include); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"includeFiles\":null}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsEmptyArray_ReturnsEmptyIncludeFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsEmptyArray_ReturnsEmptyIncludeFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"includeFiles\":[]}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.IncludeFiles); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsValid_ReturnsIncludeFiles(string value, params string[] expectedResults) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a, b\"", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[null]", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"\"]", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\"]", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a, b\"]", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsValid_ReturnsIncludeFiles(IEnvironmentVariableReader environmentVariableReader, string value, params string[] expectedResults) { expectedResults = expectedResults ?? new string[] { null }; var json = $"{{\"packOptions\":{{\"files\":{{\"includeFiles\":{value}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.IncludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsNull_ReturnsNullIncludeExcludeFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsNull_ReturnsNullIncludeExcludeFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"exclude\":null}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsEmptyArray_ReturnsEmptyExclude() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsEmptyArray_ReturnsEmptyExclude(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"exclude\":[]}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.Exclude); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsValid_ReturnsExclude(string value, params string[] expectedResults) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a, b\"", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[null]", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"\"]", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\"]", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a, b\"]", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsValid_ReturnsExclude(IEnvironmentVariableReader environmentVariableReader, string value, params string[] expectedResults) { expectedResults = expectedResults ?? new string[] { null }; var json = $"{{\"packOptions\":{{\"files\":{{\"exclude\":{value}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.Exclude); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"excludeFiles\":null}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsEmptyArray_ReturnsEmptyExcludeFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsEmptyArray_ReturnsEmptyExcludeFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"excludeFiles\":[]}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.ExcludeFiles); } [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsValid_ReturnsExcludeFiles(string value, params string[] expectedResults) + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a, b\"", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[null]", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"\"]", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\"]", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a, b\"]", "a, b")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"a\", \"b\"]", "a", "b")] + public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsValid_ReturnsExcludeFiles(IEnvironmentVariableReader environmentVariableReader, string value, params string[] expectedResults) { expectedResults = expectedResults ?? new string[] { null }; var json = $"{{\"packOptions\":{{\"files\":{{\"excludeFiles\":{value}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.ExcludeFiles); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsPropertyIsAbsent_ReturnsNullMappings() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesMappingsPropertyIsAbsent_ReturnsNullMappings(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.Mappings); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsNull_ReturnsNullMappings() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsNull_ReturnsNullMappings(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"packOptions\":{\"files\":{\"mappings\":null}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.PackOptions.Mappings); } [Theory] - [InlineData("\"b\"", "b")] - [InlineData("\"b,c\"", "b,c")] - [InlineData("[\"b\", \"c\"]", "b", "c")] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsValid_ReturnsMappings(string value, params string[] expectedIncludes) + [MemberData(nameof(TestEnvironmentVariableReader), "\"b\"", "b")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"b,c\"", "b,c")] + [MemberData(nameof(TestEnvironmentVariableReader), "[\"b\", \"c\"]", "b", "c")] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsValid_ReturnsMappings(IEnvironmentVariableReader environmentVariableReader, string value, params string[] expectedIncludes) { var expectedResults = new Dictionary() - { - { "a", new IncludeExcludeFiles() { Include = expectedIncludes } } - }; + { + { "a", new IncludeExcludeFiles() { Include = expectedIncludes } } + }; var json = $"{{\"packOptions\":{{\"files\":{{\"mappings\":{{\"a\":{value}}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasMultipleMappings_ReturnsMappings() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasMultipleMappings_ReturnsMappings(IEnvironmentVariableReader environmentVariableReader) { var expectedResults = new Dictionary() - { - { "a", new IncludeExcludeFiles() { Include = new[] { "b" } } }, - { "c", new IncludeExcludeFiles() { Include = new[] { "d", "e" } } } - }; + { + { "a", new IncludeExcludeFiles() { Include = new[] { "b" } } }, + { "c", new IncludeExcludeFiles() { Include = new[] { "d", "e" } } } + }; const string json = "{\"packOptions\":{\"files\":{\"mappings\":{\"a\":\"b\",\"c\":[\"d\", \"e\"]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); } - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasFiles_ReturnsMappings() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasFiles_ReturnsMappings(IEnvironmentVariableReader environmentVariableReader) { var expectedResults = new Dictionary() - { - { - "a", - new IncludeExcludeFiles() { - Include = new [] { "b" }, - IncludeFiles = new [] { "c" }, - Exclude = new [] { "d" }, - ExcludeFiles = new [] { "e" } - } - } - }; + { + "a", + new IncludeExcludeFiles() + { + Include = new [] { "b" }, + IncludeFiles = new [] { "c" }, + Exclude = new [] { "d" }, + ExcludeFiles = new [] { "e" } + } + } + }; const string json = "{\"packOptions\":{\"files\":{\"mappings\":{\"a\":{\"include\":\"b\",\"includeFiles\":\"c\",\"exclude\":\"d\",\"excludeFiles\":\"e\"}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); } #pragma warning restore CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenRestorePropertyIsAbsent_ReturnsNullRestoreMetadata() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestorePropertyIsAbsent_ReturnsNullRestoreMetadata(IEnvironmentVariableReader environmentVariableReader) { const string json = "{}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Null(packageSpec.RestoreMetadata); } - [Fact] - public void GetPackageSpec_WhenRestoreValueIsEmptyObject_ReturnsRestoreMetadata() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreValueIsEmptyObject_ReturnsRestoreMetadata(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.NotNull(packageSpec.RestoreMetadata); } [Theory] - [InlineData("null")] - [InlineData("\"\"")] - [InlineData("\"a\"")] - public void GetPackageSpec_WhenRestoreProjectStyleValueIsInvalid_ReturnsProjectStyle(string value) + [MemberData(nameof(TestEnvironmentVariableReader), "null")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"")] + public void GetPackageSpec_WhenRestoreProjectStyleValueIsInvalid_ReturnsProjectStyle(IEnvironmentVariableReader environmentVariableReader, string value) { var json = $"{{\"restore\":{{\"projectStyle\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(ProjectStyle.Unknown, packageSpec.RestoreMetadata.ProjectStyle); } - [Fact] - public void GetPackageSpec_WhenRestoreProjectStyleValueIsValid_ReturnsProjectStyle() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreProjectStyleValueIsValid_ReturnsProjectStyle(IEnvironmentVariableReader environmentVariableReader) { const ProjectStyle expectedResult = ProjectStyle.PackageReference; var json = $"{{\"restore\":{{\"projectStyle\":\"{expectedResult.ToString().ToLowerInvariant()}\"}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectStyle); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestoreProjectUniqueNameValueIsValid_ReturnsProjectUniqueName( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"projectUniqueName\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectUniqueName); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestoreOutputPathValueIsValid_ReturnsOutputPath( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"outputPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.OutputPath); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestorePackagesPathValueIsValid_ReturnsPackagesPath( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"packagesPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.PackagesPath); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestoreProjectJsonPathValueIsValid_ReturnsProjectJsonPath( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"projectJsonPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectJsonPath); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestoreProjectNameValueIsValid_ReturnsProjectName( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"projectName\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectName); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestoreProjectPathValueIsValid_ReturnsProjectPath( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"projectPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectPath); } [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] + [MemberData(nameof(TestEnvironmentVariableReader), null, false)] + [MemberData(nameof(TestEnvironmentVariableReader), true, true)] + [MemberData(nameof(TestEnvironmentVariableReader), false, false)] public void GetPackageSpec_WhenCrossTargetingValueIsValid_ReturnsCrossTargeting( + IEnvironmentVariableReader environmentVariableReader, bool? value, bool expectedValue) { var json = $"{{\"restore\":{{\"crossTargeting\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CrossTargeting); } [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] + [MemberData(nameof(TestEnvironmentVariableReader), null, false)] + [MemberData(nameof(TestEnvironmentVariableReader), true, true)] + [MemberData(nameof(TestEnvironmentVariableReader), false, false)] public void GetPackageSpec_WhenLegacyPackagesDirectoryValueIsValid_ReturnsLegacyPackagesDirectory( + IEnvironmentVariableReader environmentVariableReader, bool? value, bool expectedValue) { var json = $"{{\"restore\":{{\"legacyPackagesDirectory\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.LegacyPackagesDirectory); } [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] + [MemberData(nameof(TestEnvironmentVariableReader), null, false)] + [MemberData(nameof(TestEnvironmentVariableReader), true, true)] + [MemberData(nameof(TestEnvironmentVariableReader), false, false)] public void GetPackageSpec_WhenValidateRuntimeAssetsValueIsValid_ReturnsValidateRuntimeAssets( + IEnvironmentVariableReader environmentVariableReader, bool? value, bool expectedValue) { var json = $"{{\"restore\":{{\"validateRuntimeAssets\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ValidateRuntimeAssets); } [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] + [MemberData(nameof(TestEnvironmentVariableReader), null, false)] + [MemberData(nameof(TestEnvironmentVariableReader), true, true)] + [MemberData(nameof(TestEnvironmentVariableReader), false, false)] public void GetPackageSpec_WhenSkipContentFileWriteValueIsValid_ReturnsSkipContentFileWrite( + IEnvironmentVariableReader environmentVariableReader, bool? value, bool expectedValue) { var json = $"{{\"restore\":{{\"skipContentFileWrite\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.SkipContentFileWrite); } [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] + [MemberData(nameof(TestEnvironmentVariableReader), null, false)] + [MemberData(nameof(TestEnvironmentVariableReader), true, true)] + [MemberData(nameof(TestEnvironmentVariableReader), false, false)] public void GetPackageSpec_WhenCentralPackageVersionsManagementEnabledValueIsValid_ReturnsCentralPackageVersionsManagementEnabled( + IEnvironmentVariableReader environmentVariableReader, bool? value, bool expectedValue) { var json = $"{{\"restore\":{{\"centralPackageVersionsManagementEnabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageVersionsEnabled); } - [Fact] - public void GetPackageSpec_WhenSourcesValueIsEmptyObject_ReturnsEmptySources() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenSourcesValueIsEmptyObject_ReturnsEmptySources(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{\"sources\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.RestoreMetadata.Sources); } - [Fact] - public void GetPackageSpec_WhenSourcesValueIsValid_ReturnsSources() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenSourcesValueIsValid_ReturnsSources(IEnvironmentVariableReader environmentVariableReader) { PackageSource[] expectedResults = { new PackageSource(source: "a"), new PackageSource(source: "b") }; string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult.Name}\":{{}}")); var json = $"{{\"restore\":{{\"sources\":{{{values}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.RestoreMetadata.Sources); } - [Fact] - public void GetPackageSpec_WhenFilesValueIsEmptyObject_ReturnsEmptyFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFilesValueIsEmptyObject_ReturnsEmptyFiles(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{\"files\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.RestoreMetadata.Files); } - [Fact] - public void GetPackageSpec_WhenFilesValueIsValid_ReturnsFiles() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenFilesValueIsValid_ReturnsFiles(IEnvironmentVariableReader environmentVariableReader) { ProjectRestoreMetadataFile[] expectedResults = { - new ProjectRestoreMetadataFile(packagePath: "a", absolutePath: "b"), - new ProjectRestoreMetadataFile(packagePath: "c", absolutePath:"d") - }; + new ProjectRestoreMetadataFile(packagePath: "a", absolutePath: "b"), + new ProjectRestoreMetadataFile(packagePath: "c", absolutePath:"d") + }; string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult.PackagePath}\":\"{expectedResult.AbsolutePath}\"")); var json = $"{{\"restore\":{{\"files\":{{{values}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.RestoreMetadata.Files); } - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{\"frameworks\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.RestoreMetadata.TargetFrameworks); } - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksFrameworkNameValueIsValid_ReturnsFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreFrameworksFrameworkNameValueIsValid_ReturnsFrameworks(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Collection( packageSpec.RestoreMetadata.TargetFrameworks, actualResult => Assert.Equal(expectedResult, actualResult)); } - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithoutAssets_ReturnsFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithoutAssets_ReturnsFrameworks(IEnvironmentVariableReader environmentVariableReader) { var projectReference = new ProjectRestoreReference() { @@ -3075,15 +3364,16 @@ public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenc var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{\"projectReferences\":{{" + $"\"{projectReference.ProjectUniqueName}\":{{\"projectPath\":\"{projectReference.ProjectPath}\"}}}}}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Collection( packageSpec.RestoreMetadata.TargetFrameworks, actualResult => Assert.Equal(expectedResult, actualResult)); } - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithAssets_ReturnsFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithAssets_ReturnsFrameworks(IEnvironmentVariableReader environmentVariableReader) { var projectReference = new ProjectRestoreReference() { @@ -3101,85 +3391,93 @@ public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenc $"\"{projectReference.ProjectUniqueName}\":{{\"projectPath\":\"{projectReference.ProjectPath}\"," + $"\"includeAssets\":\"{projectReference.IncludeAssets}\",\"excludeAssets\":\"{projectReference.ExcludeAssets}\"," + $"\"privateAssets\":\"{projectReference.PrivateAssets}\"}}}}}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Collection( packageSpec.RestoreMetadata.TargetFrameworks, actualResult => Assert.Equal(expectedResult, actualResult)); } - [Fact] - public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsEmptyArray_ReturnsEmptyConfigFilePaths() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsEmptyArray_ReturnsEmptyConfigFilePaths(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{\"configFilePaths\":[]}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.RestoreMetadata.ConfigFilePaths); } - [Fact] - public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsValid_ReturnsConfigFilePaths() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsValid_ReturnsConfigFilePaths(IEnvironmentVariableReader environmentVariableReader) { string[] expectedResults = { "a", "b" }; string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); var json = $"{{\"restore\":{{\"configFilePaths\":[{values}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.RestoreMetadata.ConfigFilePaths); } - [Fact] - public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsEmptyArray_ReturnsEmptyFallbackFolders() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsEmptyArray_ReturnsEmptyFallbackFolders(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{\"fallbackFolders\":[]}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.RestoreMetadata.FallbackFolders); } - [Fact] - public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsValid_ReturnsConfigFilePaths() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsValid_ReturnsConfigFilePaths(IEnvironmentVariableReader environmentVariableReader) { string[] expectedResults = { "a", "b" }; string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); var json = $"{{\"restore\":{{\"fallbackFolders\":[{values}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.RestoreMetadata.FallbackFolders); } - [Fact] - public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsEmptyArray_ReturnsEmptyOriginalTargetFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsEmptyArray_ReturnsEmptyOriginalTargetFrameworks(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"restore\":{\"originalTargetFrameworks\":[]}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.RestoreMetadata.OriginalTargetFrameworks); } - [Fact] - public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsValid_ReturnsOriginalTargetFrameworks() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsValid_ReturnsOriginalTargetFrameworks(IEnvironmentVariableReader environmentVariableReader) { string[] expectedResults = { "a", "b" }; string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); var json = $"{{\"restore\":{{\"originalTargetFrameworks\":[{values}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResults, packageSpec.RestoreMetadata.OriginalTargetFrameworks); } - [Fact] - public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsEmptyObject_ReturnsWarningProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsEmptyObject_ReturnsWarningProperties(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new WarningProperties(); const string json = "{\"restore\":{\"warningProperties\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectWideWarningProperties); } - [Fact] - public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsValid_ReturnsWarningProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsValid_ReturnsWarningProperties(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new WarningProperties( new HashSet() { NuGetLogCode.NU3000 }, @@ -3188,23 +3486,25 @@ public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsValid_ReturnsWarni new HashSet()); var json = $"{{\"restore\":{{\"warningProperties\":{{\"allWarningsAsErrors\":{expectedResult.AllWarningsAsErrors.ToString().ToLowerInvariant()}," + $"\"warnAsError\":[\"{expectedResult.WarningsAsErrors.Single()}\"],\"noWarn\":[\"{expectedResult.NoWarn.Single()}\"]}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectWideWarningProperties); } - [Fact] - public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsEmptyObject_ReturnsRestoreLockProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsEmptyObject_ReturnsRestoreLockProperties(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new RestoreLockProperties(); const string json = "{\"restore\":{\"restoreLockProperties\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RestoreMetadata.RestoreLockProperties); } - [Fact] - public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsValid_ReturnsRestoreLockProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsValid_ReturnsRestoreLockProperties(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new RestoreLockProperties( restorePackagesWithLockFile: "a", @@ -3213,61 +3513,64 @@ public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsValid_ReturnsR var json = $"{{\"restore\":{{\"restoreLockProperties\":{{\"restoreLockedMode\":{expectedResult.RestoreLockedMode.ToString().ToLowerInvariant()}," + $"\"restorePackagesWithLockFile\":\"{expectedResult.RestorePackagesWithLockFile}\"," + $"\"nuGetLockFilePath\":\"{expectedResult.NuGetLockFilePath}\"}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RestoreMetadata.RestoreLockProperties); } [Theory] - [InlineData("null")] - [InlineData("\"\"")] - [InlineData("\"a\"")] - public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsNotPackagesConfig_DoesNotReturnPackagesConfigPath( - string value) + [MemberData(nameof(TestEnvironmentVariableReader), "null")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"")] + public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsNotPackagesConfig_DoesNotReturnPackagesConfigPath(IEnvironmentVariableReader environmentVariableReader, string value) { var json = $"{{\"restore\":{{\"projectStyle\":\"PackageReference\",\"packagesConfigPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.IsNotType(packageSpec.RestoreMetadata); } [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsPackagesConfig_ReturnsPackagesConfigPath( + IEnvironmentVariableReader environmentVariableReader, string value, string expectedValue) { var json = $"{{\"restore\":{{\"projectStyle\":\"PackagesConfig\",\"packagesConfigPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.IsType(packageSpec.RestoreMetadata); Assert.Equal(expectedValue, ((PackagesConfigProjectRestoreMetadata)packageSpec.RestoreMetadata).PackagesConfigPath); } - [Fact] - public void GetPackageSpec_WhenRestoreSettingsValueIsEmptyObject_ReturnsRestoreSettings() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRestoreSettingsValueIsEmptyObject_ReturnsRestoreSettings(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = new ProjectRestoreSettings(); const string json = "{\"restoreSettings\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RestoreSettings); } - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsEmptyObject_ReturnsRuntimes() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRuntimesValueIsEmptyObject_ReturnsRuntimes(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = RuntimeGraph.Empty; const string json = "{\"runtimes\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsValidWithImports_ReturnsRuntimes() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRuntimesValueIsValidWithImports_ReturnsRuntimes(IEnvironmentVariableReader environmentVariableReader) { var runtimeDescription = new RuntimeDescription( runtimeIdentifier: "a", @@ -3276,13 +3579,14 @@ public void GetPackageSpec_WhenRuntimesValueIsValidWithImports_ReturnsRuntimes() var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"#import\":[" + $"{string.Join(",", runtimeDescription.InheritedRuntimes.Select(runtime => $"\"{runtime}\""))}]}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySet_ReturnsRuntimes() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySet_ReturnsRuntimes(IEnvironmentVariableReader environmentVariableReader) { var dependencySet = new RuntimeDependencySet(id: "b"); var runtimeDescription = new RuntimeDescription( @@ -3291,13 +3595,14 @@ public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySet_ReturnsRunt runtimeDependencySets: new[] { dependencySet }); var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"{dependencySet.Id}\":{{}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySetWithDependency_ReturnsRuntimes() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySetWithDependency_ReturnsRuntimes(IEnvironmentVariableReader environmentVariableReader) { var dependency = new RuntimePackageDependency("c", VersionRange.Parse("[1.2.3,4.5.6)")); var dependencySet = new RuntimeDependencySet(id: "b", new[] { dependency }); @@ -3308,75 +3613,85 @@ public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySetWithDependen var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"{dependencySet.Id}\":{{" + $"\"{dependency.Id}\":\"{dependency.VersionRange.ToLegacyString()}\"}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } - [Fact] - public void GetPackageSpec_WhenSupportsValueIsEmptyObject_ReturnsSupports() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenSupportsValueIsEmptyObject_ReturnsSupports(IEnvironmentVariableReader environmentVariableReader) { var expectedResult = RuntimeGraph.Empty; const string json = "{\"supports\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } - [Fact] - public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfiles_ReturnsSupports() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfiles_ReturnsSupports(IEnvironmentVariableReader environmentVariableReader) { var profile = new CompatibilityProfile(name: "a"); var expectedResult = new RuntimeGraph(new[] { profile }); var json = $"{{\"supports\":{{\"{profile.Name}\":{{}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } - [Fact] - public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfilesAndFrameworkRuntimePairs_ReturnsSupports() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfilesAndFrameworkRuntimePairs_ReturnsSupports(IEnvironmentVariableReader environmentVariableReader) { FrameworkRuntimePair[] restoreContexts = new[] { - new FrameworkRuntimePair(NuGetFramework.Parse("net472"), "b"), - new FrameworkRuntimePair(NuGetFramework.Parse("net48"), "c") - }; + new FrameworkRuntimePair(NuGetFramework.Parse("net472"), "b"), + new FrameworkRuntimePair(NuGetFramework.Parse("net48"), "c") + }; var profile = new CompatibilityProfile(name: "a", restoreContexts); var expectedResult = new RuntimeGraph(new[] { profile }); var json = $"{{\"supports\":{{\"{profile.Name}\":{{" + $"\"{restoreContexts[0].Framework.GetShortFolderName()}\":\"{restoreContexts[0].RuntimeIdentifier}\"," + $"\"{restoreContexts[1].Framework.GetShortFolderName()}\":[\"{restoreContexts[1].RuntimeIdentifier}\"]}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.RuntimeGraph); } #pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenScriptsValueIsEmptyObject_ReturnsScripts() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenScriptsValueIsEmptyObject_ReturnsScripts(IEnvironmentVariableReader environmentVariableReader) { const string json = "{\"scripts\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Empty(packageSpec.Scripts); } - [Fact] - public void GetPackageSpec_WhenScriptsValueIsInvalid_Throws() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenScriptsValueIsInvalid_Throws(IEnvironmentVariableReader environmentVariableReader) { var json = "{\"scripts\":{\"a\":0}}"; - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); + FileFormatException exception = Assert.Throws(() => GetPackageSpec(json, environmentVariableReader)); Assert.Equal("The value of a script in 'project.json' can only be a string or an array of strings", exception.Message); - Assert.Equal(1, exception.Line); - Assert.Equal(17, exception.Column); Assert.Null(exception.InnerException); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(1, exception.Line); + Assert.Equal(17, exception.Column); + } } - [Fact] - public void GetPackageSpec_WhenScriptsValueIsValid_ReturnsScripts() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenScriptsValueIsValid_ReturnsScripts(IEnvironmentVariableReader environmentVariableReader) { const string name0 = "a"; const string name1 = "b"; @@ -3385,7 +3700,7 @@ public void GetPackageSpec_WhenScriptsValueIsValid_ReturnsScripts() const string script2 = "e"; var json = $"{{\"scripts\":{{\"{name0}\":\"{script0}\",\"{name1}\":[\"{script1}\",\"{script2}\"]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Collection( packageSpec.Scripts, @@ -3408,76 +3723,79 @@ public void GetPackageSpec_WhenScriptsValueIsValid_ReturnsScripts() #pragma warning restore CS0612 // Type or member is obsolete [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenTitleValueIsValid_ReturnsTitle(string value, string expectedResult) + [MemberData(nameof(TestEnvironmentVariableReader), "null", null)] + [MemberData(nameof(TestEnvironmentVariableReader), "\"\"", "")] + [MemberData(nameof(TestEnvironmentVariableReader), "\"a\"", "a")] + public void GetPackageSpec_WhenTitleValueIsValid_ReturnsTitle(IEnvironmentVariableReader environmentVariableReader, string value, string expectedResult) { var json = $"{{\"title\":{value}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.Title); } - [Fact] - public void GetPackageSpec_WhenNameIsNull_RestoreMetadataProvidesFallbackName() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WhenNameIsNull_RestoreMetadataProvidesFallbackName(IEnvironmentVariableReader environmentVariableReader) { const string expectedResult = "a"; var json = $"{{\"restore\":{{\"projectName\":\"{expectedResult}\"}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.Name); } [Theory] - [InlineData("{\"restore\":{\"projectJsonPath\":\"a\"}}")] - [InlineData("{\"restore\":{\"projectPath\":\"a\"}}")] - [InlineData("{\"restore\":{\"projectJsonPath\":\"a\",\"projectPath\":\"b\"}}")] - public void GetPackageSpec_WhenFilePathIsNull_RestoreMetadataProvidesFallbackFilePath(string json) + [MemberData(nameof(TestEnvironmentVariableReader), "{\"restore\":{\"projectJsonPath\":\"a\"}}")] + [MemberData(nameof(TestEnvironmentVariableReader), "{\"restore\":{\"projectPath\":\"a\"}}")] + [MemberData(nameof(TestEnvironmentVariableReader), "{\"restore\":{\"projectJsonPath\":\"a\",\"projectPath\":\"b\"}}")] + public void GetPackageSpec_WhenFilePathIsNull_RestoreMetadataProvidesFallbackFilePath(IEnvironmentVariableReader environmentVariableReader, string json) { const string expectedResult = "a"; - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); Assert.Equal(expectedResult, packageSpec.FilePath); } - [Fact] - public void GetTargetFrameworkInformation_WithAnAlias() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetTargetFrameworkInformation_WithAnAlias(IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"net46\":{ \"targetAlias\" : \"alias\"}}}"); + TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"net46\":{ \"targetAlias\" : \"alias\"}}}", environmentVariableReader); Assert.Equal("alias", framework.TargetAlias); } - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithAliases() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_ReadsRestoreMetadataWithAliases(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""targetAlias"" : ""alias"", - ""projectReferences"": {} - } - }, - ""warningProperties"": { - } - } -}"; + ""restore"": { + ""projectUniqueName"": ""projectUniqueName"", + ""projectName"": ""projectName"", + ""projectPath"": ""projectPath"", + ""projectJsonPath"": ""projectJsonPath"", + ""packagesPath"": ""packagesPath"", + ""outputPath"": ""outputPath"", + ""projectStyle"": ""PackageReference"", + ""crossTargeting"": true, + ""frameworks"": { + ""frameworkidentifier123-frameworkprofile"": { + ""targetAlias"" : ""alias"", + ""projectReferences"": {} + } + }, + ""warningProperties"": { + } + } + }"; - var actual = NjPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); // Assert var metadata = actual.RestoreMetadata; @@ -3487,49 +3805,80 @@ public void PackageSpecReader_ReadsRestoreMetadataWithAliases() Assert.Equal("alias", metadata.TargetFrameworks.Single().TargetAlias); } - [Fact] - public void PackageSpecReader_Read() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_Read(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ - ""centralTransitiveDependencyGroups"": { - "".NETCoreApp,Version=v3.1"": { - ""Foo"": { - ""exclude"": ""Native"", - ""include"": ""Build"", - ""suppressParent"": ""All"", - ""version"": ""1.0.0"" - } - }, - "".NETCoreApp,Version=v3.0"": { - ""Bar"": { - ""exclude"": ""Native"", - ""include"": ""Build"", - ""suppressParent"": ""All"", - ""version"": ""2.0.0"" + ""centralTransitiveDependencyGroups"": { + "".NETCoreApp,Version=v3.1"": { + ""Foo"": { + ""exclude"": ""Native"", + ""include"": ""Build"", + ""suppressParent"": ""All"", + ""version"": ""1.0.0"" + } + }, + "".NETCoreApp,Version=v3.0"": { + ""Bar"": { + ""exclude"": ""Native"", + ""include"": ""Build"", + ""suppressParent"": ""All"", + ""version"": ""2.0.0"" + } + } } - } - } - }"; + }"; // Act var results = new List(); - using (var stringReader = new StringReader(json.ToString())) - using (var jsonReader = new JsonTextReader(stringReader)) + if (environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING").Equals(bool.FalseString, StringComparison.OrdinalIgnoreCase)) { - jsonReader.ReadObject(ctdPropertyName => + using Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + var reader = new Utf8JsonStreamReader(stream); + + if (reader.TokenType == JsonTokenType.StartObject) { - jsonReader.ReadObject(frameworkPropertyName => + while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) { - var dependencies = new List(); - NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); - NjPackageSpecReader.ReadCentralTransitiveDependencyGroup( - jsonReader: jsonReader, - results: dependencies, - packageSpecPath: "SomePath"); - results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); + if (reader.Read() && reader.TokenType == JsonTokenType.StartObject) + { + while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) + { + var frameworkPropertyName = reader.GetString(); + NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); + var dependencies = new List(); + + Utf8JsonStreamPackageSpecReader.ReadCentralTransitiveDependencyGroup( + jsonReader: ref reader, + results: dependencies, + packageSpecPath: "SomePath"); + results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); + } + } + } + } + } + else + { + using (var stringReader = new StringReader(json.ToString())) + using (var jsonReader = new JsonTextReader(stringReader)) + { + jsonReader.ReadObject(ctdPropertyName => + { + jsonReader.ReadObject(frameworkPropertyName => + { + var dependencies = new List(); + NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); + NjPackageSpecReader.ReadCentralTransitiveDependencyGroup( + jsonReader: jsonReader, + results: dependencies, + packageSpecPath: "SomePath"); + results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); + }); }); - }); + } } // Assert @@ -3550,24 +3899,26 @@ public void PackageSpecReader_Read() Assert.True(secondGroup.TransitiveDependencies.First().VersionCentrallyManaged); } - [Fact] - public void GetPackageSpec_WithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework(IEnvironmentVariableReader environmentVariableReader) { var json = $"{{\"frameworks\":{{\"net5.0\":{{\"secondaryFramework\": \"native\"}}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); framework.FrameworkName.Should().BeOfType(); var dualCompatibilityFramework = framework.FrameworkName as DualCompatibilityFramework; dualCompatibilityFramework.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); dualCompatibilityFramework.SecondaryFramework.Should().Be(FrameworkConstants.CommonFrameworks.Native); } - [Fact] - public void GetPackageSpec_WithAssetTargetFallbackAndWithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WithAssetTargetFallbackAndWithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework(IEnvironmentVariableReader environmentVariableReader) { var json = $"{{\"frameworks\":{{\"net5.0\":{{\"assetTargetFallback\": true, \"imports\": [\"net472\", \"net471\"], \"secondaryFramework\": \"native\" }}}}}}"; - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); framework.FrameworkName.Should().BeOfType(); framework.AssetTargetFallback.Should().BeTrue(); var assetTargetFallbackFramework = framework.FrameworkName as AssetTargetFallbackFramework; @@ -3580,14 +3931,15 @@ public void GetPackageSpec_WithAssetTargetFallbackAndWithSecondaryFrameworks_Ret assetTargetFallbackFramework.Fallback.Last().Should().Be(FrameworkConstants.CommonFrameworks.Net471); } - [Fact] - public void GetPackageSpec_WithRestoreAuditProperties_ReturnsRestoreAuditProperties() + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void GetPackageSpec_WithRestoreAuditProperties_ReturnsRestoreAuditProperties(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = $"{{\"restore\":{{\"restoreAuditProperties\":{{\"enableAudit\": \"a\", \"auditLevel\": \"b\", \"auditMode\": \"c\"}}}}}}"; // Act - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); // Assert packageSpec.RestoreMetadata.RestoreAuditProperties.EnableAudit.Should().Be("a"); @@ -3595,41 +3947,93 @@ public void GetPackageSpec_WithRestoreAuditProperties_ReturnsRestoreAuditPropert packageSpec.RestoreMetadata.RestoreAuditProperties.AuditMode.Should().Be("c"); } - private static PackageSpec GetPackageSpec(string json) + private static PackageSpec GetPackageSpec(string json, IEnvironmentVariableReader environmentVariableReader) { - using (var stringReader = new StringReader(json)) - using (var stream = new JsonTextReader(stringReader)) - { - return NjPackageSpecReader.GetPackageSpec(stream, name: null, packageSpecPath: null, snapshotValue: null); - } + return GetPackageSpec(json, name: null, packageSpecPath: null, snapshotValue: null, environmentVariableReader: environmentVariableReader); } - private static LibraryDependency GetDependency(string json) + private static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, string snapshotValue, IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec(json); + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + return JsonPackageSpecReader.GetPackageSpec(stream, name, packageSpecPath, snapshotValue, environmentVariableReader); + } + + private static LibraryDependency GetDependency(string json, IEnvironmentVariableReader environmentVariableReader) + { + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); return packageSpec.Dependencies.Single(); } - private static TargetFrameworkInformation GetFramework(string json) + private static TargetFrameworkInformation GetFramework(string json, IEnvironmentVariableReader environmentVariableReader) { - PackageSpec packageSpec = GetPackageSpec(json); + PackageSpec packageSpec = GetPackageSpec(json, environmentVariableReader); return packageSpec.TargetFrameworks.Single(); } - private static LibraryDependency GetFrameworksDependency(string json) + private static LibraryDependency GetFrameworksDependency(string json, IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); return framework.Dependencies.Single(); } - private static FrameworkDependency GetFrameworksFrameworkReference(string json) + private static FrameworkDependency GetFrameworksFrameworkReference(string json, IEnvironmentVariableReader environmentVariableReader) { - TargetFrameworkInformation framework = GetFramework(json); + TargetFrameworkInformation framework = GetFramework(json, environmentVariableReader); return framework.FrameworkReferences.Single(); } + + public static IEnumerable TestEnvironmentVariableReader() + { + return GetTestEnvironmentVariableReader(); + } + + public static IEnumerable TestEnvironmentVariableReader(object value1) + { + return GetTestEnvironmentVariableReader(value1); + } + + public static IEnumerable TestEnvironmentVariableReader(object value1, object value2) + { + return GetTestEnvironmentVariableReader(value1, value2); + } + + public static IEnumerable TestEnvironmentVariableReader(object value1, object value2, object value3) + { + return GetTestEnvironmentVariableReader(value1, value2, value3); + } + + private static IEnumerable GetTestEnvironmentVariableReader(params object[] objects) + { + var UseNjForFileTrue = new List { + new TestEnvironmentVariableReader( + new Dictionary() + { + ["NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"] = bool.TrueString + }, "NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING: true") + }; + var UseNjForFileFalse = new List { + new TestEnvironmentVariableReader( + new Dictionary() + { + ["NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"] = bool.FalseString + }, "NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING: false") + }; + + if (objects != null) + { + UseNjForFileFalse.AddRange(objects); + UseNjForFileTrue.AddRange(objects); + } + + return new List + { + UseNjForFileTrue.ToArray(), + UseNjForFileFalse.ToArray() + }; + } } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs deleted file mode 100644 index 5e65c57d60e..00000000000 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamPackageSpecReaderTests.cs +++ /dev/null @@ -1,3634 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.Json; -using FluentAssertions; -using NuGet.Common; -using NuGet.Configuration; -using NuGet.Frameworks; -using NuGet.LibraryModel; -using NuGet.Packaging.Core; -using NuGet.RuntimeModel; -using NuGet.Versioning; -using Xunit; - -namespace NuGet.ProjectModel.Test -{ - [UseCulture("")] // Fix tests failing on systems with non-English locales - public class Utf8JsonStreamPackageSpecReaderTests - { - [Fact] - public void PackageSpecReader_PackageMissingVersion() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""type"": ""build"" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; - - // Act - Exception exception = null; - - try - { - var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - } - catch (Exception ex) - { - exception = ex; - } - - // Assert - Assert.Contains("specify a version range", exception.Message); - } - - [Fact] - public void PackageSpecReader_ProjectMissingVersion() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""project"" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; - - // Act - var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - var range = spec.Dependencies.Single().LibraryRange.VersionRange; - - // Assert - Assert.Equal(VersionRange.All, range); - } - - [Fact] - public void PackageSpecReader_PackageEmptyVersion() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": """" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; - - Exception exception = null; - - try - { - var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - } - catch (Exception ex) - { - exception = ex; - } - - // Assert - Assert.Contains("specify a version range", exception.Message); - } - - [Fact] - public void PackageSpecReader_PackageWhitespaceVersion() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": "" "" - } - }, - ""frameworks"": { - ""net46"": {} - } - }"; - - Exception exception = null; - - try - { - var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - } - catch (Exception ex) - { - exception = ex; - } - - // Assert - Assert.Contains("not a valid version string", exception.Message); - } - - [Fact] - public void PackageSpecReader_FrameworkAssemblyEmptyVersion() - { - // Arrange - var json = @"{ - ""frameworks"": { - ""net46"": { - ""frameworkAssemblies"": { - ""packageA"": """" - } - } - } - }"; - - // Act - var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - var range = spec.TargetFrameworks.Single().Dependencies.Single().LibraryRange.VersionRange; - - // Assert - Assert.Equal(VersionRange.All, range); - } - - [Fact] - public void PackageSpecReader_ExplicitIncludesOverrideTypePlatform() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""redist"": { - ""version"": ""1.0.0"", - ""type"": ""platform"", - ""include"": ""analyzers"" - } - } - }"; - - // Act - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("redist")); - Assert.NotNull(dep); - - var expected = LibraryIncludeFlags.Analyzers; - Assert.Equal(expected, dep.IncludeType); - } - - [Theory] - [InlineData("{}")] - [InlineData(@"{ - ""packOptions"": {} - }")] - [InlineData(@"{ - ""packOptions"": { - ""foo"": [1, 2] - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": null - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [] - } - }")] -#pragma warning disable CS0612 // Type or member is obsolete - public void PackageSpecReader_PackOptions_Default(string json) - { - // Arrange & Act - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - Assert.NotNull(actual.PackOptions); - Assert.NotNull(actual.PackOptions.PackageType); - Assert.Empty(actual.PackOptions.PackageType); - } - - [Theory] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": ""foo"" - } - }", new[] { "foo" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": ""foo, bar"" - } - }", new[] { "foo, bar" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ ""foo"" ] - } - }", new[] { "foo" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ ""foo, bar"" ] - } - }", new[] { "foo, bar" })] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ ""foo"", ""bar"" ] - } - }", new[] { "foo", "bar" })] - public void PackageSpecReader_PackOptions_ValidPackageType(string json, string[] expectedNames) - { - // Arrange - var expected = expectedNames - .Select(n => new PackageType(n, PackageType.EmptyVersion)) - .ToArray(); - - // Act - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - Assert.NotNull(actual.PackOptions); - Assert.NotNull(actual.PackOptions.PackageType); - Assert.Equal(expected, actual.PackOptions.PackageType.ToArray()); - } - - [Theory] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": 1 - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": false - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": 1.0 - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": {} - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": { - ""name"": ""foo"" - } - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ - { ""name"": ""foo"" }, - { ""name"": ""bar"" } - ] - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ - ""foo"", - null - ] - } - }")] - [InlineData(@"{ - ""packOptions"": { - ""packageType"": [ - ""foo"", - true - ] - } - }")] - public void PackageSpecReader_PackOptions_InvalidPackageType(string json) - { - // Arrange & Act & Assert - var actual = Assert.Throws( - () => Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json")); - - Assert.Contains("The pack options package type must be a string or array of strings in 'project.json'.", actual.Message); - } - - [Fact] - public void PackageSpecReader_PackOptions_Files1() - { - // Arrange & Act - var json = @"{ - ""packOptions"": { - ""files"": { - ""include"": ""file1"", - ""exclude"": ""file2"", - ""includeFiles"": ""file3"", - ""excludeFiles"": ""file4"", - ""mappings"": { - ""dest/path"": ""./src/path"" - } - } - } - }"; - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - Assert.NotNull(actual.PackOptions); - Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.Include.Count); - Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.Exclude.Count); - Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.IncludeFiles.Count); - Assert.Equal(1, actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.Count); - Assert.Equal("file1", actual.PackOptions.IncludeExcludeFiles.Include.First()); - Assert.Equal("file2", actual.PackOptions.IncludeExcludeFiles.Exclude.First()); - Assert.Equal("file3", actual.PackOptions.IncludeExcludeFiles.IncludeFiles.First()); - Assert.Equal("file4", actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.First()); - Assert.NotNull(actual.PackOptions.Mappings); - Assert.Equal(1, actual.PackOptions.Mappings.Count()); - Assert.Equal("dest/path", actual.PackOptions.Mappings.First().Key); - Assert.Equal(1, actual.PackOptions.Mappings.First().Value.Include.Count()); - Assert.Null(actual.PackOptions.Mappings.First().Value.Exclude); - Assert.Null(actual.PackOptions.Mappings.First().Value.IncludeFiles); - Assert.Null(actual.PackOptions.Mappings.First().Value.ExcludeFiles); - Assert.Equal("./src/path", actual.PackOptions.Mappings.First().Value.Include.First()); - } - - [Fact] - public void PackageSpecReader_PackOptions_Files2() - { - // Arrange & Act - var json = @"{ - ""packOptions"": { - ""files"": { - ""include"": [""file1a"", ""file1b""], - ""exclude"": [""file2a"", ""file2b""], - ""includeFiles"": [""file3a"", ""file3b""], - ""excludeFiles"": [""file4a"", ""file4b""], - ""mappings"": { - ""dest/path1"": [""./src/path1"", ""./src/path2""], - ""dest/path2"": { - ""includeFiles"": [""map1a"", ""map1b""], - }, - } - } - } - }"; - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - Assert.NotNull(actual.PackOptions); - Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.Include.Count); - Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.Exclude.Count); - Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.IncludeFiles.Count); - Assert.Equal(2, actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.Count); - Assert.Equal("file1a", actual.PackOptions.IncludeExcludeFiles.Include.First()); - Assert.Equal("file2a", actual.PackOptions.IncludeExcludeFiles.Exclude.First()); - Assert.Equal("file3a", actual.PackOptions.IncludeExcludeFiles.IncludeFiles.First()); - Assert.Equal("file4a", actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.First()); - Assert.Equal("file1b", actual.PackOptions.IncludeExcludeFiles.Include.Last()); - Assert.Equal("file2b", actual.PackOptions.IncludeExcludeFiles.Exclude.Last()); - Assert.Equal("file3b", actual.PackOptions.IncludeExcludeFiles.IncludeFiles.Last()); - Assert.Equal("file4b", actual.PackOptions.IncludeExcludeFiles.ExcludeFiles.Last()); - Assert.NotNull(actual.PackOptions.Mappings); - Assert.Equal(2, actual.PackOptions.Mappings.Count()); - Assert.Equal("dest/path1", actual.PackOptions.Mappings.First().Key); - Assert.Equal("dest/path2", actual.PackOptions.Mappings.Last().Key); - Assert.Equal(2, actual.PackOptions.Mappings.First().Value.Include.Count()); - Assert.Null(actual.PackOptions.Mappings.First().Value.Exclude); - Assert.Null(actual.PackOptions.Mappings.First().Value.IncludeFiles); - Assert.Null(actual.PackOptions.Mappings.First().Value.ExcludeFiles); - Assert.Equal("./src/path1", actual.PackOptions.Mappings.First().Value.Include.First()); - Assert.Equal("./src/path2", actual.PackOptions.Mappings.First().Value.Include.Last()); - Assert.Null(actual.PackOptions.Mappings.Last().Value.Include); - Assert.Null(actual.PackOptions.Mappings.Last().Value.Exclude); - Assert.Null(actual.PackOptions.Mappings.Last().Value.ExcludeFiles); - Assert.Equal("map1a", actual.PackOptions.Mappings.Last().Value.IncludeFiles.First()); - Assert.Equal("map1b", actual.PackOptions.Mappings.Last().Value.IncludeFiles.Last()); - } - - [Theory] - [InlineData("{}", null, true)] - [InlineData(@"{ - ""buildOptions"": {} - }", null, false)] - [InlineData(@"{ - ""buildOptions"": { - ""outputName"": ""dllName"" - } - }", "dllName", false)] - [InlineData(@"{ - ""buildOptions"": { - ""outputName"": ""dllName2"", - ""emitEntryPoint"": true - } - }", "dllName2", false)] - [InlineData(@"{ - ""buildOptions"": { - ""outputName"": null - } - }", null, false)] - public void PackageSpecReader_BuildOptions(string json, string expectedValue, bool nullBuildOptions) - { - // Arrange & Act - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - if (nullBuildOptions) - { - Assert.Null(actual.BuildOptions); - } - else - { - Assert.NotNull(actual.BuildOptions); - Assert.Equal(expectedValue, actual.BuildOptions.OutputName); - } - } -#pragma warning restore CS0612 // Type or member is obsolete - - [Fact] - public void PackageSpecReader_ReadsWithoutRestoreSettings() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"" - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - Assert.NotNull(actual); - Assert.NotNull(actual.RestoreSettings); - Assert.False(actual.RestoreSettings.HideWarningsAndErrors); - } - - [Fact] - public void PackageSpecReader_ReadsDependencyWithMultipleNoWarn() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ""NU1500"", - ""NU1107"" - ] - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); - Assert.NotNull(dep); - Assert.NotNull(dep.NoWarn); - Assert.Equal(dep.NoWarn.Count, 2); - Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); - Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1107)); - } - - [Fact] - public void PackageSpecReader_ReadsDependencyWithSingleNoWarn() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ""NU1500"" - ] - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); - Assert.NotNull(dep); - Assert.NotNull(dep.NoWarn); - Assert.Equal(dep.NoWarn.Count, 1); - Assert.True(dep.NoWarn.Contains(NuGetLogCode.NU1500)); - } - - [Fact] - public void PackageSpecReader_ReadsDependencyWithSingleEmptyNoWarn() - { - // Arrange - var json = @"{ - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ] - } - }, - ""frameworks"": { - ""net46"": {} - }, - }"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var dep = actual.Dependencies.FirstOrDefault(d => d.Name.Equals("packageA")); - Assert.NotNull(dep); - Assert.NotNull(dep.NoWarn); - Assert.Equal(dep.NoWarn.Count, 0); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningProperties() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""allWarningsAsErrors"": true, - ""noWarn"": [ - ""NU1601"", - ], - ""warnAsError"": [ - ""NU1500"", - ""NU1501"" - ], - ""warnNotAsError"": [ - ""NU1801"", - ""NU1802"" - ] - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.NotNull(warningProperties); - Assert.True(warningProperties.AllWarningsAsErrors); - Assert.Equal(1, warningProperties.NoWarn.Count); - Assert.True(warningProperties.NoWarn.Contains(NuGetLogCode.NU1601)); - Assert.Equal(2, warningProperties.WarningsAsErrors.Count); - Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1500)); - Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); - Assert.Equal(2, warningProperties.WarningsNotAsErrors.Count); - Assert.True(warningProperties.WarningsNotAsErrors.Contains(NuGetLogCode.NU1801)); - Assert.True(warningProperties.WarningsNotAsErrors.Contains(NuGetLogCode.NU1802)); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_NoWarn() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""allWarningsAsErrors"": true, - ""warnAsError"": [ - ""NU1500"", - ""NU1501"" - ] - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.NotNull(warningProperties); - Assert.True(warningProperties.AllWarningsAsErrors); - Assert.Equal(0, warningProperties.NoWarn.Count); - Assert.Equal(2, warningProperties.WarningsAsErrors.Count); - Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1500)); - Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_WarnAsError() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""allWarningsAsErrors"": true, - ""noWarn"": [ - ""NU1601"", - ] - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.NotNull(warningProperties); - Assert.True(warningProperties.AllWarningsAsErrors); - Assert.Equal(1, warningProperties.NoWarn.Count); - Assert.True(warningProperties.NoWarn.Contains(NuGetLogCode.NU1601)); - Assert.Equal(0, warningProperties.WarningsAsErrors.Count); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithWarningPropertiesAndNo_AllWarningsAsErrors() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - ""noWarn"": [ - ""NU1601"", - ], - ""warnAsError"": [ - ""NU1500"", - ""NU1501"" - ] - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.NotNull(warningProperties); - Assert.False(warningProperties.AllWarningsAsErrors); - Assert.Equal(1, warningProperties.NoWarn.Count); - Assert.True(warningProperties.NoWarn.Contains(NuGetLogCode.NU1601)); - Assert.Equal(2, warningProperties.WarningsAsErrors.Count); - Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1500)); - Assert.True(warningProperties.WarningsAsErrors.Contains(NuGetLogCode.NU1501)); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithEmptyWarningPropertiesAnd() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - }, - ""warningProperties"": { - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.NotNull(warningProperties); - Assert.False(warningProperties.AllWarningsAsErrors); - Assert.Equal(0, warningProperties.NoWarn.Count); - Assert.Equal(0, warningProperties.WarningsAsErrors.Count); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithNoWarningProperties() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""configFilePaths"": [ - ""b"", - ""a"", - ""c"" - ], - ""fallbackFolders"": [ - ""b"", - ""a"", - ""c"" - ], - ""originalTargetFrameworks"": [ - ""b"", - ""a"", - ""c"" - ], - ""sources"": { - ""source"": {} - }, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""projectReferences"": {} - } - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.NotNull(warningProperties); - } - - [Fact] - public void PackageSpecReader_RuntimeIdentifierPathNullIfEmpty() - { - // Arrange - var json = @"{ - ""frameworks"": { - ""net46"": { - ""dependencies"": { - ""packageA"": { - ""target"": ""package"", - ""version"": ""1.0.0"", - ""noWarn"": [ - ""NU1500"" - ] - } - } - } - } - }"; - - // Act - var spec = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - Assert.Null(spec.TargetFrameworks.First().RuntimeIdentifierGraphPath); - } - -#pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenAuthorsPropertyIsAbsent_ReturnsEmptyAuthors() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Empty(packageSpec.Authors); - } - - [Fact] - public void GetPackageSpec_WhenAuthorsValueIsNull_ReturnsEmptyAuthors() - { - PackageSpec packageSpec = GetPackageSpec("{\"authors\":null}"); - - Assert.Empty(packageSpec.Authors); - } - - [Fact] - public void GetPackageSpec_WhenAuthorsValueIsString_ReturnsEmptyAuthors() - { - PackageSpec packageSpec = GetPackageSpec("{\"authors\":\"b\"}"); - - Assert.Empty(packageSpec.Authors); - } - - [Theory] - [InlineData("")] - [InlineData("/**/")] - public void GetPackageSpec_WhenAuthorsValueIsEmptyArray_ReturnsEmptyAuthors(string value) - { - PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}"); - - Assert.Empty(packageSpec.Authors); - } - - [Theory] - [InlineData("{}")] - [InlineData("[]")] - public void GetPackageSpec_WhenAuthorsValueElementIsNotConvertibleToString_Throws(string value) - { - var json = $"{{\"authors\":[{value}]}}"; - - Assert.Throws(() => GetPackageSpec(json)); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("true", "True")] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - public void GetPackageSpec_WhenAuthorsValueElementIsConvertibleToString_ReturnsAuthor(string value, string expectedValue) - { - PackageSpec packageSpec = GetPackageSpec($"{{\"authors\":[{value}]}}"); - - Assert.Collection(packageSpec.Authors, author => Assert.Equal(expectedValue, author)); - } - - [Fact] - public void GetPackageSpec_WhenBuildOptionsPropertyIsAbsent_ReturnsNullBuildOptions() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Null(packageSpec.BuildOptions); - } - - [Fact] - public void GetPackageSpec_WhenBuildOptionsValueIsEmptyObject_ReturnsBuildOptions() - { - PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{}}"); - - Assert.NotNull(packageSpec.BuildOptions); - Assert.Null(packageSpec.BuildOptions.OutputName); - } - - [Fact] - public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsNull_ReturnsNullOutputName() - { - PackageSpec packageSpec = GetPackageSpec("{\"buildOptions\":{\"outputName\":null}}"); - - Assert.Null(packageSpec.BuildOptions.OutputName); - } - - [Fact] - public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsValid_ReturnsOutputName() - { - const string expectedResult = "a"; - - var json = $"{{\"buildOptions\":{{\"outputName\":\"{expectedResult}\"}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.BuildOptions.OutputName); - } - - [Theory] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - [InlineData("true", "True")] - public void GetPackageSpec_WhenBuildOptionsValueOutputNameIsConvertibleToString_ReturnsOutputName(string outputName, string expectedValue) - { - PackageSpec packageSpec = GetPackageSpec($"{{\"buildOptions\":{{\"outputName\":{outputName}}}}}"); - - Assert.Equal(expectedValue, packageSpec.BuildOptions.OutputName); - } - - [Fact] - public void GetPackageSpec_WhenContentFilesPropertyIsAbsent_ReturnsEmptyContentFiles() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Empty(packageSpec.ContentFiles); - } - - [Fact] - public void GetPackageSpec_WhenContentFilesValueIsNull_ReturnsEmptyContentFiles() - { - PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":null}"); - - Assert.Empty(packageSpec.ContentFiles); - } - - [Fact] - public void GetPackageSpec_WhenContentFilesValueIsString_ReturnsEmptyContentFiles() - { - PackageSpec packageSpec = GetPackageSpec("{\"contentFiles\":\"a\"}"); - - Assert.Empty(packageSpec.ContentFiles); - } - - [Theory] - [InlineData("")] - [InlineData("/**/")] - public void GetPackageSpec_WhenContentFilesValueIsEmptyArray_ReturnsEmptyContentFiles(string value) - { - PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}"); - - Assert.Empty(packageSpec.ContentFiles); - } - - [Theory] - [InlineData("{}")] - [InlineData("[]")] - public void GetPackageSpec_WhenContentFilesValueElementIsNotConvertibleToString_Throws(string value) - { - var json = $"{{\"contentFiles\":[{value}]}}"; - - Assert.Throws(() => GetPackageSpec(json)); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("true", "True")] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - public void GetPackageSpec_WhenContentFilesValueElementIsConvertibleToString_ReturnsContentFile(string value, string expectedValue) - { - PackageSpec packageSpec = GetPackageSpec($"{{\"contentFiles\":[{value}]}}"); - - Assert.Collection(packageSpec.ContentFiles, contentFile => Assert.Equal(expectedValue, contentFile)); - } - - [Fact] - public void GetPackageSpec_WhenCopyrightPropertyIsAbsent_ReturnsNullCopyright() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Null(packageSpec.Copyright); - } - - [Fact] - public void GetPackageSpec_WhenCopyrightValueIsNull_ReturnsNullCopyright() - { - PackageSpec packageSpec = GetPackageSpec("{\"copyright\":null}"); - - Assert.Null(packageSpec.Copyright); - } - - [Fact] - public void GetPackageSpec_WhenCopyrightValueIsString_ReturnsCopyright() - { - const string expectedResult = "a"; - - PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":\"{expectedResult}\"}}"); - - Assert.Equal(expectedResult, packageSpec.Copyright); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("true", "True")] - [InlineData("-2", "-2")] - [InlineData("3.14", "3.14")] - public void GetPackageSpec_WhenCopyrightValueIsConvertibleToString_ReturnsCopyright(string value, string expectedValue) - { - PackageSpec packageSpec = GetPackageSpec($"{{\"copyright\":{value}}}"); - - Assert.Equal(expectedValue, packageSpec.Copyright); - } -#pragma warning restore CS0612 // Type or member is obsolete - - [Fact] - public void GetPackageSpec_WhenDependenciesPropertyIsAbsent_ReturnsEmptyDependencies() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Empty(packageSpec.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesValueIsNull_ReturnsEmptyDependencies() - { - PackageSpec packageSpec = GetPackageSpec("{\"dependencies\":null}"); - - Assert.Empty(packageSpec.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyNameIsEmptyString_Throws() - { - const string json = "{\"dependencies\":{\"\":{}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - Assert.Equal("Error reading '' : Unable to resolve dependency ''.", exception.Message); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange() - { - var expectedResult = new LibraryRange( - name: "a", - new VersionRange(new NuGetVersion("1.2.3")), - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); - var json = $"{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange.ToShortString()}\"}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedResult, dependency.LibraryRange); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange() - { - var expectedResult = new LibraryRange( - name: "a", - new VersionRange(new NuGetVersion("1.2.3"), includeMinVersion: true, new NuGetVersion("4.5.6"), includeMaxVersion: false), - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); - var json = $"{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange}\"}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedResult, dependency.LibraryRange); - } - - [Theory] - [InlineData(LibraryDependencyTarget.None)] - [InlineData(LibraryDependencyTarget.Assembly)] - [InlineData(LibraryDependencyTarget.Reference)] - [InlineData(LibraryDependencyTarget.WinMD)] - [InlineData(LibraryDependencyTarget.All)] - [InlineData(LibraryDependencyTarget.PackageProjectExternal)] - public void GetPackageSpec_WhenDependenciesDependencyTargetIsUnsupported_Throws(LibraryDependencyTarget target) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"version\":\"1.2.3\",\"target\":\"{target}\"}}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal($"Error reading '' : Invalid dependency target value '{target}'.", exception.Message); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced() - { - LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Project\"}}}}}}"); - - Assert.False(dependency.AutoReferenced); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(bool expectedValue) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"autoReferenced\":{expectedValue.ToString().ToLower()},\"target\":\"Project\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedValue, dependency.AutoReferenced); - } - - [Theory] - [InlineData("exclude")] - [InlineData("include")] - [InlineData("suppressParent")] - public void GetPackageSpec_WhenDependenciesDependencyValueIsArray_Throws(string propertyName) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"{propertyName}\":[\"b\"]}}}}}}"; - - var exception = Assert.Throws(() => GetPackageSpec(json)); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(LibraryIncludeFlags.All, dependency.IncludeType); - } - - [Theory] - [InlineData("\"Native\"", LibraryIncludeFlags.Native)] - [InlineData("\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] - public void GetPackageSpec_WhenDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType( - string value, - LibraryIncludeFlags result) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"exclude\":{value},\"version\":\"1.0.0\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(LibraryIncludeFlags.All & ~result, dependency.IncludeType); - } - - [Theory] - [InlineData("\"Native\"", LibraryIncludeFlags.Native)] - [InlineData("\"Analyzers, Native\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Native)] - public void GetPackageSpec_WhenDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType( - string value, - LibraryIncludeFlags expectedResult) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"include\":{value},\"version\":\"1.0.0\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedResult, dependency.IncludeType); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType() - { - const string json = "{\"dependencies\":{\"a\":{\"include\":\"ContentFiles\",\"type\":\"BecomesNupkgDependency, SharedFramework\",\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent() - { - const string json = "{\"dependencies\":{\"a\":{\"suppressParent\":\"ContentFiles\",\"type\":\"SharedFramework\",\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.SuppressParent); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(LibraryIncludeFlagUtils.DefaultSuppressParent, dependency.SuppressParent); - } - - [Theory] - [InlineData("\"Compile\"", LibraryIncludeFlags.Compile)] - [InlineData("\"Analyzers, Compile\"", LibraryIncludeFlags.Analyzers | LibraryIncludeFlags.Compile)] - public void GetPackageSpec_WhenDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent( - string value, - LibraryIncludeFlags expectedResult) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"suppressParent\":{value},\"version\":\"1.0.0\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedResult, dependency.SuppressParent); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyVersionValueIsInvalid_Throws() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"b\"}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : 'b' is not a valid version string.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() - { - const string json = "{\"dependencies\":{\"a\":{\"target\":\"Package\"}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() - { - LibraryDependency dependency = GetDependency("{\"dependencies\":{\"a\":{\"target\":\"Project\"}}}"); - - Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Empty(dependency.NoWarn); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns() - { - NuGetLogCode[] expectedResults = { NuGetLogCode.NU1000, NuGetLogCode.NU3000 }; - var json = $"{{\"dependencies\":{{\"a\":{{\"noWarn\":[\"{expectedResults[0].ToString()}\",\"{expectedResults[1].ToString()}\"],\"version\":\"1.0.0\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Collection( - dependency.NoWarn, - noWarn => Assert.Equal(expectedResults[0], noWarn), - noWarn => Assert.Equal(expectedResults[1], noWarn)); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.False(dependency.GeneratePathProperty); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(bool expectedResult) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"generatePathProperty\":{expectedResult.ToString().ToLowerInvariant()},\"version\":\"1.0.0\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedResult, dependency.GeneratePathProperty); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint() - { - const string json = "{\"dependencies\":{\"a\":{\"version\":\"1.0.0\"}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal( - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, - dependency.LibraryRange.TypeConstraint); - } - - [Fact] - public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged() - { - LibraryDependency dependency = GetDependency($"{{\"dependencies\":{{\"a\":{{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}"); - - Assert.False(dependency.VersionCentrallyManaged); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(bool expectedValue) - { - var json = $"{{\"dependencies\":{{\"a\":{{\"versionCentrallyManaged\":{expectedValue.ToString().ToLower()},\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}"; - - LibraryDependency dependency = GetDependency(json); - - Assert.Equal(expectedValue, dependency.VersionCentrallyManaged); - } - -#pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenDescriptionPropertyIsAbsent_ReturnsNullDescription() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Null(packageSpec.Description); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("b")] - public void GetPackageSpec_WhenDescriptionValueIsValid_ReturnsDescription(string expectedResult) - { - string description = expectedResult == null ? "null" : $"\"{expectedResult}\""; - PackageSpec packageSpec = GetPackageSpec($"{{\"description\":{description}}}"); - - Assert.Equal(expectedResult, packageSpec.Description); - } - - [Fact] - public void GetPackageSpec_WhenLanguagePropertyIsAbsent_ReturnsNullLanguage() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Null(packageSpec.Language); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("b")] - public void GetPackageSpec_WhenLanguageValueIsValid_ReturnsLanguage(string expectedResult) - { - string language = expectedResult == null ? "null" : $"\"{expectedResult}\""; - PackageSpec packageSpec = GetPackageSpec($"{{\"language\":{language}}}"); - - Assert.Equal(expectedResult, packageSpec.Language); - } -#pragma warning restore CS0612 // Type or member is obsolete - - [Fact] - public void GetPackageSpec_WhenFrameworksPropertyIsAbsent_ReturnsEmptyFrameworks() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Empty(packageSpec.TargetFrameworks); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks() - { - PackageSpec packageSpec = GetPackageSpec("{\"frameworks\":{}}"); - - Assert.Empty(packageSpec.TargetFrameworks); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksAssetTargetFallbackPropertyIsAbsent_ReturnsFalseAssetTargetFallback() - { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); - - Assert.False(framework.AssetTargetFallback); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksAssetTargetFallbackValueIsValid_ReturnsAssetTargetFallback(bool expectedValue) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"assetTargetFallback\":{expectedValue.ToString().ToLowerInvariant()}}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Equal(expectedValue, framework.AssetTargetFallback); - } - - [Fact] - public void GetPackageSpec_WithAssetTargetFallbackAndImportsValues_ReturnsValidAssetTargetFallbackFramework() - { - var json = $"{{\"frameworks\":{{\"net5.0\":{{\"assetTargetFallback\": true, \"imports\": [\"net472\", \"net471\"]}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - framework.AssetTargetFallback.Should().BeTrue(); - var assetTargetFallback = framework.FrameworkName as AssetTargetFallbackFramework; - assetTargetFallback.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); - assetTargetFallback.Fallback.Should().HaveCount(2); - assetTargetFallback.Fallback.First().Should().Be(FrameworkConstants.CommonFrameworks.Net472); - assetTargetFallback.Fallback.Last().Should().Be(FrameworkConstants.CommonFrameworks.Net471); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsPropertyIsAbsent_ReturnsEmptyCentralPackageVersions() - { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); - - Assert.Empty(framework.CentralPackageVersions); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsValueIsEmptyObject_ReturnsEmptyCentralPackageVersions() - { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"centralPackageVersions\":{}}}}"); - - Assert.Empty(framework.CentralPackageVersions); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyNameIsEmptyString_Throws() - { - var json = "{\"frameworks\":{\"a\":{\"centralPackageVersions\":{\"\":\"1.0.0\"}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Unable to resolve central version ''.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Theory] - [InlineData("null")] - [InlineData("\"\"")] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsVersionPropertyValueIsNullOrEmptyString_Throws(string value) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"b\":{value}}}}}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal($"Error reading '' : The version cannot be null or empty.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsIsValid_ReturnsCentralPackageVersions() - { - const string expectedPackageId = "b"; - VersionRange expectedVersionRange = VersionRange.Parse("[1.2.3,4.5.6)"); - var expectedCentralPackageVersion = new CentralPackageVersion(expectedPackageId, expectedVersionRange); - var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"{expectedPackageId}\":\"{expectedVersionRange.ToShortString()}\"}}}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Collection( - framework.CentralPackageVersions, - actualResult => - { - Assert.Equal(expectedPackageId, actualResult.Key); - Assert.Equal(expectedCentralPackageVersion, actualResult.Value); - }); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksCentralPackageVersionsHasDuplicateKey_LastOneWins() - { - const string expectedPackageId = "b"; - VersionRange unexpectedVersionRange = VersionRange.Parse("1.2.3"); - VersionRange expectedVersionRange = VersionRange.Parse("4.5.6"); - var expectedCentralPackageVersion = new CentralPackageVersion(expectedPackageId, expectedVersionRange); - var json = $"{{\"frameworks\":{{\"a\":{{\"centralPackageVersions\":{{\"{expectedPackageId}\":\"{unexpectedVersionRange.ToShortString()}\"," + - $"\"{expectedPackageId}\":\"{expectedVersionRange.ToShortString()}\"}}}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Collection( - framework.CentralPackageVersions, - actualResult => - { - Assert.Equal(expectedPackageId, actualResult.Key); - Assert.Equal(expectedCentralPackageVersion, actualResult.Value); - }); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesPropertyIsAbsent_ReturnsEmptyDependencies() - { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{}}}"); - - Assert.Empty(framework.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesValueIsNull_ReturnsEmptyDependencies() - { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"a\":{\"dependencies\":null}}}"); - - Assert.Empty(framework.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyNameIsEmptyString_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"\":{}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Unable to resolve dependency ''.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionString_ReturnsDependencyVersionRange() - { - var expectedResult = new LibraryRange( - name: "b", - new VersionRange(new NuGetVersion("1.2.3")), - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange.ToShortString()}\"}}}}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(expectedResult, dependency.LibraryRange); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsVersionRangeString_ReturnsDependencyVersionRange() - { - var expectedResult = new LibraryRange( - name: "b", - new VersionRange(new NuGetVersion("1.2.3"), includeMinVersion: true, new NuGetVersion("4.5.6"), includeMaxVersion: false), - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference); - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"{expectedResult.Name}\":\"{expectedResult.VersionRange}\"}}}}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(expectedResult, dependency.LibraryRange); - } - - [Theory] - [InlineData(LibraryDependencyTarget.None)] - [InlineData(LibraryDependencyTarget.Assembly)] - [InlineData(LibraryDependencyTarget.Reference)] - [InlineData(LibraryDependencyTarget.WinMD)] - [InlineData(LibraryDependencyTarget.All)] - [InlineData(LibraryDependencyTarget.PackageProjectExternal)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsUnsupported_Throws(LibraryDependencyTarget target) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"version\":\"1.2.3\",\"target\":\"{target}\"}}}}}}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal($"Error reading '' : Invalid dependency target value '{target}'.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedPropertyIsAbsent_ReturnsFalseAutoreferenced() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Project\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.False(dependency.AutoReferenced); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyAutoreferencedValueIsBool_ReturnsBoolAutoreferenced(bool expectedValue) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"autoReferenced\":{expectedValue.ToString().ToLower()},\"target\":\"Project\"}}}}}}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(expectedValue, dependency.AutoReferenced); - } - - [Theory] - [InlineData("exclude")] - [InlineData("include")] - [InlineData("suppressParent")] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyValueIsArray_Throws(string propertyName) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"{propertyName}\":[\"c\"]}}}}}}}}}}"; - - // The exception messages will not be the same because the innermost exception in the baseline - // is a Newtonsoft.Json exception, while it's a .NET exception in the improved. - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal($"Error reading '' : Specified cast is not valid.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeAndExcludePropertiesAreAbsent_ReturnsAllIncludeType() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlags.All, dependency.IncludeType); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyExcludeValueIsValid_ReturnsIncludeType() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"exclude\":\"Native\",\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlags.All & ~LibraryIncludeFlags.Native, dependency.IncludeType); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueIsValid_ReturnsIncludeType() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"include\":\"ContentFiles\",\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyIncludeValueOverridesTypeValue_ReturnsIncludeType() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"include\":\"ContentFiles\",\"type\":\"BecomesNupkgDependency, SharedFramework\",\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.IncludeType); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueOverridesTypeValue_ReturnsSuppressParent() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"suppressParent\":\"ContentFiles\",\"type\":\"SharedFramework\",\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlags.ContentFiles, dependency.SuppressParent); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentPropertyIsAbsent_ReturnsSuppressParent() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlagUtils.DefaultSuppressParent, dependency.SuppressParent); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencySuppressParentValueIsValid_ReturnsSuppressParent() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"suppressParent\":\"Compile\",\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryIncludeFlags.Compile, dependency.SuppressParent); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionValueIsInvalid_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"c\"}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : 'c' is not a valid version string.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetPropertyIsAbsent_ReturnsTarget() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal( - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, - dependency.LibraryRange.TypeConstraint); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Package\"}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Project\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnPropertyIsAbsent_ReturnsEmptyNoWarns() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Empty(dependency.NoWarn); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyNoWarnValueIsValid_ReturnsNoWarns() - { - NuGetLogCode[] expectedResults = { NuGetLogCode.NU1000, NuGetLogCode.NU3000 }; - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"noWarn\":[\"{expectedResults[0].ToString()}\",\"{expectedResults[1].ToString()}\"],\"version\":\"1.0.0\"}}}}}}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Collection( - dependency.NoWarn, - noWarn => Assert.Equal(expectedResults[0], noWarn), - noWarn => Assert.Equal(expectedResults[1], noWarn)); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyPropertyIsAbsent_ReturnsFalseGeneratePathProperty() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.False(dependency.GeneratePathProperty); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyGeneratePathPropertyValueIsValid_ReturnsGeneratePathProperty(bool expectedResult) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"generatePathProperty\":{expectedResult.ToString().ToLowerInvariant()},\"version\":\"1.0.0\"}}}}}}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(expectedResult, dependency.GeneratePathProperty); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyTypePropertyIsAbsent_ReturnsDefaultTypeConstraint() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal( - LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference, - dependency.LibraryRange.TypeConstraint); - } - - - [Fact] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedPropertyIsAbsent_ReturnsFalseVersionCentrallyManaged() - { - const string json = "{\"frameworks\":{\"a\":{\"dependencies\":{\"b\":{\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.False(dependency.VersionCentrallyManaged); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksDependenciesDependencyVersionCentrallyManagedValueIsBool_ReturnsBoolVersionCentrallyManaged(bool expectedValue) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"dependencies\":{{\"b\":{{\"versionCentrallyManaged\":{expectedValue.ToString().ToLower()},\"target\":\"Package\",\"version\":\"1.0.0\"}}}}}}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(expectedValue, dependency.VersionCentrallyManaged); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesPropertyIsAbsent_ReturnsEmptyDownloadDependencies() - { - const string json = "{\"frameworks\":{\"a\":{}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.DownloadDependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNull_ReturnsEmptyDownloadDependencies() - { - const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":null}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.DownloadDependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsNotArray_ReturnsEmptyDownloadDependencies() - { - const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":\"b\"}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.DownloadDependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsEmptyArray_ReturnsEmptyDownloadDependencies() - { - const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[]}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.DownloadDependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsAbsent_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[{\"version\":\"1.2.3\"}]}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Unable to resolve downloadDependency ''.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyNameIsNull_ReturnsDownloadDependencies() - { - var expectedResult = new DownloadDependency(name: null, new VersionRange(new NuGetVersion("1.2.3"))); - var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":null,\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}]}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - DownloadDependency actualResult = framework.DownloadDependencies.Single(); - - Assert.Equal(expectedResult.Name, actualResult.Name); - Assert.Equal(expectedResult.VersionRange, actualResult.VersionRange); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsAbsent_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[{\"name\":\"b\"}]}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : The version cannot be null or empty", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Theory] - [InlineData("null")] - [InlineData("c")] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesDependencyVersionIsInvalid_Throws(string version) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":\"b\",\"version\":\"{version}\"}}]}}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal($"Error reading '' : '{version}' is not a valid version string.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueIsValid_ReturnsDownloadDependencies() - { - var expectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("1.2.3"))); - var json = $"{{\"frameworks\":{{\"a\":{{\"downloadDependencies\":[{{\"name\":\"{expectedResult.Name}\",\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}]}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Equal(expectedResult, framework.DownloadDependencies.Single()); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksDownloadDependenciesValueHasDuplicates_PrefersFirstByName() - { - var expectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("1.2.3"))); - var unexpectedResult = new DownloadDependency(name: "b", new VersionRange(new NuGetVersion("4.5.6"))); - var json = "{\"frameworks\":{\"a\":{\"downloadDependencies\":[" + - $"{{\"name\":\"{expectedResult.Name}\",\"version\":\"{expectedResult.VersionRange.ToShortString()}\"}}," + - $"{{\"name\":\"{unexpectedResult.Name}\",\"version\":\"{unexpectedResult.VersionRange.ToShortString()}\"}}" + - "]}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Equal(expectedResult, framework.DownloadDependencies.Single()); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesPropertyIsAbsent_ReturnsEmptyDependencies() - { - const string json = "{\"frameworks\":{\"a\":{}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsNull_ReturnsEmptyDependencies() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":null}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesValueIsEmptyObject_ReturnsEmptyDependencies() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Dependencies); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetPropertyIsAbsent_ReturnsTarget() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"version\":\"1.0.0\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(LibraryDependencyTarget.Reference, dependency.LibraryRange.TypeConstraint); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsPackageAndVersionPropertyIsAbsent_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"target\":\"Package\"}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Package dependencies must specify a version range.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.IsType(exception.InnerException.InnerException); - Assert.Null(exception.InnerException.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkAssembliesDependencyTargetValueIsProjectAndVersionPropertyIsAbsent_ReturnsAllVersionRange() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkAssemblies\":{\"b\":{\"target\":\"Project\"}}}}}"; - - LibraryDependency dependency = GetFrameworksDependency(json); - - Assert.Equal(VersionRange.All, dependency.LibraryRange.VersionRange); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPropertyIsAbsent_ReturnsEmptyFrameworkReferences() - { - const string json = "{\"frameworks\":{\"a\":{}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.FrameworkReferences); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsNull_ReturnsEmptyFrameworkReferences() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":null}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.FrameworkReferences); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesValueIsEmptyObject_ReturnsEmptyFrameworkReferences() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":{}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.FrameworkReferences); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesFrameworkNameIsEmptyString_Throws() - { - const string json = "{\"frameworks\":{\"a\":{\"frameworkReferences\":{\"\":{}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : Unable to resolve frameworkReference.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsPropertyIsAbsent_ReturnsNonePrivateAssets() - { - var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.None); - var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{}}}}}}}}}}"; - - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); - - Assert.Equal(expectedResult, dependency); - } - - [Theory] - [InlineData("\"null\"")] - [InlineData("\"\"")] - [InlineData("\"c\"")] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsInvalidValue_ReturnsNonePrivateAssets(string privateAssets) - { - var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.None); - var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":{privateAssets}}}}}}}}}}}"; - - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); - - Assert.Equal(expectedResult, dependency); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidString_ReturnsPrivateAssets() - { - var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.All); - var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":\"{expectedResult.PrivateAssets.ToString().ToLowerInvariant()}\"}}}}}}}}}}"; - - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); - - Assert.Equal(expectedResult, dependency); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksFrameworkReferencesPrivateAssetsValueIsValidDelimitedString_ReturnsPrivateAssets() - { - var expectedResult = new FrameworkDependency(name: "b", FrameworkDependencyFlags.All); - var json = $"{{\"frameworks\":{{\"a\":{{\"frameworkReferences\":{{\"{expectedResult.Name}\":{{\"privateAssets\":\"none,all\"}}}}}}}}}}"; - - FrameworkDependency dependency = GetFrameworksFrameworkReference(json); - - Assert.Equal(expectedResult, dependency); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksImportsPropertyIsAbsent_ReturnsEmptyImports() - { - const string json = "{\"frameworks\":{\"a\":{}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Imports); - } - - [Theory] - [InlineData("null")] - [InlineData("\"\"")] - public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfNullOrEmptyString_ImportIsSkipped(string import) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[{import}]}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Imports); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueIsNull_ReturnsEmptyList() - { - const string json = "{\"frameworks\":{\"a\":{\"imports\":null}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Imports); - } - - [Theory] - [InlineData("true")] - [InlineData("-2")] - [InlineData("3.14")] - [InlineData("{}")] - public void GetPackageSpec_WhenFrameworksImportsValueIsInvalidValue_ReturnsEmptyList(string value) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":{value}}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Empty(framework.Imports); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueContainsInvalidValue_Throws() - { - const string expectedImport = "b"; - - var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[\"{expectedImport}\"]}}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal( - $"Error reading '' : Imports contains an invalid framework: '{expectedImport}' in 'project.json'.", - exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueIsString_ReturnsImport() - { - NuGetFramework expectedResult = NuGetFramework.Parse("net48"); - var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":\"{expectedResult.GetShortFolderName()}\"}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Collection( - framework.Imports, - actualResult => Assert.Equal(expectedResult, actualResult)); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksImportsValueIsArrayOfStrings_ReturnsImports() - { - NuGetFramework[] expectedResults = { NuGetFramework.Parse("net472"), NuGetFramework.Parse("net48") }; - var json = $"{{\"frameworks\":{{\"a\":{{\"imports\":[\"{expectedResults[0].GetShortFolderName()}\",\"{expectedResults[1].GetShortFolderName()}\"]}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Collection( - framework.Imports, - actualResult => Assert.Equal(expectedResults[0], actualResult), - actualResult => Assert.Equal(expectedResults[1], actualResult)); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathPropertyIsAbsent_ReturnsRuntimeIdentifierGraphPath() - { - const string json = "{\"frameworks\":{\"a\":{}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Null(framework.RuntimeIdentifierGraphPath); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("b")] - public void GetPackageSpec_WhenFrameworksRuntimeIdentifierGraphPathValueIsString_ReturnsRuntimeIdentifierGraphPath(string expectedResult) - { - string runtimeIdentifierGraphPath = expectedResult == null ? "null" : $"\"{expectedResult}\""; - var json = $"{{\"frameworks\":{{\"a\":{{\"runtimeIdentifierGraphPath\":{runtimeIdentifierGraphPath}}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Equal(expectedResult, framework.RuntimeIdentifierGraphPath); - } - - [Fact] - public void GetPackageSpec_WhenFrameworksWarnPropertyIsAbsent_ReturnsWarn() - { - const string json = "{\"frameworks\":{\"a\":{}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.False(framework.Warn); - } - - [Theory] - [InlineData(true)] - [InlineData(false)] - public void GetPackageSpec_WhenFrameworksWarnValueIsValid_ReturnsWarn(bool expectedResult) - { - var json = $"{{\"frameworks\":{{\"a\":{{\"warn\":{expectedResult.ToString().ToLowerInvariant()}}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - - Assert.Equal(expectedResult, framework.Warn); - } - -#pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenPackIncludePropertyIsAbsent_ReturnsEmptyPackInclude() - { - PackageSpec packageSpec = GetPackageSpec("{}"); - - Assert.Empty(packageSpec.PackInclude); - } - - [Fact] - public void GetPackageSpec_WhenPackIncludePropertyIsValid_ReturnsPackInclude() - { - var expectedResults = new List>() { new KeyValuePair("a", "b"), new KeyValuePair("c", "d") }; - var json = $"{{\"packInclude\":{{\"{expectedResults[0].Key}\":\"{expectedResults[0].Value}\",\"{expectedResults[1].Key}\":\"{expectedResults[1].Value}\"}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Collection( - packageSpec.PackInclude, - actualResult => Assert.Equal(expectedResults[0], actualResult), - actualResult => Assert.Equal(expectedResults[1], actualResult)); - } - - [Theory] - [InlineData("{}")] - [InlineData("{\"packOptions\":null}")] - public void GetPackageSpec_WhenPackOptionsPropertyIsAbsentOrValueIsNull_ReturnsPackOptions(string json) - { - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.NotNull(packageSpec.PackOptions); - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - Assert.Empty(packageSpec.PackOptions.Mappings); - Assert.Empty(packageSpec.PackOptions.PackageType); - - Assert.Null(packageSpec.IconUrl); - Assert.Null(packageSpec.LicenseUrl); - Assert.Empty(packageSpec.Owners); - Assert.Null(packageSpec.ProjectUrl); - Assert.Null(packageSpec.ReleaseNotes); - Assert.False(packageSpec.RequireLicenseAcceptance); - Assert.Null(packageSpec.Summary); - Assert.Empty(packageSpec.Tags); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsPropertyIsAbsent_OwnersAndTagsAreEmpty() - { - const string json = "{\"owners\":[\"a\"],\"tags\":[\"b\"]}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.Owners); - Assert.Empty(packageSpec.Tags); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsPropertyIsEmptyObject_ReturnsPackOptions() - { - string json = "{\"packOptions\":{}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.NotNull(packageSpec.PackOptions); - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - Assert.Null(packageSpec.PackOptions.Mappings); - Assert.Empty(packageSpec.PackOptions.PackageType); - - Assert.Null(packageSpec.IconUrl); - Assert.Null(packageSpec.LicenseUrl); - Assert.Empty(packageSpec.Owners); - Assert.Null(packageSpec.ProjectUrl); - Assert.Null(packageSpec.ReleaseNotes); - Assert.False(packageSpec.RequireLicenseAcceptance); - Assert.Null(packageSpec.Summary); - Assert.Empty(packageSpec.Tags); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsValueIsValid_ReturnsPackOptions() - { - const string iconUrl = "a"; - const string licenseUrl = "b"; - string[] owners = { "c", "d" }; - const string projectUrl = "e"; - const string releaseNotes = "f"; - const bool requireLicenseAcceptance = true; - const string summary = "g"; - string[] tags = { "h", "i" }; - - var json = $"{{\"packOptions\":{{\"iconUrl\":\"{iconUrl}\",\"licenseUrl\":\"{licenseUrl}\",\"owners\":[{string.Join(",", owners.Select(owner => $"\"{owner}\""))}]," + - $"\"projectUrl\":\"{projectUrl}\",\"releaseNotes\":\"{releaseNotes}\",\"requireLicenseAcceptance\":{requireLicenseAcceptance.ToString().ToLowerInvariant()}," + - $"\"summary\":\"{summary}\",\"tags\":[{string.Join(",", tags.Select(tag => $"\"{tag}\""))}]}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.NotNull(packageSpec.PackOptions); - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - Assert.Null(packageSpec.PackOptions.Mappings); - Assert.Empty(packageSpec.PackOptions.PackageType); - Assert.Equal(iconUrl, packageSpec.IconUrl); - Assert.Equal(licenseUrl, packageSpec.LicenseUrl); - Assert.Equal(owners, packageSpec.Owners); - Assert.Equal(projectUrl, packageSpec.ProjectUrl); - Assert.Equal(releaseNotes, packageSpec.ReleaseNotes); - Assert.Equal(requireLicenseAcceptance, packageSpec.RequireLicenseAcceptance); - Assert.Equal(summary, packageSpec.Summary); - Assert.Equal(tags, packageSpec.Tags); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsNull_ReturnsEmptyPackageTypes() - { - const string json = "{\"packOptions\":{\"packageType\":null}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.PackOptions.PackageType); - } - - [Theory] - [InlineData("true")] - [InlineData("-2")] - [InlineData("3.14")] - [InlineData("{}")] - [InlineData("[true]")] - [InlineData("[-2]")] - [InlineData("[3.14]")] - [InlineData("[null]")] - [InlineData("[{}]")] - [InlineData("[[]]")] - public void GetPackageSpec_WhenPackOptionsPackageTypeIsInvalid_Throws(string value) - { - var json = $"{{\"packOptions\":{{\"packageType\":{value}}}}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : The pack options package type must be a string or array of strings in 'project.json'.", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a,b\"", "a,b")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a b\"]", "a b")] - public void GetPackageSpec_WhenPackOptionsPackageTypeValueIsValid_ReturnsPackageTypes(string value, string expectedName) - { - var expectedResult = new PackageType(expectedName, PackageType.EmptyVersion); - var json = $"{{\"packOptions\":{{\"packageType\":{value}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Collection( - packageSpec.PackOptions.PackageType, - actualResult => Assert.Equal(expectedResult, actualResult)); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesValueIsNull_ReturnsNullInclude() - { - const string json = "{\"packOptions\":{\"files\":null}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesValueIsEmptyObject_ReturnsNullInclude() - { - const string json = "{\"packOptions\":{\"files\":{}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsNull_ReturnsNullIncludeExcludeFiles() - { - const string json = "{\"packOptions\":{\"files\":{\"include\":null}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsEmptyArray_ReturnsEmptyInclude() - { - const string json = "{\"packOptions\":{\"files\":{\"include\":[]}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.Include); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesIncludeValueIsValid_ReturnsInclude(string value, params string[] expectedResults) - { - expectedResults = expectedResults ?? new string[] { null }; - - var json = $"{{\"packOptions\":{{\"files\":{{\"include\":{value}}}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.Include); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles() - { - const string json = "{\"packOptions\":{\"files\":{\"includeFiles\":null}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsEmptyArray_ReturnsEmptyIncludeFiles() - { - const string json = "{\"packOptions\":{\"files\":{\"includeFiles\":[]}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.IncludeFiles); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesIncludeFilesValueIsValid_ReturnsIncludeFiles(string value, params string[] expectedResults) - { - expectedResults = expectedResults ?? new string[] { null }; - - var json = $"{{\"packOptions\":{{\"files\":{{\"includeFiles\":{value}}}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.IncludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsNull_ReturnsNullIncludeExcludeFiles() - { - const string json = "{\"packOptions\":{\"files\":{\"exclude\":null}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsEmptyArray_ReturnsEmptyExclude() - { - const string json = "{\"packOptions\":{\"files\":{\"exclude\":[]}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.Exclude); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesExcludeValueIsValid_ReturnsExclude(string value, params string[] expectedResults) - { - expectedResults = expectedResults ?? new string[] { null }; - - var json = $"{{\"packOptions\":{{\"files\":{{\"exclude\":{value}}}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.Exclude); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsNull_ReturnsNullIncludeExcludeFiles() - { - const string json = "{\"packOptions\":{\"files\":{\"excludeFiles\":null}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.IncludeExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsEmptyArray_ReturnsEmptyExcludeFiles() - { - const string json = "{\"packOptions\":{\"files\":{\"excludeFiles\":[]}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.PackOptions.IncludeExcludeFiles.ExcludeFiles); - } - - [Theory] - [InlineData("\"a\"", "a")] - [InlineData("\"a, b\"", "a, b")] - [InlineData("[null]", null)] - [InlineData("[\"\"]", "")] - [InlineData("[\"a\"]", "a")] - [InlineData("[\"a, b\"]", "a, b")] - [InlineData("[\"a\", \"b\"]", "a", "b")] - public void GetPackageSpec_WhenPackOptionsFilesExcludeFilesValueIsValid_ReturnsExcludeFiles(string value, params string[] expectedResults) - { - expectedResults = expectedResults ?? new string[] { null }; - - var json = $"{{\"packOptions\":{{\"files\":{{\"excludeFiles\":{value}}}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.IncludeExcludeFiles.ExcludeFiles); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsPropertyIsAbsent_ReturnsNullMappings() - { - const string json = "{\"packOptions\":{\"files\":{}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.Mappings); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsNull_ReturnsNullMappings() - { - const string json = "{\"packOptions\":{\"files\":{\"mappings\":null}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.PackOptions.Mappings); - } - - [Theory] - [InlineData("\"b\"", "b")] - [InlineData("\"b,c\"", "b,c")] - [InlineData("[\"b\", \"c\"]", "b", "c")] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueIsValid_ReturnsMappings(string value, params string[] expectedIncludes) - { - var expectedResults = new Dictionary() - { - { "a", new IncludeExcludeFiles() { Include = expectedIncludes } } - }; - var json = $"{{\"packOptions\":{{\"files\":{{\"mappings\":{{\"a\":{value}}}}}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasMultipleMappings_ReturnsMappings() - { - var expectedResults = new Dictionary() - { - { "a", new IncludeExcludeFiles() { Include = new[] { "b" } } }, - { "c", new IncludeExcludeFiles() { Include = new[] { "d", "e" } } } - }; - const string json = "{\"packOptions\":{\"files\":{\"mappings\":{\"a\":\"b\",\"c\":[\"d\", \"e\"]}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); - } - - [Fact] - public void GetPackageSpec_WhenPackOptionsFilesMappingsValueHasFiles_ReturnsMappings() - { - var expectedResults = new Dictionary() - { - { - "a", - new IncludeExcludeFiles() - { - Include = new [] { "b" }, - IncludeFiles = new [] { "c" }, - Exclude = new [] { "d" }, - ExcludeFiles = new [] { "e" } - } - } - }; - const string json = "{\"packOptions\":{\"files\":{\"mappings\":{\"a\":{\"include\":\"b\",\"includeFiles\":\"c\",\"exclude\":\"d\",\"excludeFiles\":\"e\"}}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.PackOptions.Mappings); - } -#pragma warning restore CS0612 // Type or member is obsolete - - [Fact] - public void GetPackageSpec_WhenRestorePropertyIsAbsent_ReturnsNullRestoreMetadata() - { - const string json = "{}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Null(packageSpec.RestoreMetadata); - } - - [Fact] - public void GetPackageSpec_WhenRestoreValueIsEmptyObject_ReturnsRestoreMetadata() - { - const string json = "{\"restore\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.NotNull(packageSpec.RestoreMetadata); - } - - [Theory] - [InlineData("null")] - [InlineData("\"\"")] - [InlineData("\"a\"")] - public void GetPackageSpec_WhenRestoreProjectStyleValueIsInvalid_ReturnsProjectStyle(string value) - { - var json = $"{{\"restore\":{{\"projectStyle\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(ProjectStyle.Unknown, packageSpec.RestoreMetadata.ProjectStyle); - } - - [Fact] - public void GetPackageSpec_WhenRestoreProjectStyleValueIsValid_ReturnsProjectStyle() - { - const ProjectStyle expectedResult = ProjectStyle.PackageReference; - - var json = $"{{\"restore\":{{\"projectStyle\":\"{expectedResult.ToString().ToLowerInvariant()}\"}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectStyle); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestoreProjectUniqueNameValueIsValid_ReturnsProjectUniqueName( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"projectUniqueName\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectUniqueName); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestoreOutputPathValueIsValid_ReturnsOutputPath( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"outputPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.OutputPath); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestorePackagesPathValueIsValid_ReturnsPackagesPath( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"packagesPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.PackagesPath); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestoreProjectJsonPathValueIsValid_ReturnsProjectJsonPath( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"projectJsonPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectJsonPath); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestoreProjectNameValueIsValid_ReturnsProjectName( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"projectName\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectName); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestoreProjectPathValueIsValid_ReturnsProjectPath( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"projectPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ProjectPath); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenCrossTargetingValueIsValid_ReturnsCrossTargeting( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"crossTargeting\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CrossTargeting); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenLegacyPackagesDirectoryValueIsValid_ReturnsLegacyPackagesDirectory( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"legacyPackagesDirectory\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.LegacyPackagesDirectory); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenValidateRuntimeAssetsValueIsValid_ReturnsValidateRuntimeAssets( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"validateRuntimeAssets\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.ValidateRuntimeAssets); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenSkipContentFileWriteValueIsValid_ReturnsSkipContentFileWrite( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"skipContentFileWrite\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.SkipContentFileWrite); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenCentralPackageVersionsManagementEnabledValueIsValid_ReturnsCentralPackageVersionsManagementEnabled( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"centralPackageVersionsManagementEnabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageVersionsEnabled); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenCentralPackageVersionOverrideDisabledValueIsValid_ReturnsCentralPackageVersionOverrideDisabled( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"centralPackageVersionOverrideDisabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageVersionOverrideDisabled); - } - - [Theory] - [InlineData(null, false)] - [InlineData(true, true)] - [InlineData(false, false)] - public void GetPackageSpec_WhenCentralPackageTransitivePinningEnabledValueIsValid_ReturnsCentralPackageTransitivePinningEnabled( - bool? value, - bool expectedValue) - { - var json = $"{{\"restore\":{{\"CentralPackageTransitivePinningEnabled\":{(value.HasValue ? value.ToString().ToLowerInvariant() : "null")}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedValue, packageSpec.RestoreMetadata.CentralPackageTransitivePinningEnabled); - } - - [Fact] - public void GetPackageSpec_WhenSourcesValueIsEmptyObject_ReturnsEmptySources() - { - const string json = "{\"restore\":{\"sources\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.RestoreMetadata.Sources); - } - - [Fact] - public void GetPackageSpec_WhenSourcesValueIsValid_ReturnsSources() - { - PackageSource[] expectedResults = { new PackageSource(source: "a"), new PackageSource(source: "b") }; - string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult.Name}\":{{}}")); - var json = $"{{\"restore\":{{\"sources\":{{{values}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.RestoreMetadata.Sources); - } - - [Fact] - public void GetPackageSpec_WhenFilesValueIsEmptyObject_ReturnsEmptyFiles() - { - const string json = "{\"restore\":{\"files\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.RestoreMetadata.Files); - } - - [Fact] - public void GetPackageSpec_WhenFilesValueIsValid_ReturnsFiles() - { - ProjectRestoreMetadataFile[] expectedResults = - { - new ProjectRestoreMetadataFile(packagePath: "a", absolutePath: "b"), - new ProjectRestoreMetadataFile(packagePath: "c", absolutePath:"d") - }; - string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult.PackagePath}\":\"{expectedResult.AbsolutePath}\"")); - var json = $"{{\"restore\":{{\"files\":{{{values}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.RestoreMetadata.Files); - } - - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksValueIsEmptyObject_ReturnsEmptyFrameworks() - { - const string json = "{\"restore\":{\"frameworks\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.RestoreMetadata.TargetFrameworks); - } - - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksFrameworkNameValueIsValid_ReturnsFrameworks() - { - var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); - var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Collection( - packageSpec.RestoreMetadata.TargetFrameworks, - actualResult => Assert.Equal(expectedResult, actualResult)); - } - - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithoutAssets_ReturnsFrameworks() - { - var projectReference = new ProjectRestoreReference() - { - ProjectUniqueName = "a", - ProjectPath = "b" - }; - var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); - - expectedResult.ProjectReferences.Add(projectReference); - - var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{\"projectReferences\":{{" + - $"\"{projectReference.ProjectUniqueName}\":{{\"projectPath\":\"{projectReference.ProjectPath}\"}}}}}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Collection( - packageSpec.RestoreMetadata.TargetFrameworks, - actualResult => Assert.Equal(expectedResult, actualResult)); - } - - [Fact] - public void GetPackageSpec_WhenRestoreFrameworksFrameworkValueHasProjectReferenceWithAssets_ReturnsFrameworks() - { - var projectReference = new ProjectRestoreReference() - { - ProjectUniqueName = "a", - ProjectPath = "b", - IncludeAssets = LibraryIncludeFlags.Analyzers, - ExcludeAssets = LibraryIncludeFlags.Native, - PrivateAssets = LibraryIncludeFlags.Runtime - }; - var expectedResult = new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.ParseFolder("net472")); - - expectedResult.ProjectReferences.Add(projectReference); - - var json = $"{{\"restore\":{{\"frameworks\":{{\"{expectedResult.FrameworkName.GetShortFolderName()}\":{{\"projectReferences\":{{" + - $"\"{projectReference.ProjectUniqueName}\":{{\"projectPath\":\"{projectReference.ProjectPath}\"," + - $"\"includeAssets\":\"{projectReference.IncludeAssets}\",\"excludeAssets\":\"{projectReference.ExcludeAssets}\"," + - $"\"privateAssets\":\"{projectReference.PrivateAssets}\"}}}}}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Collection( - packageSpec.RestoreMetadata.TargetFrameworks, - actualResult => Assert.Equal(expectedResult, actualResult)); - } - - [Fact] - public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsEmptyArray_ReturnsEmptyConfigFilePaths() - { - const string json = "{\"restore\":{\"configFilePaths\":[]}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.RestoreMetadata.ConfigFilePaths); - } - - [Fact] - public void GetPackageSpec_WhenRestoreConfigFilePathsValueIsValid_ReturnsConfigFilePaths() - { - string[] expectedResults = { "a", "b" }; - string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); - var json = $"{{\"restore\":{{\"configFilePaths\":[{values}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.RestoreMetadata.ConfigFilePaths); - } - - [Fact] - public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsEmptyArray_ReturnsEmptyFallbackFolders() - { - const string json = "{\"restore\":{\"fallbackFolders\":[]}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.RestoreMetadata.FallbackFolders); - } - - [Fact] - public void GetPackageSpec_WhenRestoreFallbackFoldersValueIsValid_ReturnsConfigFilePaths() - { - string[] expectedResults = { "a", "b" }; - string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); - var json = $"{{\"restore\":{{\"fallbackFolders\":[{values}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.RestoreMetadata.FallbackFolders); - } - - [Fact] - public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsEmptyArray_ReturnsEmptyOriginalTargetFrameworks() - { - const string json = "{\"restore\":{\"originalTargetFrameworks\":[]}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.RestoreMetadata.OriginalTargetFrameworks); - } - - [Fact] - public void GetPackageSpec_WhenRestoreOriginalTargetFrameworksValueIsValid_ReturnsOriginalTargetFrameworks() - { - string[] expectedResults = { "a", "b" }; - string values = string.Join(",", expectedResults.Select(expectedResult => $"\"{expectedResult}\"")); - var json = $"{{\"restore\":{{\"originalTargetFrameworks\":[{values}]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResults, packageSpec.RestoreMetadata.OriginalTargetFrameworks); - } - - [Fact] - public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsEmptyObject_ReturnsWarningProperties() - { - var expectedResult = new WarningProperties(); - const string json = "{\"restore\":{\"warningProperties\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectWideWarningProperties); - } - - [Fact] - public void GetPackageSpec_WhenRestoreWarningPropertiesValueIsValid_ReturnsWarningProperties() - { - var expectedResult = new WarningProperties( - new HashSet() { NuGetLogCode.NU3000 }, - new HashSet() { NuGetLogCode.NU3001 }, - allWarningsAsErrors: true, - new HashSet()); - var json = $"{{\"restore\":{{\"warningProperties\":{{\"allWarningsAsErrors\":{expectedResult.AllWarningsAsErrors.ToString().ToLowerInvariant()}," + - $"\"warnAsError\":[\"{expectedResult.WarningsAsErrors.Single()}\"],\"noWarn\":[\"{expectedResult.NoWarn.Single()}\"]}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RestoreMetadata.ProjectWideWarningProperties); - } - - [Fact] - public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsEmptyObject_ReturnsRestoreLockProperties() - { - var expectedResult = new RestoreLockProperties(); - const string json = "{\"restore\":{\"restoreLockProperties\":{}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RestoreMetadata.RestoreLockProperties); - } - - [Fact] - public void GetPackageSpec_WhenRestoreRestoreLockPropertiesValueIsValid_ReturnsRestoreLockProperties() - { - var expectedResult = new RestoreLockProperties( - restorePackagesWithLockFile: "a", - nuGetLockFilePath: "b", - restoreLockedMode: true); ; - var json = $"{{\"restore\":{{\"restoreLockProperties\":{{\"restoreLockedMode\":{expectedResult.RestoreLockedMode.ToString().ToLowerInvariant()}," + - $"\"restorePackagesWithLockFile\":\"{expectedResult.RestorePackagesWithLockFile}\"," + - $"\"nuGetLockFilePath\":\"{expectedResult.NuGetLockFilePath}\"}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RestoreMetadata.RestoreLockProperties); - } - - [Theory] - [InlineData("null")] - [InlineData("\"\"")] - [InlineData("\"a\"")] - public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsNotPackagesConfig_DoesNotReturnPackagesConfigPath( - string value) - { - var json = $"{{\"restore\":{{\"projectStyle\":\"PackageReference\",\"packagesConfigPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.IsNotType(packageSpec.RestoreMetadata); - } - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenRestorePackagesConfigPathValueIsValidAndProjectStyleValueIsPackagesConfig_ReturnsPackagesConfigPath( - string value, - string expectedValue) - { - var json = $"{{\"restore\":{{\"projectStyle\":\"PackagesConfig\",\"packagesConfigPath\":{value}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.IsType(packageSpec.RestoreMetadata); - Assert.Equal(expectedValue, ((PackagesConfigProjectRestoreMetadata)packageSpec.RestoreMetadata).PackagesConfigPath); - } - - [Fact] - public void GetPackageSpec_WhenRestoreSettingsValueIsEmptyObject_ReturnsRestoreSettings() - { - var expectedResult = new ProjectRestoreSettings(); - const string json = "{\"restoreSettings\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RestoreSettings); - } - - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsEmptyObject_ReturnsRuntimes() - { - var expectedResult = RuntimeGraph.Empty; - const string json = "{\"runtimes\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsValidWithImports_ReturnsRuntimes() - { - var runtimeDescription = new RuntimeDescription( - runtimeIdentifier: "a", - inheritedRuntimes: new[] { "b", "c" }, - Enumerable.Empty()); - var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); - var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"#import\":[" + - $"{string.Join(",", runtimeDescription.InheritedRuntimes.Select(runtime => $"\"{runtime}\""))}]}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySet_ReturnsRuntimes() - { - var dependencySet = new RuntimeDependencySet(id: "b"); - var runtimeDescription = new RuntimeDescription( - runtimeIdentifier: "a", - inheritedRuntimes: Enumerable.Empty(), - runtimeDependencySets: new[] { dependencySet }); - var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); - var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"{dependencySet.Id}\":{{}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - - [Fact] - public void GetPackageSpec_WhenRuntimesValueIsValidWithDependencySetWithDependency_ReturnsRuntimes() - { - var dependency = new RuntimePackageDependency("c", VersionRange.Parse("[1.2.3,4.5.6)")); - var dependencySet = new RuntimeDependencySet(id: "b", new[] { dependency }); - var runtimeDescription = new RuntimeDescription( - runtimeIdentifier: "a", - inheritedRuntimes: Enumerable.Empty(), - runtimeDependencySets: new[] { dependencySet }); - var expectedResult = new RuntimeGraph(new[] { runtimeDescription }); - var json = $"{{\"runtimes\":{{\"{runtimeDescription.RuntimeIdentifier}\":{{\"{dependencySet.Id}\":{{" + - $"\"{dependency.Id}\":\"{dependency.VersionRange.ToLegacyString()}\"}}}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - - [Fact] - public void GetPackageSpec_WhenSupportsValueIsEmptyObject_ReturnsSupports() - { - var expectedResult = RuntimeGraph.Empty; - const string json = "{\"supports\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - - [Fact] - public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfiles_ReturnsSupports() - { - var profile = new CompatibilityProfile(name: "a"); - var expectedResult = new RuntimeGraph(new[] { profile }); - var json = $"{{\"supports\":{{\"{profile.Name}\":{{}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - - [Fact] - public void GetPackageSpec_WhenSupportsValueIsValidWithCompatibilityProfilesAndFrameworkRuntimePairs_ReturnsSupports() - { - FrameworkRuntimePair[] restoreContexts = new[] - { - new FrameworkRuntimePair(NuGetFramework.Parse("net472"), "b"), - new FrameworkRuntimePair(NuGetFramework.Parse("net48"), "c") - }; - var profile = new CompatibilityProfile(name: "a", restoreContexts); - var expectedResult = new RuntimeGraph(new[] { profile }); - var json = $"{{\"supports\":{{\"{profile.Name}\":{{" + - $"\"{restoreContexts[0].Framework.GetShortFolderName()}\":\"{restoreContexts[0].RuntimeIdentifier}\"," + - $"\"{restoreContexts[1].Framework.GetShortFolderName()}\":[\"{restoreContexts[1].RuntimeIdentifier}\"]}}}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.RuntimeGraph); - } - -#pragma warning disable CS0612 // Type or member is obsolete - [Fact] - public void GetPackageSpec_WhenScriptsValueIsEmptyObject_ReturnsScripts() - { - const string json = "{\"scripts\":{}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Empty(packageSpec.Scripts); - } - - [Fact] - public void GetPackageSpec_WhenScriptsValueIsInvalid_Throws() - { - var json = "{\"scripts\":{\"a\":0}}"; - - FileFormatException exception = Assert.Throws(() => GetPackageSpec(json)); - - Assert.Equal("Error reading '' : The value of a script in 'project.json' can only be a string or an array of strings", exception.Message); - Assert.IsType(exception.InnerException); - Assert.Null(exception.InnerException.InnerException); - - } - - [Fact] - public void GetPackageSpec_WhenScriptsValueIsValid_ReturnsScripts() - { - const string name0 = "a"; - const string name1 = "b"; - const string script0 = "c"; - const string script1 = "d"; - const string script2 = "e"; - - var json = $"{{\"scripts\":{{\"{name0}\":\"{script0}\",\"{name1}\":[\"{script1}\",\"{script2}\"]}}}}"; - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Collection( - packageSpec.Scripts, - actualResult => - { - Assert.Equal(name0, actualResult.Key); - Assert.Collection( - actualResult.Value, - actualScript => Assert.Equal(script0, actualScript)); - }, - actualResult => - { - Assert.Equal(name1, actualResult.Key); - Assert.Collection( - actualResult.Value, - actualScript => Assert.Equal(script1, actualScript), - actualScript => Assert.Equal(script2, actualScript)); - }); - } -#pragma warning restore CS0612 // Type or member is obsolete - - [Theory] - [InlineData("null", null)] - [InlineData("\"\"", "")] - [InlineData("\"a\"", "a")] - public void GetPackageSpec_WhenTitleValueIsValid_ReturnsTitle(string value, string expectedResult) - { - var json = $"{{\"title\":{value}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.Title); - } - - [Fact] - public void GetPackageSpec_WhenNameIsNull_RestoreMetadataProvidesFallbackName() - { - const string expectedResult = "a"; - var json = $"{{\"restore\":{{\"projectName\":\"{expectedResult}\"}}}}"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.Name); - } - - [Theory] - [InlineData("{\"restore\":{\"projectJsonPath\":\"a\"}}")] - [InlineData("{\"restore\":{\"projectPath\":\"a\"}}")] - [InlineData("{\"restore\":{\"projectJsonPath\":\"a\",\"projectPath\":\"b\"}}")] - public void GetPackageSpec_WhenFilePathIsNull_RestoreMetadataProvidesFallbackFilePath(string json) - { - const string expectedResult = "a"; - - PackageSpec packageSpec = GetPackageSpec(json); - - Assert.Equal(expectedResult, packageSpec.FilePath); - } - - [Fact] - public void GetTargetFrameworkInformation_WithAnAlias() - { - TargetFrameworkInformation framework = GetFramework("{\"frameworks\":{\"net46\":{ \"targetAlias\" : \"alias\"}}}"); - - Assert.Equal("alias", framework.TargetAlias); - } - - [Fact] - public void PackageSpecReader_ReadsRestoreMetadataWithAliases() - { - // Arrange - var json = @"{ - ""restore"": { - ""projectUniqueName"": ""projectUniqueName"", - ""projectName"": ""projectName"", - ""projectPath"": ""projectPath"", - ""projectJsonPath"": ""projectJsonPath"", - ""packagesPath"": ""packagesPath"", - ""outputPath"": ""outputPath"", - ""projectStyle"": ""PackageReference"", - ""crossTargeting"": true, - ""frameworks"": { - ""frameworkidentifier123-frameworkprofile"": { - ""targetAlias"" : ""alias"", - ""projectReferences"": {} - } - }, - ""warningProperties"": { - } - } -}"; - - var actual = Utf8JsonStreamPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); - - // Assert - var metadata = actual.RestoreMetadata; - var warningProperties = actual.RestoreMetadata.ProjectWideWarningProperties; - - Assert.NotNull(metadata); - Assert.Equal("alias", metadata.TargetFrameworks.Single().TargetAlias); - } - - [Fact] - public void PackageSpecReader_Read() - { - // Arrange - var json = @"{ - ""centralTransitiveDependencyGroups"": { - "".NETCoreApp,Version=v3.1"": { - ""Foo"": { - ""exclude"": ""Native"", - ""include"": ""Build"", - ""suppressParent"": ""All"", - ""version"": ""1.0.0"" - } - }, - "".NETCoreApp,Version=v3.0"": { - ""Bar"": { - ""exclude"": ""Native"", - ""include"": ""Build"", - ""suppressParent"": ""All"", - ""version"": ""2.0.0"" - } - } - } - }"; - - // Act - var results = new List(); - using Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); - var reader = new Utf8JsonStreamReader(stream); - - if (reader.TokenType == JsonTokenType.StartObject) - { - while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) - { - if (reader.Read() && reader.TokenType == JsonTokenType.StartObject) - { - while (reader.Read() && reader.TokenType == JsonTokenType.PropertyName) - { - var frameworkPropertyName = reader.GetString(); - NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); - var dependencies = new List(); - - Utf8JsonStreamPackageSpecReader.ReadCentralTransitiveDependencyGroup( - jsonReader: ref reader, - results: dependencies, - packageSpecPath: "SomePath"); - results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); - } - } - } - } - - // Assert - Assert.Equal(2, results.Count); - Assert.Equal(".NETCoreApp,Version=v3.1", results.ElementAt(0).FrameworkName); - var firstGroup = results.ElementAt(0); - Assert.Equal(1, firstGroup.TransitiveDependencies.Count()); - Assert.Equal("Build", firstGroup.TransitiveDependencies.First().IncludeType.ToString()); - Assert.Equal("All", firstGroup.TransitiveDependencies.First().SuppressParent.ToString()); - Assert.Equal("[1.0.0, )", firstGroup.TransitiveDependencies.First().LibraryRange.VersionRange.ToNormalizedString()); - Assert.True(firstGroup.TransitiveDependencies.First().VersionCentrallyManaged); - - var secondGroup = results.ElementAt(1); - Assert.Equal(1, secondGroup.TransitiveDependencies.Count()); - Assert.Equal("Build", secondGroup.TransitiveDependencies.First().IncludeType.ToString()); - Assert.Equal("All", secondGroup.TransitiveDependencies.First().SuppressParent.ToString()); - Assert.Equal("[2.0.0, )", secondGroup.TransitiveDependencies.First().LibraryRange.VersionRange.ToNormalizedString()); - Assert.True(secondGroup.TransitiveDependencies.First().VersionCentrallyManaged); - } - - [Fact] - public void GetPackageSpec_WithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework() - { - var json = $"{{\"frameworks\":{{\"net5.0\":{{\"secondaryFramework\": \"native\"}}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - framework.FrameworkName.Should().BeOfType(); - var dualCompatibilityFramework = framework.FrameworkName as DualCompatibilityFramework; - dualCompatibilityFramework.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); - dualCompatibilityFramework.SecondaryFramework.Should().Be(FrameworkConstants.CommonFrameworks.Native); - } - - [Fact] - public void GetPackageSpec_WithAssetTargetFallbackAndWithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework() - { - var json = $"{{\"frameworks\":{{\"net5.0\":{{\"assetTargetFallback\": true, \"imports\": [\"net472\", \"net471\"], \"secondaryFramework\": \"native\" }}}}}}"; - - TargetFrameworkInformation framework = GetFramework(json); - framework.FrameworkName.Should().BeOfType(); - framework.AssetTargetFallback.Should().BeTrue(); - var assetTargetFallbackFramework = framework.FrameworkName as AssetTargetFallbackFramework; - assetTargetFallbackFramework.RootFramework.Should().BeOfType(); - var dualCompatibilityFramework = assetTargetFallbackFramework.RootFramework as DualCompatibilityFramework; - dualCompatibilityFramework.RootFramework.Should().Be(FrameworkConstants.CommonFrameworks.Net50); - dualCompatibilityFramework.SecondaryFramework.Should().Be(FrameworkConstants.CommonFrameworks.Native); - assetTargetFallbackFramework.Fallback.Should().HaveCount(2); - assetTargetFallbackFramework.Fallback.First().Should().Be(FrameworkConstants.CommonFrameworks.Net472); - assetTargetFallbackFramework.Fallback.Last().Should().Be(FrameworkConstants.CommonFrameworks.Net471); - } - - [Fact] - public void GetPackageSpec_WithRestoreAuditProperties_ReturnsRestoreAuditProperties() - { - // Arrange - var json = $"{{\"restore\":{{\"restoreAuditProperties\":{{\"enableAudit\": \"a\", \"auditLevel\": \"b\", \"auditMode\": \"c\"}}}}}}"; - - // Act - PackageSpec packageSpec = GetPackageSpec(json); - - // Assert - packageSpec.RestoreMetadata.RestoreAuditProperties.EnableAudit.Should().Be("a"); - packageSpec.RestoreMetadata.RestoreAuditProperties.AuditLevel.Should().Be("b"); - packageSpec.RestoreMetadata.RestoreAuditProperties.AuditMode.Should().Be("c"); - } - - private static PackageSpec GetPackageSpec(string json) - { - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) - { - return Utf8JsonStreamPackageSpecReader.GetPackageSpec(stream, name: null, packageSpecPath: null, snapshotValue: null); - } - } - - private static LibraryDependency GetDependency(string json) - { - PackageSpec packageSpec = GetPackageSpec(json); - - return packageSpec.Dependencies.Single(); - } - - private static TargetFrameworkInformation GetFramework(string json) - { - PackageSpec packageSpec = GetPackageSpec(json); - - return packageSpec.TargetFrameworks.Single(); - } - - private static LibraryDependency GetFrameworksDependency(string json) - { - TargetFrameworkInformation framework = GetFramework(json); - - return framework.Dependencies.Single(); - } - - private static FrameworkDependency GetFrameworksFrameworkReference(string json) - { - TargetFrameworkInformation framework = GetFramework(json); - - return framework.FrameworkReferences.Single(); - } - } -} diff --git a/test/TestUtilities/Test.Utility/TestEnvironmentVariableReader.cs b/test/TestUtilities/Test.Utility/TestEnvironmentVariableReader.cs index d2556660e89..ef5b209b8c8 100644 --- a/test/TestUtilities/Test.Utility/TestEnvironmentVariableReader.cs +++ b/test/TestUtilities/Test.Utility/TestEnvironmentVariableReader.cs @@ -11,6 +11,8 @@ public sealed class TestEnvironmentVariableReader : IEnvironmentVariableReader { private readonly IReadOnlyDictionary _variables; + private readonly string _toStringSuffix; + public static IEnvironmentVariableReader EmptyInstance { get; } = new TestEnvironmentVariableReader(); private TestEnvironmentVariableReader() @@ -18,9 +20,10 @@ private TestEnvironmentVariableReader() _variables = new Dictionary(); } - public TestEnvironmentVariableReader(IReadOnlyDictionary variables) + public TestEnvironmentVariableReader(IReadOnlyDictionary variables, string toStringSuffix = null) { _variables = variables ?? throw new ArgumentNullException(nameof(variables)); + _toStringSuffix = toStringSuffix; } public string GetEnvironmentVariable(string variable) @@ -32,5 +35,14 @@ public string GetEnvironmentVariable(string variable) return null; } + + public override string ToString() + { + if (string.IsNullOrEmpty(_toStringSuffix)) + { + return base.ToString(); + } + return $"{base.ToString()}({_toStringSuffix})"; + } } } From 96e628a696461d5a9b11559a8ae424506f5b99b4 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Wed, 13 Dec 2023 10:13:27 -0800 Subject: [PATCH 05/20] Remove unused functions --- .../NuGet.ProjectModel/FileFormatException.cs | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs index 0dd5de270cd..5d240d3ce2f 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/FileFormatException.cs @@ -47,14 +47,6 @@ private FileFormatException WithLineInfo(int line, int column) return this; } - private FileFormatException WithLineInfo(long? line, long? column) - { - Line = unchecked((int)line.Value); - Column = unchecked((int)column); - - return this; - } - private FileFormatException WithLineInfo(IJsonLineInfo lineInfo) { Line = lineInfo.LineNumber; @@ -140,33 +132,5 @@ internal static FileFormatException Create(string message, string path) return new FileFormatException(message) .WithFilePath(path); } - - internal static FileFormatException Create(System.Text.Json.JsonException exception, string path) - { - string message; - if (exception.BytePositionInLine is not null && exception.LineNumber is not null) - { - message = string.Format(CultureInfo.CurrentCulture, - Strings.Log_ErrorReadingProjectJsonWithLocation, - path, exception.LineNumber, - exception.BytePositionInLine, - exception.Message); - } - else - { - message = string.Format(CultureInfo.CurrentCulture, - Strings.Log_ErrorReadingProjectJson, - path, - exception.Message); - } - var fileFormatException = new FileFormatException(message, exception); - fileFormatException.WithFilePath(path); - if (exception.BytePositionInLine is not null && exception.LineNumber is not null) - { - fileFormatException.WithLineInfo(exception.LineNumber, exception.BytePositionInLine); - } - - return fileFormatException; - } } } From de5f9e82ade57dc7ae90f4e2a61380e9c275adb6 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Wed, 13 Dec 2023 10:35:32 -0800 Subject: [PATCH 06/20] Rename property names --- .../Utf8JsonStreamPackageSpecReader.cs | 392 +++++++++--------- 1 file changed, 196 insertions(+), 196 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs index 86a1ffc27e9..5a20e0a249e 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs @@ -18,97 +18,97 @@ namespace NuGet.ProjectModel { - internal static class Utf8JsonStreamPackageSpecReader + internal static class JsonStreamPackageSpecReaderPropertyName { private static readonly char[] VersionSeparators = new[] { ';' }; - private static readonly byte[] Utf8Authors = Encoding.UTF8.GetBytes("authors"); - private static readonly byte[] BuildOptionsUtf8 = Encoding.UTF8.GetBytes("buildOptions"); - private static readonly byte[] Utf8ContentFiles = Encoding.UTF8.GetBytes("contentFiles"); - private static readonly byte[] Utf8Copyright = Encoding.UTF8.GetBytes("copyright"); - private static readonly byte[] Utf8Dependencies = Encoding.UTF8.GetBytes("dependencies"); - private static readonly byte[] Utf8Description = Encoding.UTF8.GetBytes("description"); - private static readonly byte[] Utf8Language = Encoding.UTF8.GetBytes("language"); - private static readonly byte[] Utf8PackInclude = Encoding.UTF8.GetBytes("packInclude"); - private static readonly byte[] Utf8PackOptions = Encoding.UTF8.GetBytes("packOptions"); - private static readonly byte[] Utf8Scripts = Encoding.UTF8.GetBytes("scripts"); - private static readonly byte[] Utf8Frameworks = Encoding.UTF8.GetBytes("frameworks"); - private static readonly byte[] Utf8Restore = Encoding.UTF8.GetBytes("restore"); - private static readonly byte[] Utf8Runtimes = Encoding.UTF8.GetBytes("runtimes"); - private static readonly byte[] Utf8Supports = Encoding.UTF8.GetBytes("supports"); - private static readonly byte[] Utf8Title = Encoding.UTF8.GetBytes("title"); - private static readonly byte[] Utf8Version = Encoding.UTF8.GetBytes("version"); - private static readonly byte[] Utf8OutputName = Encoding.UTF8.GetBytes("outputName"); - private static readonly byte[] Utf8AutoReferenced = Encoding.UTF8.GetBytes("autoReferenced"); - private static readonly byte[] Utf8Exclude = Encoding.UTF8.GetBytes("exclude"); - private static readonly byte[] Utf8GeneratePathProperty = Encoding.UTF8.GetBytes("generatePathProperty"); - private static readonly byte[] Utf8Include = Encoding.UTF8.GetBytes("include"); - private static readonly byte[] Utf8NoWarn = Encoding.UTF8.GetBytes("noWarn"); - private static readonly byte[] Utf8SuppressParent = Encoding.UTF8.GetBytes("suppressParent"); - private static readonly byte[] Utf8Target = Encoding.UTF8.GetBytes("target"); - private static readonly byte[] Utf8VersionOverride = Encoding.UTF8.GetBytes("versionOverride"); - private static readonly byte[] Utf8VersionCentrallyManaged = Encoding.UTF8.GetBytes("versionCentrallyManaged"); - private static readonly byte[] Utf8Aliases = Encoding.UTF8.GetBytes("aliases"); - private static readonly byte[] Utf8Name = Encoding.UTF8.GetBytes("name"); - private static readonly byte[] Utf8PrivateAssets = Encoding.UTF8.GetBytes("privateAssets"); - private static readonly byte[] Utf8ExcludeFiles = Encoding.UTF8.GetBytes("excludeFiles"); - private static readonly byte[] Utf8IncludeFiles = Encoding.UTF8.GetBytes("includeFiles"); - private static readonly byte[] Utf8CentralPackageVersionsManagementEnabled = Encoding.UTF8.GetBytes("centralPackageVersionsManagementEnabled"); - private static readonly byte[] Utf8CentralPackageVersionOverrideDisabled = Encoding.UTF8.GetBytes("centralPackageVersionOverrideDisabled"); - private static readonly byte[] Utf8CentralPackageTransitivePinningEnabled = Encoding.UTF8.GetBytes("CentralPackageTransitivePinningEnabled"); - private static readonly byte[] Utf8ConfigFilePaths = Encoding.UTF8.GetBytes("configFilePaths"); - private static readonly byte[] Utf8CrossTargeting = Encoding.UTF8.GetBytes("crossTargeting"); - private static readonly byte[] Utf8FallbackFolders = Encoding.UTF8.GetBytes("fallbackFolders"); - private static readonly byte[] Utf8Files = Encoding.UTF8.GetBytes("files"); - private static readonly byte[] Utf8LegacyPackagesDirectory = Encoding.UTF8.GetBytes("legacyPackagesDirectory"); - private static readonly byte[] Utf8OriginalTargetFrameworks = Encoding.UTF8.GetBytes("originalTargetFrameworks"); - private static readonly byte[] Utf8OutputPath = Encoding.UTF8.GetBytes("outputPath"); - private static readonly byte[] Utf8PackagesConfigPath = Encoding.UTF8.GetBytes("packagesConfigPath"); - private static readonly byte[] Utf8PackagesPath = Encoding.UTF8.GetBytes("packagesPath"); - private static readonly byte[] Utf8ProjectJsonPath = Encoding.UTF8.GetBytes("projectJsonPath"); - private static readonly byte[] Utf8ProjectName = Encoding.UTF8.GetBytes("projectName"); - private static readonly byte[] Utf8ProjectPath = Encoding.UTF8.GetBytes("projectPath"); - private static readonly byte[] Utf8ProjectStyle = Encoding.UTF8.GetBytes("projectStyle"); - private static readonly byte[] Utf8ProjectUniqueName = Encoding.UTF8.GetBytes("projectUniqueName"); - private static readonly byte[] Utf8RestoreLockProperties = Encoding.UTF8.GetBytes("restoreLockProperties"); - private static readonly byte[] Utf8NuGetLockFilePath = Encoding.UTF8.GetBytes("nuGetLockFilePath"); - private static readonly byte[] Utf8RestoreLockedMode = Encoding.UTF8.GetBytes("restoreLockedMode"); - private static readonly byte[] Utf8RestorePackagesWithLockFile = Encoding.UTF8.GetBytes("restorePackagesWithLockFile"); - private static readonly byte[] Utf8RestoreAuditProperties = Encoding.UTF8.GetBytes("restoreAuditProperties"); - private static readonly byte[] Utf8EnableAudit = Encoding.UTF8.GetBytes("enableAudit"); - private static readonly byte[] Utf8AuditLevel = Encoding.UTF8.GetBytes("auditLevel"); - private static readonly byte[] Utf8AuditMode = Encoding.UTF8.GetBytes("auditMode"); - private static readonly byte[] Utf8SkipContentFileWrite = Encoding.UTF8.GetBytes("skipContentFileWrite"); - private static readonly byte[] Utf8Sources = Encoding.UTF8.GetBytes("sources"); - private static readonly byte[] Utf8ValidateRuntimeAssets = Encoding.UTF8.GetBytes("validateRuntimeAssets"); - private static readonly byte[] Utf8WarningProperties = Encoding.UTF8.GetBytes("warningProperties"); - private static readonly byte[] Utf8AllWarningsAsErrors = Encoding.UTF8.GetBytes("allWarningsAsErrors"); - private static readonly byte[] Utf8WarnAsError = Encoding.UTF8.GetBytes("warnAsError"); - private static readonly byte[] Utf8WarnNotAsError = Encoding.UTF8.GetBytes("warnNotAsError"); - private static readonly byte[] Utf8ExcludeAssets = Encoding.UTF8.GetBytes("excludeAssets"); - private static readonly byte[] Utf8IncludeAssets = Encoding.UTF8.GetBytes("includeAssets"); - private static readonly byte[] Utf8TargetAlias = Encoding.UTF8.GetBytes("targetAlias"); - private static readonly byte[] Utf8AssetTargetFallback = Encoding.UTF8.GetBytes("assetTargetFallback"); - private static readonly byte[] Utf8SecondaryFramework = Encoding.UTF8.GetBytes("secondaryFramework"); - private static readonly byte[] Utf8CentralPackageVersions = Encoding.UTF8.GetBytes("centralPackageVersions"); - private static readonly byte[] Utf8DownloadDependencies = Encoding.UTF8.GetBytes("downloadDependencies"); - private static readonly byte[] Utf8FrameworkAssemblies = Encoding.UTF8.GetBytes("frameworkAssemblies"); - private static readonly byte[] Utf8FrameworkReferences = Encoding.UTF8.GetBytes("frameworkReferences"); - private static readonly byte[] Utf8Imports = Encoding.UTF8.GetBytes("imports"); - private static readonly byte[] Utf8RuntimeIdentifierGraphPath = Encoding.UTF8.GetBytes("runtimeIdentifierGraphPath"); - private static readonly byte[] Utf8Warn = Encoding.UTF8.GetBytes("warn"); - private static readonly byte[] Utf8IconUrl = Encoding.UTF8.GetBytes("iconUrl"); - private static readonly byte[] Utf8LicenseUrl = Encoding.UTF8.GetBytes("licenseUrl"); - private static readonly byte[] Utf8Owners = Encoding.UTF8.GetBytes("owners"); - private static readonly byte[] Utf8PackageType = Encoding.UTF8.GetBytes("packageType"); - private static readonly byte[] Utf8ProjectUrl = Encoding.UTF8.GetBytes("projectUrl"); - private static readonly byte[] Utf8ReleaseNotes = Encoding.UTF8.GetBytes("releaseNotes"); - private static readonly byte[] Utf8RequireLicenseAcceptance = Encoding.UTF8.GetBytes("requireLicenseAcceptance"); - private static readonly byte[] Utf8Summary = Encoding.UTF8.GetBytes("summary"); - private static readonly byte[] Utf8Tags = Encoding.UTF8.GetBytes("tags"); - private static readonly byte[] Utf8Mappings = Encoding.UTF8.GetBytes("mappings"); - private static readonly byte[] Utf8HashTagImport = Encoding.UTF8.GetBytes("#import"); - private static readonly byte[] Utf8ProjectReferences = Encoding.UTF8.GetBytes("projectReferences"); - private static readonly byte[] Utf8EmptyString = Encoding.UTF8.GetBytes(string.Empty); + private static readonly byte[] AuthorsPropertyName = Encoding.UTF8.GetBytes("authors"); + private static readonly byte[] BuildOptionsPropertyName = Encoding.UTF8.GetBytes("buildOptions"); + private static readonly byte[] ContentFilesPropertyName = Encoding.UTF8.GetBytes("contentFiles"); + private static readonly byte[] CopyrightPropertyName = Encoding.UTF8.GetBytes("copyright"); + private static readonly byte[] DependenciesPropertyName = Encoding.UTF8.GetBytes("dependencies"); + private static readonly byte[] DescriptionPropertyName = Encoding.UTF8.GetBytes("description"); + private static readonly byte[] LanguagePropertyName = Encoding.UTF8.GetBytes("language"); + private static readonly byte[] PackIncludePropertyName = Encoding.UTF8.GetBytes("packInclude"); + private static readonly byte[] PackOptionsPropertyName = Encoding.UTF8.GetBytes("packOptions"); + private static readonly byte[] ScriptsPropertyName = Encoding.UTF8.GetBytes("scripts"); + private static readonly byte[] FrameworksPropertyName = Encoding.UTF8.GetBytes("frameworks"); + private static readonly byte[] RestorePropertyName = Encoding.UTF8.GetBytes("restore"); + private static readonly byte[] RuntimesPropertyName = Encoding.UTF8.GetBytes("runtimes"); + private static readonly byte[] SupportsPropertyName = Encoding.UTF8.GetBytes("supports"); + private static readonly byte[] TitlePropertyName = Encoding.UTF8.GetBytes("title"); + private static readonly byte[] VersionPropertyName = Encoding.UTF8.GetBytes("version"); + private static readonly byte[] OutputNamePropertyName = Encoding.UTF8.GetBytes("outputName"); + private static readonly byte[] AutoReferencedPropertyName = Encoding.UTF8.GetBytes("autoReferenced"); + private static readonly byte[] ExcludePropertyName = Encoding.UTF8.GetBytes("exclude"); + private static readonly byte[] GeneratePathPropertyPropertyName = Encoding.UTF8.GetBytes("generatePathProperty"); + private static readonly byte[] IncludePropertyName = Encoding.UTF8.GetBytes("include"); + private static readonly byte[] NoWarnPropertyName = Encoding.UTF8.GetBytes("noWarn"); + private static readonly byte[] SuppressParentPropertyName = Encoding.UTF8.GetBytes("suppressParent"); + private static readonly byte[] TargetPropertyName = Encoding.UTF8.GetBytes("target"); + private static readonly byte[] VersionOverridePropertyName = Encoding.UTF8.GetBytes("versionOverride"); + private static readonly byte[] VersionCentrallyManagedPropertyName = Encoding.UTF8.GetBytes("versionCentrallyManaged"); + private static readonly byte[] AliasesPropertyName = Encoding.UTF8.GetBytes("aliases"); + private static readonly byte[] NamePropertyName = Encoding.UTF8.GetBytes("name"); + private static readonly byte[] PrivateAssetsPropertyName = Encoding.UTF8.GetBytes("privateAssets"); + private static readonly byte[] ExcludeFilesPropertyName = Encoding.UTF8.GetBytes("excludeFiles"); + private static readonly byte[] IncludeFilesPropertyName = Encoding.UTF8.GetBytes("includeFiles"); + private static readonly byte[] CentralPackageVersionsManagementEnabledPropertyName = Encoding.UTF8.GetBytes("centralPackageVersionsManagementEnabled"); + private static readonly byte[] CentralPackageVersionOverrideDisabledPropertyName = Encoding.UTF8.GetBytes("centralPackageVersionOverrideDisabled"); + private static readonly byte[] CentralPackageTransitivePinningEnabledPropertyName = Encoding.UTF8.GetBytes("CentralPackageTransitivePinningEnabled"); + private static readonly byte[] ConfigFilePathsPropertyName = Encoding.UTF8.GetBytes("configFilePaths"); + private static readonly byte[] CrossTargetingPropertyName = Encoding.UTF8.GetBytes("crossTargeting"); + private static readonly byte[] FallbackFoldersPropertyName = Encoding.UTF8.GetBytes("fallbackFolders"); + private static readonly byte[] FilesPropertyName = Encoding.UTF8.GetBytes("files"); + private static readonly byte[] LegacyPackagesDirectoryPropertyName = Encoding.UTF8.GetBytes("legacyPackagesDirectory"); + private static readonly byte[] OriginalTargetFrameworksPropertyName = Encoding.UTF8.GetBytes("originalTargetFrameworks"); + private static readonly byte[] OutputPathPropertyName = Encoding.UTF8.GetBytes("outputPath"); + private static readonly byte[] PackagesConfigPathPropertyName = Encoding.UTF8.GetBytes("packagesConfigPath"); + private static readonly byte[] PackagesPathPropertyName = Encoding.UTF8.GetBytes("packagesPath"); + private static readonly byte[] ProjectJsonPathPropertyName = Encoding.UTF8.GetBytes("projectJsonPath"); + private static readonly byte[] ProjectNamePropertyName = Encoding.UTF8.GetBytes("projectName"); + private static readonly byte[] ProjectPathPropertyName = Encoding.UTF8.GetBytes("projectPath"); + private static readonly byte[] ProjectStylePropertyName = Encoding.UTF8.GetBytes("projectStyle"); + private static readonly byte[] ProjectUniqueNamePropertyName = Encoding.UTF8.GetBytes("projectUniqueName"); + private static readonly byte[] RestoreLockPropertiesPropertyName = Encoding.UTF8.GetBytes("restoreLockProperties"); + private static readonly byte[] NuGetLockFilePathPropertyName = Encoding.UTF8.GetBytes("nuGetLockFilePath"); + private static readonly byte[] RestoreLockedModePropertyName = Encoding.UTF8.GetBytes("restoreLockedMode"); + private static readonly byte[] RestorePackagesWithLockFilePropertyName = Encoding.UTF8.GetBytes("restorePackagesWithLockFile"); + private static readonly byte[] RestoreAuditPropertiesPropertyName = Encoding.UTF8.GetBytes("restoreAuditProperties"); + private static readonly byte[] EnableAuditPropertyName = Encoding.UTF8.GetBytes("enableAudit"); + private static readonly byte[] AuditLevelPropertyName = Encoding.UTF8.GetBytes("auditLevel"); + private static readonly byte[] AuditModePropertyName = Encoding.UTF8.GetBytes("auditMode"); + private static readonly byte[] SkipContentFileWritePropertyName = Encoding.UTF8.GetBytes("skipContentFileWrite"); + private static readonly byte[] SourcesPropertyName = Encoding.UTF8.GetBytes("sources"); + private static readonly byte[] ValidateRuntimeAssetsPropertyName = Encoding.UTF8.GetBytes("validateRuntimeAssets"); + private static readonly byte[] WarningPropertiesPropertyName = Encoding.UTF8.GetBytes("warningProperties"); + private static readonly byte[] AllWarningsAsErrorsPropertyName = Encoding.UTF8.GetBytes("allWarningsAsErrors"); + private static readonly byte[] WarnAsErrorPropertyName = Encoding.UTF8.GetBytes("warnAsError"); + private static readonly byte[] WarnNotAsErrorPropertyName = Encoding.UTF8.GetBytes("warnNotAsError"); + private static readonly byte[] ExcludeAssetsPropertyName = Encoding.UTF8.GetBytes("excludeAssets"); + private static readonly byte[] IncludeAssetsPropertyName = Encoding.UTF8.GetBytes("includeAssets"); + private static readonly byte[] TargetAliasPropertyName = Encoding.UTF8.GetBytes("targetAlias"); + private static readonly byte[] AssetTargetFallbackPropertyName = Encoding.UTF8.GetBytes("assetTargetFallback"); + private static readonly byte[] SecondaryFrameworkPropertyName = Encoding.UTF8.GetBytes("secondaryFramework"); + private static readonly byte[] CentralPackageVersionsPropertyName = Encoding.UTF8.GetBytes("centralPackageVersions"); + private static readonly byte[] DownloadDependenciesPropertyName = Encoding.UTF8.GetBytes("downloadDependencies"); + private static readonly byte[] FrameworkAssembliesPropertyName = Encoding.UTF8.GetBytes("frameworkAssemblies"); + private static readonly byte[] FrameworkReferencesPropertyName = Encoding.UTF8.GetBytes("frameworkReferences"); + private static readonly byte[] ImportsPropertyName = Encoding.UTF8.GetBytes("imports"); + private static readonly byte[] RuntimeIdentifierGraphPathPropertyName = Encoding.UTF8.GetBytes("runtimeIdentifierGraphPath"); + private static readonly byte[] WarnPropertyName = Encoding.UTF8.GetBytes("warn"); + private static readonly byte[] IconUrlPropertyName = Encoding.UTF8.GetBytes("iconUrl"); + private static readonly byte[] LicenseUrlPropertyName = Encoding.UTF8.GetBytes("licenseUrl"); + private static readonly byte[] OwnersPropertyName = Encoding.UTF8.GetBytes("owners"); + private static readonly byte[] PackageTypePropertyName = Encoding.UTF8.GetBytes("packageType"); + private static readonly byte[] ProjectUrlPropertyName = Encoding.UTF8.GetBytes("projectUrl"); + private static readonly byte[] ReleaseNotesPropertyName = Encoding.UTF8.GetBytes("releaseNotes"); + private static readonly byte[] RequireLicenseAcceptancePropertyName = Encoding.UTF8.GetBytes("requireLicenseAcceptance"); + private static readonly byte[] SummaryPropertyName = Encoding.UTF8.GetBytes("summary"); + private static readonly byte[] TagsPropertyName = Encoding.UTF8.GetBytes("tags"); + private static readonly byte[] MappingsPropertyName = Encoding.UTF8.GetBytes("mappings"); + private static readonly byte[] HashTagImportPropertyName = Encoding.UTF8.GetBytes("#import"); + private static readonly byte[] ProjectReferencesPropertyName = Encoding.UTF8.GetBytes("projectReferences"); + private static readonly byte[] EmptyStringPropertyName = Encoding.UTF8.GetBytes(string.Empty); internal static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, string snapshotValue = null) { @@ -150,12 +150,12 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8EmptyString)) + if (jsonReader.ValueTextEquals(EmptyStringPropertyName)) { jsonReader.Skip(); } #pragma warning disable CS0612 // Type or member is obsolete - else if (jsonReader.ValueTextEquals(Utf8Authors)) + else if (jsonReader.ValueTextEquals(AuthorsPropertyName)) { jsonReader.Read(); if (jsonReader.TokenType == JsonTokenType.StartArray) @@ -167,42 +167,42 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, packageSpec.Authors = Array.Empty(); } } - else if (jsonReader.ValueTextEquals(BuildOptionsUtf8)) + else if (jsonReader.ValueTextEquals(BuildOptionsPropertyName)) { ReadBuildOptions(ref jsonReader, packageSpec); } - else if (jsonReader.ValueTextEquals(Utf8ContentFiles)) + else if (jsonReader.ValueTextEquals(ContentFilesPropertyName)) { jsonReader.Read(); jsonReader.ReadStringArrayAsIList(packageSpec.ContentFiles); } - else if (jsonReader.ValueTextEquals(Utf8Copyright)) + else if (jsonReader.ValueTextEquals(CopyrightPropertyName)) { packageSpec.Copyright = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Description)) + else if (jsonReader.ValueTextEquals(DescriptionPropertyName)) { packageSpec.Description = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Language)) + else if (jsonReader.ValueTextEquals(LanguagePropertyName)) { packageSpec.Language = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8PackInclude)) + else if (jsonReader.ValueTextEquals(PackIncludePropertyName)) { ReadPackInclude(ref jsonReader, packageSpec); } - else if (jsonReader.ValueTextEquals(Utf8PackOptions)) + else if (jsonReader.ValueTextEquals(PackOptionsPropertyName)) { ReadPackOptions(ref jsonReader, packageSpec, ref isMappingsNull); wasPackOptionsSet = true; } - else if (jsonReader.ValueTextEquals(Utf8Scripts)) + else if (jsonReader.ValueTextEquals(ScriptsPropertyName)) { ReadScripts(ref jsonReader, packageSpec); } #pragma warning restore CS0612 // Type or member is - else if (jsonReader.ValueTextEquals(Utf8Dependencies)) + else if (jsonReader.ValueTextEquals(DependenciesPropertyName)) { ReadDependencies( ref jsonReader, @@ -210,27 +210,27 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, filePath, isGacOrFrameworkReference: false); } - else if (jsonReader.ValueTextEquals(Utf8Frameworks)) + else if (jsonReader.ValueTextEquals(FrameworksPropertyName)) { ReadFrameworks(ref jsonReader, packageSpec); } - else if (jsonReader.ValueTextEquals(Utf8Restore)) + else if (jsonReader.ValueTextEquals(RestorePropertyName)) { ReadMSBuildMetadata(ref jsonReader, packageSpec); } - else if (jsonReader.ValueTextEquals(Utf8Runtimes)) + else if (jsonReader.ValueTextEquals(RuntimesPropertyName)) { runtimeDescriptions = ReadRuntimes(ref jsonReader); } - else if (jsonReader.ValueTextEquals(Utf8Supports)) + else if (jsonReader.ValueTextEquals(SupportsPropertyName)) { compatibilityProfiles = ReadSupports(ref jsonReader); } - else if (jsonReader.ValueTextEquals(Utf8Title)) + else if (jsonReader.ValueTextEquals(TitlePropertyName)) { packageSpec.Title = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Version)) + else if (jsonReader.ValueTextEquals(VersionPropertyName)) { string version = jsonReader.ReadNextTokenAsString(); if (version != null) @@ -327,22 +327,22 @@ internal static void ReadCentralTransitiveDependencyGroup( { IEnumerable values = null; - if (jsonReader.ValueTextEquals(Utf8Exclude)) + if (jsonReader.ValueTextEquals(ExcludePropertyName)) { values = jsonReader.ReadDelimitedString(); dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } - else if (jsonReader.ValueTextEquals(Utf8Include)) + else if (jsonReader.ValueTextEquals(IncludePropertyName)) { values = jsonReader.ReadDelimitedString(); dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } - else if (jsonReader.ValueTextEquals(Utf8SuppressParent)) + else if (jsonReader.ValueTextEquals(SuppressParentPropertyName)) { values = jsonReader.ReadDelimitedString(); suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } - else if (jsonReader.ValueTextEquals(Utf8Version)) + else if (jsonReader.ValueTextEquals(VersionPropertyName)) { if (jsonReader.Read()) { @@ -453,45 +453,45 @@ private static void ReadDependencies( while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { IEnumerable values = null; - if (jsonReader.ValueTextEquals(Utf8AutoReferenced)) + if (jsonReader.ValueTextEquals(AutoReferencedPropertyName)) { autoReferenced = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8Exclude)) + else if (jsonReader.ValueTextEquals(ExcludePropertyName)) { values = jsonReader.ReadDelimitedString(); dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } - else if (jsonReader.ValueTextEquals(Utf8GeneratePathProperty)) + else if (jsonReader.ValueTextEquals(GeneratePathPropertyPropertyName)) { generatePathProperty = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8Include)) + else if (jsonReader.ValueTextEquals(IncludePropertyName)) { values = jsonReader.ReadDelimitedString(); dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } - else if (jsonReader.ValueTextEquals(Utf8NoWarn)) + else if (jsonReader.ValueTextEquals(NoWarnPropertyName)) { noWarn = ReadNuGetLogCodesList(ref jsonReader); } - else if (jsonReader.ValueTextEquals(Utf8SuppressParent)) + else if (jsonReader.ValueTextEquals(SuppressParentPropertyName)) { values = jsonReader.ReadDelimitedString(); suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } - else if (jsonReader.ValueTextEquals(Utf8Target)) + else if (jsonReader.ValueTextEquals(TargetPropertyName)) { targetFlagsValue = ReadTarget(ref jsonReader, packageSpecPath, targetFlagsValue); } - else if (jsonReader.ValueTextEquals(Utf8Version)) + else if (jsonReader.ValueTextEquals(VersionPropertyName)) { if (jsonReader.Read()) { dependencyVersionValue = jsonReader.GetString(); } } - else if (jsonReader.ValueTextEquals(Utf8VersionOverride)) + else if (jsonReader.ValueTextEquals(VersionOverridePropertyName)) { if (jsonReader.Read()) { @@ -506,11 +506,11 @@ private static void ReadDependencies( } } } - else if (jsonReader.ValueTextEquals(Utf8VersionCentrallyManaged)) + else if (jsonReader.ValueTextEquals(VersionCentrallyManagedPropertyName)) { versionCentrallyManaged = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8Aliases)) + else if (jsonReader.ValueTextEquals(AliasesPropertyName)) { aliases = jsonReader.ReadNextTokenAsString(); } @@ -602,7 +602,7 @@ private static void ReadBuildOptions(ref Utf8JsonStreamReader jsonReader, Packag { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8OutputName)) + if (jsonReader.ValueTextEquals(OutputNamePropertyName)) { packageSpec.BuildOptions.OutputName = jsonReader.ReadNextTokenAsString(); } @@ -692,12 +692,12 @@ private static void ReadDownloadDependencies( { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8Name)) + if (jsonReader.ValueTextEquals(NamePropertyName)) { isNameDefined = true; name = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Version)) + else if (jsonReader.ValueTextEquals(VersionPropertyName)) { versionValue = jsonReader.ReadNextTokenAsString(); } @@ -777,7 +777,7 @@ private static void ReadFrameworkReferences( { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8PrivateAssets)) + if (jsonReader.ValueTextEquals(PrivateAssetsPropertyName)) { IEnumerable strings = jsonReader.ReadDelimitedString(); @@ -876,19 +876,19 @@ private static void ReadMappings(ref Utf8JsonStreamReader jsonReader, string map while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8ExcludeFiles)) + if (jsonReader.ValueTextEquals(ExcludeFilesPropertyName)) { excludeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8Exclude)) + else if (jsonReader.ValueTextEquals(ExcludePropertyName)) { exclude = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8IncludeFiles)) + else if (jsonReader.ValueTextEquals(IncludeFilesPropertyName)) { includeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8Include)) + else if (jsonReader.ValueTextEquals(IncludePropertyName)) { include = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } @@ -948,33 +948,33 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8CentralPackageVersionsManagementEnabled)) + if (jsonReader.ValueTextEquals(CentralPackageVersionsManagementEnabledPropertyName)) { centralPackageVersionsManagementEnabled = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8CentralPackageVersionOverrideDisabled)) + else if (jsonReader.ValueTextEquals(CentralPackageVersionOverrideDisabledPropertyName)) { centralPackageVersionOverrideDisabled = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8CentralPackageTransitivePinningEnabled)) + else if (jsonReader.ValueTextEquals(CentralPackageTransitivePinningEnabledPropertyName)) { CentralPackageTransitivePinningEnabled = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8ConfigFilePaths)) + else if (jsonReader.ValueTextEquals(ConfigFilePathsPropertyName)) { jsonReader.Read(); configFilePaths = jsonReader.ReadStringArrayAsIList() as List; } - else if (jsonReader.ValueTextEquals(Utf8CrossTargeting)) + else if (jsonReader.ValueTextEquals(CrossTargetingPropertyName)) { crossTargeting = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8FallbackFolders)) + else if (jsonReader.ValueTextEquals(FallbackFoldersPropertyName)) { jsonReader.Read(); fallbackFolders = jsonReader.ReadStringArrayAsIList() as List; } - else if (jsonReader.ValueTextEquals(Utf8Files)) + else if (jsonReader.ValueTextEquals(FilesPropertyName)) { if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) { @@ -987,44 +987,44 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac } } } - else if (jsonReader.ValueTextEquals(Utf8Frameworks)) + else if (jsonReader.ValueTextEquals(FrameworksPropertyName)) { targetFrameworks = ReadTargetFrameworks(ref jsonReader); } - else if (jsonReader.ValueTextEquals(Utf8LegacyPackagesDirectory)) + else if (jsonReader.ValueTextEquals(LegacyPackagesDirectoryPropertyName)) { legacyPackagesDirectory = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8OriginalTargetFrameworks)) + else if (jsonReader.ValueTextEquals(OriginalTargetFrameworksPropertyName)) { jsonReader.Read(); originalTargetFrameworks = jsonReader.ReadStringArrayAsIList() as List; } - else if (jsonReader.ValueTextEquals(Utf8OutputPath)) + else if (jsonReader.ValueTextEquals(OutputPathPropertyName)) { outputPath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8PackagesConfigPath)) + else if (jsonReader.ValueTextEquals(PackagesConfigPathPropertyName)) { packagesConfigPath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8PackagesPath)) + else if (jsonReader.ValueTextEquals(PackagesPathPropertyName)) { packagesPath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8ProjectJsonPath)) + else if (jsonReader.ValueTextEquals(ProjectJsonPathPropertyName)) { projectJsonPath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8ProjectName)) + else if (jsonReader.ValueTextEquals(ProjectNamePropertyName)) { projectName = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8ProjectPath)) + else if (jsonReader.ValueTextEquals(ProjectPathPropertyName)) { projectPath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8ProjectStyle)) + else if (jsonReader.ValueTextEquals(ProjectStylePropertyName)) { string projectStyleString = jsonReader.ReadNextTokenAsString(); @@ -1034,11 +1034,11 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac projectStyle = projectStyleValue; } } - else if (jsonReader.ValueTextEquals(Utf8ProjectUniqueName)) + else if (jsonReader.ValueTextEquals(ProjectUniqueNamePropertyName)) { projectUniqueName = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8RestoreLockProperties)) + else if (jsonReader.ValueTextEquals(RestoreLockPropertiesPropertyName)) { string nuGetLockFilePath = null; var restoreLockedMode = false; @@ -1048,15 +1048,15 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8NuGetLockFilePath)) + if (jsonReader.ValueTextEquals(NuGetLockFilePathPropertyName)) { nuGetLockFilePath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8RestoreLockedMode)) + else if (jsonReader.ValueTextEquals(RestoreLockedModePropertyName)) { restoreLockedMode = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8RestorePackagesWithLockFile)) + else if (jsonReader.ValueTextEquals(RestorePackagesWithLockFilePropertyName)) { restorePackagesWithLockFile = jsonReader.ReadNextTokenAsString(); } @@ -1068,22 +1068,22 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac } restoreLockProperties = new RestoreLockProperties(restorePackagesWithLockFile, nuGetLockFilePath, restoreLockedMode); } - else if (jsonReader.ValueTextEquals(Utf8RestoreAuditProperties)) + else if (jsonReader.ValueTextEquals(RestoreAuditPropertiesPropertyName)) { string enableAudit = null, auditLevel = null, auditMode = null; if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8EnableAudit)) + if (jsonReader.ValueTextEquals(EnableAuditPropertyName)) { enableAudit = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8AuditLevel)) + else if (jsonReader.ValueTextEquals(AuditLevelPropertyName)) { auditLevel = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8AuditMode)) + else if (jsonReader.ValueTextEquals(AuditModePropertyName)) { auditMode = jsonReader.ReadNextTokenAsString(); } @@ -1100,11 +1100,11 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac AuditMode = auditMode, }; } - else if (jsonReader.ValueTextEquals(Utf8SkipContentFileWrite)) + else if (jsonReader.ValueTextEquals(SkipContentFileWritePropertyName)) { skipContentFileWrite = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8Sources)) + else if (jsonReader.ValueTextEquals(SourcesPropertyName)) { if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) { @@ -1118,11 +1118,11 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac } } } - else if (jsonReader.ValueTextEquals(Utf8ValidateRuntimeAssets)) + else if (jsonReader.ValueTextEquals(ValidateRuntimeAssetsPropertyName)) { validateRuntimeAssets = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8WarningProperties)) + else if (jsonReader.ValueTextEquals(WarningPropertiesPropertyName)) { var allWarningsAsErrors = false; var noWarn = new HashSet(); @@ -1133,19 +1133,19 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8AllWarningsAsErrors)) + if (jsonReader.ValueTextEquals(AllWarningsAsErrorsPropertyName)) { allWarningsAsErrors = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8NoWarn)) + else if (jsonReader.ValueTextEquals(NoWarnPropertyName)) { ReadNuGetLogCodes(ref jsonReader, noWarn); } - else if (jsonReader.ValueTextEquals(Utf8WarnAsError)) + else if (jsonReader.ValueTextEquals(WarnAsErrorPropertyName)) { ReadNuGetLogCodes(ref jsonReader, warnAsError); } - else if (jsonReader.ValueTextEquals(Utf8WarnNotAsError)) + else if (jsonReader.ValueTextEquals(WarnNotAsErrorPropertyName)) { ReadNuGetLogCodes(ref jsonReader, warningsNotAsErrors); } @@ -1370,19 +1370,19 @@ private static void ReadPackOptions(ref Utf8JsonStreamReader jsonReader, Package isPackOptionsValueAnObject = true; while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8Files)) + if (jsonReader.ValueTextEquals(FilesPropertyName)) { wasMappingsRead = ReadPackOptionsFiles(packageSpec, ref jsonReader, wasMappingsRead); } - else if (jsonReader.ValueTextEquals(Utf8IconUrl)) + else if (jsonReader.ValueTextEquals(IconUrlPropertyName)) { packageSpec.IconUrl = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8LicenseUrl)) + else if (jsonReader.ValueTextEquals(LicenseUrlPropertyName)) { packageSpec.LicenseUrl = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Owners)) + else if (jsonReader.ValueTextEquals(OwnersPropertyName)) { jsonReader.Read(); string[] owners = jsonReader.ReadStringArrayAsIList()?.ToArray(); @@ -1391,27 +1391,27 @@ private static void ReadPackOptions(ref Utf8JsonStreamReader jsonReader, Package packageSpec.Owners = owners; } } - else if (jsonReader.ValueTextEquals(Utf8PackageType)) + else if (jsonReader.ValueTextEquals(PackageTypePropertyName)) { ReadPackageTypes(packageSpec, ref jsonReader); } - else if (jsonReader.ValueTextEquals(Utf8ProjectUrl)) + else if (jsonReader.ValueTextEquals(ProjectUrlPropertyName)) { packageSpec.ProjectUrl = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8ReleaseNotes)) + else if (jsonReader.ValueTextEquals(ReleaseNotesPropertyName)) { packageSpec.ReleaseNotes = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8RequireLicenseAcceptance)) + else if (jsonReader.ValueTextEquals(RequireLicenseAcceptancePropertyName)) { packageSpec.RequireLicenseAcceptance = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8Summary)) + else if (jsonReader.ValueTextEquals(SummaryPropertyName)) { packageSpec.Summary = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Tags)) + else if (jsonReader.ValueTextEquals(TagsPropertyName)) { jsonReader.Read(); string[] tags = jsonReader.ReadStringArrayAsIList()?.ToArray(); @@ -1443,23 +1443,23 @@ private static bool ReadPackOptionsFiles(PackageSpec packageSpec, ref Utf8JsonSt while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { var filesPropertyName = jsonReader.GetString(); - if (jsonReader.ValueTextEquals(Utf8ExcludeFiles)) + if (jsonReader.ValueTextEquals(ExcludeFilesPropertyName)) { excludeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8Exclude)) + else if (jsonReader.ValueTextEquals(ExcludePropertyName)) { exclude = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8IncludeFiles)) + else if (jsonReader.ValueTextEquals(IncludeFilesPropertyName)) { includeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8Include)) + else if (jsonReader.ValueTextEquals(IncludePropertyName)) { include = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); } - else if (jsonReader.ValueTextEquals(Utf8Mappings)) + else if (jsonReader.ValueTextEquals(MappingsPropertyName)) { if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) { @@ -1523,7 +1523,7 @@ private static RuntimeDescription ReadRuntimeDescription(ref Utf8JsonStreamReade { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8HashTagImport)) + if (jsonReader.ValueTextEquals(HashTagImportPropertyName)) { jsonReader.Read(); inheritedRuntimes = jsonReader.ReadStringArrayAsIList() as List; @@ -1659,7 +1659,7 @@ private static List ReadTargetFrameworks(re { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8ProjectReferences)) + if (jsonReader.ValueTextEquals(ProjectReferencesPropertyName)) { if (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.StartObject) { @@ -1675,19 +1675,19 @@ private static List ReadTargetFrameworks(re { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8ExcludeAssets)) + if (jsonReader.ValueTextEquals(ExcludeAssetsPropertyName)) { excludeAssets = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8IncludeAssets)) + else if (jsonReader.ValueTextEquals(IncludeAssetsPropertyName)) { includeAssets = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8PrivateAssets)) + else if (jsonReader.ValueTextEquals(PrivateAssetsPropertyName)) { privateAssets = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8ProjectPath)) + else if (jsonReader.ValueTextEquals(ProjectPathPropertyName)) { projectReferenceProjectPath = jsonReader.ReadNextTokenAsString(); } @@ -1719,7 +1719,7 @@ private static List ReadTargetFrameworks(re } } } - else if (jsonReader.ValueTextEquals(Utf8TargetAlias)) + else if (jsonReader.ValueTextEquals(TargetAliasPropertyName)) { frameworkGroup.TargetAlias = jsonReader.ReadNextTokenAsString(); } @@ -1747,11 +1747,11 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - if (jsonReader.ValueTextEquals(Utf8AssetTargetFallback)) + if (jsonReader.ValueTextEquals(AssetTargetFallbackPropertyName)) { targetFrameworkInformation.AssetTargetFallback = jsonReader.ReadNextTokenAsBoolOrFalse(); } - else if (jsonReader.ValueTextEquals(Utf8SecondaryFramework)) + else if (jsonReader.ValueTextEquals(SecondaryFrameworkPropertyName)) { var secondaryFrameworkString = jsonReader.ReadNextTokenAsString(); if (!string.IsNullOrEmpty(secondaryFrameworkString)) @@ -1759,14 +1759,14 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt secondaryFramework = NuGetFramework.Parse(secondaryFrameworkString); } } - else if (jsonReader.ValueTextEquals(Utf8CentralPackageVersions)) + else if (jsonReader.ValueTextEquals(CentralPackageVersionsPropertyName)) { ReadCentralPackageVersions( ref jsonReader, targetFrameworkInformation.CentralPackageVersions, packageSpec.FilePath); } - else if (jsonReader.ValueTextEquals(Utf8Dependencies)) + else if (jsonReader.ValueTextEquals(DependenciesPropertyName)) { ReadDependencies( ref jsonReader, @@ -1774,14 +1774,14 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt packageSpec.FilePath, isGacOrFrameworkReference: false); } - else if (jsonReader.ValueTextEquals(Utf8DownloadDependencies)) + else if (jsonReader.ValueTextEquals(DownloadDependenciesPropertyName)) { ReadDownloadDependencies( ref jsonReader, targetFrameworkInformation.DownloadDependencies, packageSpec.FilePath); } - else if (jsonReader.ValueTextEquals(Utf8FrameworkAssemblies)) + else if (jsonReader.ValueTextEquals(FrameworkAssembliesPropertyName)) { ReadDependencies( ref jsonReader, @@ -1789,26 +1789,26 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt packageSpec.FilePath, isGacOrFrameworkReference: true); } - else if (jsonReader.ValueTextEquals(Utf8FrameworkReferences)) + else if (jsonReader.ValueTextEquals(FrameworkReferencesPropertyName)) { ReadFrameworkReferences( ref jsonReader, targetFrameworkInformation.FrameworkReferences, packageSpec.FilePath); } - else if (jsonReader.ValueTextEquals(Utf8Imports)) + else if (jsonReader.ValueTextEquals(ImportsPropertyName)) { ReadImports(packageSpec, ref jsonReader, targetFrameworkInformation); } - else if (jsonReader.ValueTextEquals(Utf8RuntimeIdentifierGraphPath)) + else if (jsonReader.ValueTextEquals(RuntimeIdentifierGraphPathPropertyName)) { targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8TargetAlias)) + else if (jsonReader.ValueTextEquals(TargetAliasPropertyName)) { targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); } - else if (jsonReader.ValueTextEquals(Utf8Warn)) + else if (jsonReader.ValueTextEquals(WarnPropertyName)) { targetFrameworkInformation.Warn = jsonReader.ReadNextTokenAsBoolOrFalse(); } From ee984061d08887565c3db51e59de0b85ed634226 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Wed, 13 Dec 2023 10:41:36 -0800 Subject: [PATCH 07/20] =?UTF-8?q?fix=20a=20rename=20bug=20=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs index 5a20e0a249e..e86efa5d073 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs @@ -18,7 +18,7 @@ namespace NuGet.ProjectModel { - internal static class JsonStreamPackageSpecReaderPropertyName + internal static class Utf8JsonStreamPackageSpecReader { private static readonly char[] VersionSeparators = new[] { ';' }; private static readonly byte[] AuthorsPropertyName = Encoding.UTF8.GetBytes("authors"); From 080362195c531d1a52d1922b4edb111f31488381 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Wed, 13 Dec 2023 11:01:46 -0800 Subject: [PATCH 08/20] Update dependency target tests --- .../JsonPackageSpecReader.cs | 2 +- .../DependencyTargetTests.cs | 93 +++++++++++++------ 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index 94e1041bc83..ba52052b5b0 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -77,7 +77,7 @@ internal static PackageSpec GetPackageSpec(Stream stream, string name, string pa using (var jsonReader = new JsonTextReader(textReader)) { #pragma warning disable CS0612 // Type or member is obsolete - return GetPackageSpec(jsonReader, packageSpecPath); + return NjPackageSpecReader.GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); #pragma warning restore CS0612 // Type or member is obsolete } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyTargetTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyTargetTests.cs index b86dcd11bba..b0e65bb8cc4 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyTargetTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/DependencyTargetTests.cs @@ -1,16 +1,22 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; +using System.IO; using System.Linq; +using System.Text; +using NuGet.Common; using NuGet.LibraryModel; using Xunit; namespace NuGet.ProjectModel.Test { + [Obsolete] public class DependencyTargetTests { - [Fact] - public void DependencyTarget_ExternalProjectValue() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_ExternalProjectValue(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -26,15 +32,16 @@ public void DependencyTarget_ExternalProjectValue() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); // Assert Assert.Equal(LibraryDependencyTarget.ExternalProject, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void DependencyTarget_ProjectValue() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_ProjectValue(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -50,15 +57,16 @@ public void DependencyTarget_ProjectValue() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); // Assert Assert.Equal(LibraryDependencyTarget.Project, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void DependencyTarget_PackageValue() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_PackageValue(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -74,15 +82,16 @@ public void DependencyTarget_PackageValue() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); // Assert Assert.Equal(LibraryDependencyTarget.Package, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void DependencyTarget_CaseInsensitive() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_CaseInsensitive(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -98,15 +107,16 @@ public void DependencyTarget_CaseInsensitive() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); // Assert Assert.Equal(LibraryDependencyTarget.Package, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void DependencyTarget_DefaultValueDefault() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_DefaultValueDefault(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -119,7 +129,7 @@ public void DependencyTarget_DefaultValueDefault() }"; // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); // Assert @@ -127,8 +137,9 @@ public void DependencyTarget_DefaultValueDefault() Assert.Equal(expected, dependency.LibraryRange.TypeConstraint); } - [Fact] - public void DependencyTarget_UnknownValueFails() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_UnknownValueFails(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -149,7 +160,7 @@ public void DependencyTarget_UnknownValueFails() try { - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); } catch (FileFormatException ex) @@ -161,11 +172,16 @@ public void DependencyTarget_UnknownValueFails() Assert.NotNull(exception); Assert.Equal("Invalid dependency target value 'blah'.", exception.Message); Assert.EndsWith("project.json", exception.Path); - Assert.Equal(5, exception.Line); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(5, exception.Line); + } } - [Fact] - public void DependencyTarget_NonWhiteListValueFails() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_NonWhiteListValueFails(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -186,7 +202,7 @@ public void DependencyTarget_NonWhiteListValueFails() try { - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); } catch (FileFormatException ex) @@ -198,11 +214,16 @@ public void DependencyTarget_NonWhiteListValueFails() Assert.NotNull(exception); Assert.Equal("Invalid dependency target value 'winmd'.", exception.Message); Assert.EndsWith("project.json", exception.Path); - Assert.Equal(5, exception.Line); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(5, exception.Line); + } } - [Fact] - public void DependencyTarget_MultipleValuesFail() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_MultipleValuesFail(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -223,7 +244,7 @@ public void DependencyTarget_MultipleValuesFail() try { - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); var dependency = spec.Dependencies.Single(); } catch (FileFormatException ex) @@ -235,11 +256,16 @@ public void DependencyTarget_MultipleValuesFail() Assert.NotNull(exception); Assert.Equal("Invalid dependency target value 'package,project'.", exception.Message); Assert.EndsWith("project.json", exception.Path); - Assert.Equal(5, exception.Line); + + if (string.Equals(bool.TrueString, environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"))) + { + Assert.Equal(5, exception.Line); + } } - [Fact] - public void DependencyTarget_AcceptsWhitespace() + [Theory] + [MemberData(nameof(JsonPackageSpecReaderTests.TestEnvironmentVariableReader), MemberType = typeof(JsonPackageSpecReaderTests))] + public void DependencyTarget_AcceptsWhitespace(IEnvironmentVariableReader environmentVariableReader) { // Arrange var json = @"{ @@ -256,11 +282,18 @@ public void DependencyTarget_AcceptsWhitespace() // Act - var spec = JsonPackageSpecReader.GetPackageSpec(json, "TestProject", "project.json"); + var spec = GetPackageSpec(json, "TestProject", "project.json", environmentVariableReader); // Assert var dependency = spec.Dependencies.Single(); Assert.Equal(LibraryDependencyTarget.Package, dependency.LibraryRange.TypeConstraint); } + + private static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, IEnvironmentVariableReader environmentVariableReader) + { + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + return JsonPackageSpecReader.GetPackageSpec(stream, name, packageSpecPath, null, environmentVariableReader); + } + } } From 08c02b289e00da6b16d647e003cbe29768f857ab Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Thu, 14 Dec 2023 10:40:47 -0800 Subject: [PATCH 09/20] fix unit tests --- .../NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs index e744202d028..3d2afa67010 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/Utf8JsonStreamReaderTests.cs @@ -441,7 +441,7 @@ public void ReadDelimitedString_WhenValueIsNotString_Throws(string value, JsonTo var json = $"{{\"a\":{value}}}"; var encodedBytes = Encoding.UTF8.GetBytes(json); var tokenType = JsonTokenType.None; - var exceptionThrown = Assert.Throws(() => + var exceptionThrown = Assert.Throws(() => { using var stream = new MemoryStream(encodedBytes); using var reader = new Utf8JsonStreamReader(stream); @@ -455,8 +455,7 @@ public void ReadDelimitedString_WhenValueIsNotString_Throws(string value, JsonTo tokenType = reader.TokenType; } }); - Assert.NotNull(exceptionThrown.InnerException); - Assert.IsType(typeof(InvalidCastException), exceptionThrown.InnerException); + Assert.Null(exceptionThrown.InnerException); Assert.Equal(expectedTokenType, tokenType); } From 51a1aa978a8aeb1f87e3cea71dc4ba659d68916f Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Thu, 14 Dec 2023 10:47:28 -0800 Subject: [PATCH 10/20] use doulbe quotes --- .../RestoreProjectJsonTest.cs | 300 +++++++++--------- 1 file changed, 150 insertions(+), 150 deletions(-) diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreProjectJsonTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreProjectJsonTest.cs index 4702b9f82f4..c766955223d 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreProjectJsonTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreProjectJsonTest.cs @@ -41,11 +41,11 @@ public async Task RestoreProjectJson_MinClientVersionFailAsync() await SimpleTestPackageUtility.CreatePackagesAsync(repositoryPath, packageContext); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0' + ""dependencies"": { + ""packageA"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -90,20 +90,20 @@ public void RestoreProjectJson_RestoreFolder_VerifyFailure() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); Util.CreateFile(projectDir2, "project.json", @"{ - 'version': '1.0.0-*', - 'dependencies': { + ""version"": ""1.0.0-*"", + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -151,10 +151,10 @@ public void RestoreProjectJson_RestoreForSingleProject() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -163,11 +163,11 @@ public void RestoreProjectJson_RestoreForSingleProject() Util.CreateFile(projectDir2, "project.json", @"{ - 'version': '1.0.0-*', - 'dependencies': { + ""version"": ""1.0.0-*"", + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -267,10 +267,10 @@ public async Task RestoreProjectJson_RestoreWithFallbackFolderAsync() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -279,13 +279,13 @@ public async Task RestoreProjectJson_RestoreWithFallbackFolderAsync() Util.CreateFile(projectDir2, "project.json", @"{ - 'version': '1.0.0-*', - 'dependencies': { - 'packageA': '1.0.0', - 'packageB': '1.0.0' + ""version"": ""1.0.0-*"", + ""dependencies"": { + ""packageA"": ""1.0.0"", + ""packageB"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -332,10 +332,10 @@ public void RestoreProjectJson_RestoreFromSlnWithCsproj() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -412,26 +412,26 @@ public void RestoreProjectJson_RestoreFromSlnWithCsproj_InconsitentCaseForProjec Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'net45': { } + ""frameworks"": { + ""net45"": { } } }"); Util.CreateFile(projectDir2, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'net45': { } + ""frameworks"": { + ""net45"": { } } }"); Util.CreateFile(projectDir3, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'net45': { } + ""frameworks"": { + ""net45"": { } } }"); @@ -570,10 +570,10 @@ public void RestoreProjectJson_P2PTimeouts(string timeout, int projectCount, int Util.CreateFile(projectDir, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -687,10 +687,10 @@ public async Task RestoreProjectJson_RestoreFromSlnWithReferenceOutputAssemblyFa Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -713,12 +713,12 @@ public async Task RestoreProjectJson_RestoreFromSlnWithReferenceOutputAssemblyFa Util.CreateFile(projectDir2, "project.json", @"{ - 'version': '1.0.0-*', - 'dependencies': { + ""version"": ""1.0.0-*"", + ""dependencies"": { ""packageA"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -897,10 +897,10 @@ public void RestoreProjectJson_RestoreCSProj() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -947,10 +947,10 @@ public void RestoreProjectJson_RestoreUnknownProj() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1002,11 +1002,11 @@ public async Task RestoreProjectJson_RestoreFromSlnWithUnknownProjAndCsproj() Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1014,12 +1014,12 @@ public async Task RestoreProjectJson_RestoreFromSlnWithUnknownProjAndCsproj() Util.CreateFile(projectDir2, "project.json", @"{ - 'version': '1.0.0-*', - 'dependencies': { - 'packageA': '1.1.0-beta-*' + ""version"": ""1.0.0-*"", + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1112,11 +1112,11 @@ public async Task RestoreProjectJson_RestoreFromSlnUsesNuGetFolderSettingsAsync( Util.CreateFile(projectDir1, "project.json", @"{ - 'dependencies': { - 'packageA': '1.0.0' + ""dependencies"": { + ""packageA"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1124,12 +1124,12 @@ public async Task RestoreProjectJson_RestoreFromSlnUsesNuGetFolderSettingsAsync( Util.CreateFile(projectDir2, "project.json", @"{ - 'version': '1.0.0-*', - 'dependencies': { - 'packageB': '1.0.0' + ""version"": ""1.0.0-*"", + ""dependencies"": { + ""packageB"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1215,11 +1215,11 @@ public void RestoreProjectJson_FloatReleaseLabelHighestPrelease() Util.CreateTestPackage("packageA", "1.0.0-beta-01", repositoryPath); Util.CreateTestPackage("packageA", "1.0.0-beta-02", repositoryPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0-*' + ""dependencies"": { + ""packageA"": ""1.0.0-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -1271,11 +1271,11 @@ public void RestoreProjectJson_FloatReleaseLabelTakesStable() Util.CreateTestPackage("packageA", "1.0.0-beta-01", repositoryPath); Util.CreateTestPackage("packageA", "1.0.0-beta-02", repositoryPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0-*' + ""dependencies"": { + ""packageA"": ""1.0.0-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -1383,11 +1383,11 @@ public void RestoreProjectJson_RestoreFiltersToStablePackages() Util.CreateTestPackage("packageB", "2.0.0-beta", repositoryPath); Util.CreateTestPackage("packageB", "3.0.0", repositoryPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0' + ""dependencies"": { + ""packageA"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -1439,12 +1439,12 @@ public void RestoreProjectJson_RestoreBumpsFromStableToPrereleaseWhenNeeded() Util.CreateTestPackage("packageC", "1.0.0", repositoryPath); Util.CreateTestPackage("packageC", "2.0.0-beta", repositoryPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0', - 'packageB': '1.0.0-*' + ""dependencies"": { + ""packageA"": ""1.0.0"", + ""packageB"": ""1.0.0-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -1495,12 +1495,12 @@ public void RestoreProjectJson_RestoreDowngradesStableDependency() Util.CreateTestPackage("packageC", "3.0.0", repositoryPath); Util.CreateTestPackage("packageC", "2.1.0", repositoryPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0', - 'packageB': '1.0.0' + ""dependencies"": { + ""packageA"": ""1.0.0"", + ""packageB"": ""1.0.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -1551,12 +1551,12 @@ public void RestoreProjectJson_RestoreDowngradesFromStableToPrereleaseWhenNeeded Util.CreateTestPackage("packageC", "2.0.0-beta", repositoryPath); Util.CreateConfigForGlobalPackagesFolder(workingPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.0.0', - 'packageB': '1.0.0-*' + ""dependencies"": { + ""packageA"": ""1.0.0"", + ""packageB"": ""1.0.0-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; @@ -1613,21 +1613,21 @@ public async Task RestoreProjectJson_SolutionFileWithAllProjectsInOneFolder() Util.CreateFile(projectDir, "testA.project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); Util.CreateFile(projectDir, "testB.project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1724,11 +1724,11 @@ public async Task RestoreProjectJson_GenerateFilesWithProjectNameFromCSProj() Util.CreateFile(workingPath, "test.project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1785,11 +1785,11 @@ public async Task RestoreProjectJson_GenerateTargetsFileFromSln() Util.CreateFile(projectDir, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1876,12 +1876,12 @@ public async Task RestoreProjectJson_GenerateTargetsFileFromCSProj() Util.CreateFile(workingPath, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*', - 'packageB': '2.2.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"", + ""packageB"": ""2.2.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -1972,12 +1972,12 @@ public async Task RestoreProjectJson_GenerateTargetsForFallbackFolderAsync() Util.CreateFile(projectDir, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*', - 'packageB': '2.2.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"", + ""packageB"": ""2.2.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -2038,12 +2038,12 @@ public async Task RestoreProjectJson_GenerateTargetsFileFromNuProj() Util.CreateFile(workingPath, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*', - 'packageB': '2.2.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"", + ""packageB"": ""2.2.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -2103,12 +2103,12 @@ public async Task RestoreProjectJson_GenerateTargetsFileWithFolder() Util.CreateFile(workingPath, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*', - 'packageB': '2.2.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"", + ""packageB"": ""2.2.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -2165,11 +2165,11 @@ public async Task RestoreProjectJson_GenerateTargetsForRootBuildFolderIgnoreSubF Util.CreateFile(workingPath, "project.json", @"{ - 'dependencies': { - 'packageA': '3.1.0', + ""dependencies"": { + ""packageA"": ""3.1.0"", }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -2232,12 +2232,12 @@ public async Task RestoreProjectJson_GenerateTargetsPersistsWithMultipleRestores Util.CreateFile(workingPath, "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0-beta-*', - 'packageB': '2.2.0-beta-*' + ""dependencies"": { + ""packageA"": ""1.1.0-beta-*"", + ""packageB"": ""2.2.0-beta-*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); @@ -2322,12 +2322,12 @@ public void RestoreProjectJson_CorruptedLockFile() Util.CreateTestPackage("packageA", "1.1.0", repositoryPath); Util.CreateTestPackage("packageB", "2.2.0", repositoryPath); var projectJson = @"{ - 'dependencies': { - 'packageA': '1.1.0', - 'packageB': '2.2.0' + ""dependencies"": { + ""packageA"": ""1.1.0"", + ""packageB"": ""2.2.0"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"; From 31d06f161d2bdac96de7b2feb8597004d4967fcf Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Thu, 14 Dec 2023 10:48:47 -0800 Subject: [PATCH 11/20] more double quotes --- .../NuGetRestoreCommandTest.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs index 571e6fd5b39..8fd0249e601 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs @@ -1288,12 +1288,12 @@ public void RestoreCommand_FromProjectJson_RelativeGlobalPackagesFolder() var projectJson = @"{ - 'dependencies': { - 'packageA': '1.1.0', - 'packageB': '2.2.0' + ""dependencies"": { + ""packageA"": ""1.1.0"", + ""packageB"": ""2.2.0"" }, - 'frameworks': { - 'netcore50': { } + ""frameworks"": { + ""netcore50"": { } } }"; @@ -1992,12 +1992,12 @@ public void RestoreCommand_FromSolutionFile_ProjectsInParentDir() Util.CreateFile(Path.Combine(basePath, "A", "A.Util"), "project.json", @"{ - 'dependencies': { - 'packageA': '1.1.0', - 'packageB': '2.2.0' + ""dependencies"": { + ""packageA"": ""1.1.0"", + ""packageB"": ""2.2.0"" }, - 'frameworks': { - 'netcore50': { } + ""frameworks"": { + ""netcore50"": { } } }"); Util.CreateFile(Path.Combine(basePath, "B"), "B.csproj", @@ -2022,10 +2022,10 @@ public void RestoreCommand_FromSolutionFile_ProjectsInParentDir() Util.CreateFile(Path.Combine(basePath, "B"), "project.json", @"{ - 'dependencies': { + ""dependencies"": { }, - 'frameworks': { - 'netcore50': { } + ""frameworks"": { + ""netcore50"": { } } }"); From 0b268164707ca5d2c50a0928a520853cc521490b Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Thu, 14 Dec 2023 10:49:48 -0800 Subject: [PATCH 12/20] double quoootes --- test/NuGet.Clients.Tests/NuGet.CommandLine.Test/Util.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/Util.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/Util.cs index 861456d7b3a..f051ef54ca4 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/Util.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/Util.cs @@ -994,14 +994,14 @@ public static void CreateConfigFile(string path, string configFileName, string t public static string GetProjectJsonFileContents(string targetFramework, IEnumerable packages) { - var dependencies = string.Join(", ", packages.Select(package => $"'{package.Id}': '{package.Version}'")); + var dependencies = string.Join(", ", packages.Select(package => $"\"{package.Id}\": \"{package.Version}\"")); return $@" {{ - 'dependencies': {{ + ""dependencies"": {{ {dependencies} }}, - 'frameworks': {{ - '{targetFramework}': {{ }} + ""frameworks"": {{ + ""{targetFramework}"": {{ }} }} }}"; } From 2c5e756277c2f7949a148f9438900497519f85fd Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Thu, 14 Dec 2023 13:20:48 -0800 Subject: [PATCH 13/20] even more quotes --- .../NetworkCallCountTest.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs index 9ced3e2f338..a04e6c73169 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs @@ -1553,23 +1553,23 @@ private void CreateMixedConfigAndJson(string workingPath) Util.CreateFile(proj3Dir, "project.json", @"{ - 'dependencies': { - 'packageD': '1.0.0', - 'packageE': '1.0.*' + ""dependencies"": { + ""packageD"": ""1.0.0"", + ""packageE"": ""1.0.*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); Util.CreateFile(proj4Dir, "project.json", @"{ - 'dependencies': { - 'packageE': '1.0.0', - 'packageF': '*' + ""dependencies"": { + ""packageE"": ""1.0.0"", + ""packageF"": ""*"" }, - 'frameworks': { - 'uap10.0': { } + ""frameworks"": { + ""uap10.0"": { } } }"); From 192ee52e51fccba3dc0857f4449a216bd2b3f06e Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Fri, 15 Dec 2023 11:05:30 -0800 Subject: [PATCH 14/20] quotes --- .../BuildIntegration/BuildIntegrationTestUtility.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/BuildIntegrationTestUtility.cs b/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/BuildIntegrationTestUtility.cs index 6e67ad8b44a..8547cdf1b75 100644 --- a/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/BuildIntegrationTestUtility.cs +++ b/test/NuGet.Core.Tests/NuGet.PackageManagement.Test/BuildIntegration/BuildIntegrationTestUtility.cs @@ -37,12 +37,12 @@ public static JObject BasicConfig } public const string ProjectJsonWithPackage = @"{ - 'dependencies': { - 'EntityFramework': '5.0.0' + ""dependencies"": { + ""EntityFramework"": ""5.0.0"" }, - 'frameworks': { - 'net46': { } - } + ""frameworks"": { + ""net46"": { } + } }"; public static ExternalProjectReference CreateReference(string name) From f1200e5ed9f50f93cdfdd2f08c0e8f25ffb130d2 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Fri, 15 Dec 2023 11:18:54 -0800 Subject: [PATCH 15/20] Move Newtson code back to main json package spec reader --- .../JsonPackageSpecReader.cs | 1768 ++++++++++++++++- .../LockFile/LockFileFormat.cs | 2 +- .../NuGet.ProjectModel/NjPackageSpecReader.cs | 1765 ---------------- .../JsonPackageSpecReaderTests.cs | 2 +- 4 files changed, 1767 insertions(+), 1770 deletions(-) delete mode 100644 src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index ba52052b5b0..15a7da29801 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -2,16 +2,27 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; +using System.Globalization; using System.IO; +using System.Linq; using System.Text; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NuGet.Common; +using NuGet.Configuration; +using NuGet.Frameworks; +using NuGet.LibraryModel; +using NuGet.Packaging.Core; +using NuGet.RuntimeModel; +using NuGet.Versioning; namespace NuGet.ProjectModel { public static class JsonPackageSpecReader { + private static readonly char[] DelimitedStringSeparators = { ' ', ',' }; + private static readonly char[] VersionSeparators = new[] { ';' }; public static readonly string RestoreOptions = "restore"; public static readonly string RestoreSettings = "restoreSettings"; public static readonly string HideWarningsAndErrors = "hideWarningsAndErrors"; @@ -54,14 +65,14 @@ public static PackageSpec GetPackageSpec(JObject rawPackageSpec, string name, st using (var stringReader = new StringReader(rawPackageSpec.ToString())) using (var jsonReader = new JsonTextReader(stringReader)) { - return NjPackageSpecReader.GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); + return GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); } } [Obsolete] internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string packageSpecPath) { - return NjPackageSpecReader.GetPackageSpec(jsonReader, packageSpecPath); + return GetPackageSpec(jsonReader, name: null, packageSpecPath, snapshotValue: null); } internal static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue, IEnvironmentVariableReader environmentVariableReader) @@ -77,10 +88,1761 @@ internal static PackageSpec GetPackageSpec(Stream stream, string name, string pa using (var jsonReader = new JsonTextReader(textReader)) { #pragma warning disable CS0612 // Type or member is obsolete - return NjPackageSpecReader.GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); + return GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); #pragma warning restore CS0612 // Type or member is obsolete } } } + + [Obsolete] + internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string name, string packageSpecPath, string snapshotValue) + { + var packageSpec = new PackageSpec(); + + List compatibilityProfiles = null; + List runtimeDescriptions = null; + var wasPackOptionsSet = false; + var isMappingsNull = false; + + string filePath = name == null ? null : Path.GetFullPath(packageSpecPath); + + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrWhiteSpace(propertyName)) + { + return; + } + + switch (propertyName) + { +#pragma warning disable CS0612 // Type or member is obsolete + case "authors": + packageSpec.Authors = ReadStringArray(jsonReader) ?? Array.Empty(); + break; + + case "buildOptions": + ReadBuildOptions(jsonReader, packageSpec); + break; + + case "contentFiles": + List contentFiles = jsonReader.ReadStringArrayAsList(); + + if (contentFiles != null) + { + packageSpec.ContentFiles = contentFiles; + } + break; + + case "copyright": + packageSpec.Copyright = jsonReader.ReadNextTokenAsString(); + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "dependencies": + ReadDependencies( + jsonReader, + packageSpec.Dependencies, + filePath, + isGacOrFrameworkReference: false); + break; + +#pragma warning disable CS0612 // Type or member is obsolete + case "description": + packageSpec.Description = jsonReader.ReadNextTokenAsString(); + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "frameworks": + ReadFrameworks(jsonReader, packageSpec); + break; + +#pragma warning disable CS0612 // Type or member is obsolete + case "language": + packageSpec.Language = jsonReader.ReadNextTokenAsString(); + break; + + case "packInclude": + ReadPackInclude(jsonReader, packageSpec); + break; + + case "packOptions": + ReadPackOptions(jsonReader, packageSpec, ref isMappingsNull); + wasPackOptionsSet = true; + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "restore": + ReadMSBuildMetadata(jsonReader, packageSpec); + break; + + case "runtimes": + runtimeDescriptions = ReadRuntimes(jsonReader); + break; + +#pragma warning disable CS0612 // Type or member is obsolete + case "scripts": + ReadScripts(jsonReader, packageSpec); + break; +#pragma warning restore CS0612 // Type or member is obsolete + + case "supports": + compatibilityProfiles = ReadSupports(jsonReader); + break; + + case "title": + packageSpec.Title = jsonReader.ReadNextTokenAsString(); + break; + + case "version": + string version = jsonReader.ReadAsString(); + + if (version != null) + { + try + { +#pragma warning disable CS0612 // Type or member is obsolete + packageSpec.HasVersionSnapshot = PackageSpecUtility.IsSnapshotVersion(version); +#pragma warning restore CS0612 // Type or member is obsolete + packageSpec.Version = PackageSpecUtility.SpecifySnapshot(version, snapshotValue); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, version, packageSpec.FilePath); + } + } + break; + } + }); + + packageSpec.Name = name; + packageSpec.FilePath = name == null ? null : Path.GetFullPath(packageSpecPath); + +#pragma warning disable CS0612 // Type or member is obsolete + if (!wasPackOptionsSet) + { + packageSpec.Owners = Array.Empty(); + packageSpec.PackOptions = new PackOptions() + { + PackageType = Array.Empty() + }; + packageSpec.Tags = Array.Empty(); + } + + if (isMappingsNull) + { + packageSpec.PackOptions.Mappings = null; + } +#pragma warning restore CS0612 // Type or member is obsolete + + packageSpec.RuntimeGraph = new RuntimeGraph( + runtimeDescriptions ?? Enumerable.Empty(), + compatibilityProfiles ?? Enumerable.Empty()); + + if (packageSpec.Name == null) + { + packageSpec.Name = packageSpec.RestoreMetadata?.ProjectName; + } + + // Use the project.json path if one is set, otherwise use the project path + if (packageSpec.FilePath == null) + { + packageSpec.FilePath = packageSpec.RestoreMetadata?.ProjectJsonPath + ?? packageSpec.RestoreMetadata?.ProjectPath; + } + + return packageSpec; + } + + [Obsolete] + internal static void ReadCentralTransitiveDependencyGroup( + JsonTextReader jsonReader, + IList results, + string packageSpecPath) + { + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrEmpty(propertyName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + if (jsonReader.ReadNextToken()) + { + int dependencyValueLine = jsonReader.LineNumber; + int dependencyValueColumn = jsonReader.LinePosition; + var versionLine = 0; + var versionColumn = 0; + + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + string dependencyVersionValue = null; + + if (jsonReader.TokenType == JsonToken.String) + { + dependencyVersionValue = (string)jsonReader.Value; + } + else if (jsonReader.TokenType == JsonToken.StartObject) + { + jsonReader.ReadProperties(dependenciesPropertyName => + { + IEnumerable values = null; + + switch (dependenciesPropertyName) + { + case "exclude": + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "include": + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "suppressParent": + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "version": + if (jsonReader.ReadNextToken()) + { + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + dependencyVersionValue = (string)jsonReader.Value; + } + break; + + default: + break; + } + }); + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + versionLine, + versionColumn, + packageSpecPath); + } + } + + if (dependencyVersionRange == null) + { + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + dependencyValueLine, + dependencyValueColumn, + packageSpecPath); + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = LibraryDependencyTarget.Package, + VersionRange = dependencyVersionRange + }, + + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + VersionCentrallyManaged = true, + ReferenceType = LibraryDependencyReferenceType.Transitive + }; + + results.Add(libraryDependency); + } + }); + } + + [Obsolete] + private static PackageType CreatePackageType(JsonTextReader jsonReader) + { + var name = (string)jsonReader.Value; + + return new PackageType(name, Packaging.Core.PackageType.EmptyVersion); + } + + [Obsolete] + private static void ReadBuildOptions(JsonTextReader jsonReader, PackageSpec packageSpec) + { + packageSpec.BuildOptions = new BuildOptions(); + + jsonReader.ReadObject(buildOptionsPropertyName => + { + if (buildOptionsPropertyName == "outputName") + { + packageSpec.BuildOptions.OutputName = jsonReader.ReadNextTokenAsString(); + } + }); + } + + [Obsolete] + private static void ReadCentralPackageVersions( + JsonTextReader jsonReader, + IDictionary centralPackageVersions, + string filePath) + { + jsonReader.ReadObject(propertyName => + { + int line = jsonReader.LineNumber; + int column = jsonReader.LinePosition; + + if (string.IsNullOrEmpty(propertyName)) + { + throw FileFormatException.Create( + "Unable to resolve central version ''.", + line, + column, + filePath); + } + + string version = jsonReader.ReadNextTokenAsString(); + + if (string.IsNullOrEmpty(version)) + { + throw FileFormatException.Create( + "The version cannot be null or empty.", + line, + column, + filePath); + } + + centralPackageVersions[propertyName] = new CentralPackageVersion(propertyName, VersionRange.Parse(version)); + }); + } + + [Obsolete] + private static CompatibilityProfile ReadCompatibilityProfile(JsonTextReader jsonReader, string profileName) + { + List sets = null; + + jsonReader.ReadObject(propertyName => + { + sets = sets ?? new List(); + + IEnumerable profiles = ReadCompatibilitySets(jsonReader, propertyName); + + sets.AddRange(profiles); + }); + + return new CompatibilityProfile(profileName, sets ?? Enumerable.Empty()); + } + + [Obsolete] + private static IEnumerable ReadCompatibilitySets(JsonTextReader jsonReader, string compatibilitySetName) + { + NuGetFramework framework = NuGetFramework.Parse(compatibilitySetName); + + IReadOnlyList values = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList() ?? Array.Empty(); + + foreach (string value in values) + { + yield return new FrameworkRuntimePair(framework, value); + } + } + + [Obsolete] + private static void ReadDependencies( + JsonTextReader jsonReader, + IList results, + string packageSpecPath, + bool isGacOrFrameworkReference) + { + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrEmpty(propertyName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + // Support + // "dependencies" : { + // "Name" : "1.0" + // } + + if (jsonReader.ReadNextToken()) + { + int dependencyValueLine = jsonReader.LineNumber; + int dependencyValueColumn = jsonReader.LinePosition; + var versionLine = 0; + var versionColumn = 0; + + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + List noWarn = null; + + // This method handles both the dependencies and framework assembly sections. + // Framework references should be limited to references. + // Dependencies should allow everything but framework references. + LibraryDependencyTarget targetFlagsValue = isGacOrFrameworkReference + ? LibraryDependencyTarget.Reference + : LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference; + + var autoReferenced = false; + var generatePathProperty = false; + var versionCentrallyManaged = false; + string aliases = null; + string dependencyVersionValue = null; + VersionRange versionOverride = null; + + if (jsonReader.TokenType == JsonToken.String) + { + dependencyVersionValue = (string)jsonReader.Value; + } + else if (jsonReader.TokenType == JsonToken.StartObject) + { + jsonReader.ReadProperties(dependenciesPropertyName => + { + IEnumerable values = null; + + switch (dependenciesPropertyName) + { + case "autoReferenced": + autoReferenced = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); + break; + + case "exclude": + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "generatePathProperty": + generatePathProperty = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); + break; + + case "include": + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "noWarn": + noWarn = ReadNuGetLogCodesList(jsonReader); + break; + + case "suppressParent": + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "target": + targetFlagsValue = ReadTarget(jsonReader, packageSpecPath, targetFlagsValue); + break; + + case "version": + if (jsonReader.ReadNextToken()) + { + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + + dependencyVersionValue = (string)jsonReader.Value; + } + break; + case "versionOverride": + if (jsonReader.ReadNextToken()) + { + try + { + versionOverride = VersionRange.Parse((string)jsonReader.Value); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + } + break; + case "versionCentrallyManaged": + versionCentrallyManaged = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); + break; + + case "aliases": + aliases = jsonReader.ReadAsString(); + break; + } + }); + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + versionLine, + versionColumn, + packageSpecPath); + } + } + + // Projects and References may have empty version ranges, Packages may not + if (dependencyVersionRange == null) + { + if ((targetFlagsValue & LibraryDependencyTarget.Package) == LibraryDependencyTarget.Package) + { + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + dependencyValueLine, + dependencyValueColumn, + packageSpecPath); + } + else + { + // Projects and references with no version property allow all versions + dependencyVersionRange = VersionRange.All; + } + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = targetFlagsValue, + VersionRange = dependencyVersionRange + }, + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + AutoReferenced = autoReferenced, + GeneratePathProperty = generatePathProperty, + VersionCentrallyManaged = versionCentrallyManaged, + Aliases = aliases, + // The ReferenceType is not persisted to the assets file + // Default to LibraryDependencyReferenceType.Direct on Read + ReferenceType = LibraryDependencyReferenceType.Direct, + VersionOverride = versionOverride + }; + + if (noWarn != null) + { + libraryDependency.NoWarn = noWarn; + } + + results.Add(libraryDependency); + } + }); + } + + [Obsolete] + private static void ReadDownloadDependencies( + JsonTextReader jsonReader, + IList downloadDependencies, + string packageSpecPath) + { + var seenIds = new HashSet(); + + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) + { + do + { + string name = null; + string versionValue = null; + var isNameDefined = false; + var isVersionDefined = false; + int line = jsonReader.LineNumber; + int column = jsonReader.LinePosition; + int versionLine = 0; + int versionColumn = 0; + + jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "name": + isNameDefined = true; + name = jsonReader.ReadNextTokenAsString(); + break; + + case "version": + isVersionDefined = true; + versionValue = jsonReader.ReadNextTokenAsString(); + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + break; + } + }, out line, out column); + + if (jsonReader.TokenType == JsonToken.EndArray) + { + break; + } + + if (!isNameDefined) + { + throw FileFormatException.Create( + "Unable to resolve downloadDependency ''.", + line, + column, + packageSpecPath); + } + + if (!seenIds.Add(name)) + { + // package ID already seen, only use first definition. + continue; + } + + if (string.IsNullOrEmpty(versionValue)) + { + throw FileFormatException.Create( + "The version cannot be null or empty", + isVersionDefined ? versionLine : line, + isVersionDefined ? versionColumn : column, + packageSpecPath); + } + + string[] versions = versionValue.Split(VersionSeparators, StringSplitOptions.RemoveEmptyEntries); + + foreach (string singleVersionValue in versions) + { + try + { + VersionRange version = VersionRange.Parse(singleVersionValue); + + downloadDependencies.Add(new DownloadDependency(name, version)); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + isVersionDefined ? versionLine : line, + isVersionDefined ? versionColumn : column, + packageSpecPath); + } + } + } while (jsonReader.TokenType == JsonToken.EndObject); + } + } + + [Obsolete] + private static IReadOnlyList ReadEnumerableOfString(JsonTextReader jsonReader) + { + string value = jsonReader.ReadNextTokenAsString(); + + return value.Split(DelimitedStringSeparators, StringSplitOptions.RemoveEmptyEntries); + } + + [Obsolete] + private static void ReadFrameworkReferences( + JsonTextReader jsonReader, + ISet frameworkReferences, + string packageSpecPath) + { + jsonReader.ReadObject(frameworkName => + { + if (string.IsNullOrEmpty(frameworkName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve frameworkReference.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + var privateAssets = FrameworkDependencyFlagsUtils.Default; + + jsonReader.ReadObject(propertyName => + { + if (propertyName == "privateAssets") + { + IEnumerable strings = ReadEnumerableOfString(jsonReader); + + privateAssets = FrameworkDependencyFlagsUtils.GetFlags(strings); + } + }); + + frameworkReferences.Add(new FrameworkDependency(frameworkName, privateAssets)); + }); + } + + [Obsolete] + private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packageSpec) + { + jsonReader.ReadObject(_ => + { + var frameworkLine = 0; + var frameworkColumn = 0; + + try + { + ReadTargetFrameworks(packageSpec, jsonReader, out frameworkLine, out frameworkColumn); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, frameworkLine, frameworkColumn, packageSpec.FilePath); + } + }); + } + + [Obsolete] + private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) + { + int lineNumber = jsonReader.LineNumber; + int linePosition = jsonReader.LinePosition; + + IReadOnlyList imports = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + + if (imports != null && imports.Count > 0) + { + foreach (string import in imports.Where(element => !string.IsNullOrEmpty(element))) + { + NuGetFramework framework = NuGetFramework.Parse(import); + + if (!framework.IsSpecificFramework) + { + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.Log_InvalidImportFramework, + import, + PackageSpec.PackageSpecFileName), + lineNumber, + linePosition, + packageSpec.FilePath); + } + + targetFrameworkInformation.Imports.Add(framework); + } + } + } + + [Obsolete] + private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, IDictionary mappings) + { + if (jsonReader.ReadNextToken()) + { + switch (jsonReader.TokenType) + { + case JsonToken.String: + { + var files = new IncludeExcludeFiles() + { + Include = new[] { (string)jsonReader.Value } + }; + + mappings.Add(mappingKey, files); + } + break; + + case JsonToken.StartArray: + { + IReadOnlyList include = jsonReader.ReadStringArrayAsReadOnlyListFromArrayStart(); + + var files = new IncludeExcludeFiles() + { + Include = include + }; + + mappings.Add(mappingKey, files); + } + break; + + case JsonToken.StartObject: + { + IReadOnlyList excludeFiles = null; + IReadOnlyList exclude = null; + IReadOnlyList includeFiles = null; + IReadOnlyList include = null; + + jsonReader.ReadProperties(filesPropertyName => + { + switch (filesPropertyName) + { + case "excludeFiles": + excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "exclude": + exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "includeFiles": + includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "include": + include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + } + }); + + if (include != null || includeFiles != null || exclude != null || excludeFiles != null) + { + var files = new IncludeExcludeFiles() + { + ExcludeFiles = excludeFiles, + Exclude = exclude, + IncludeFiles = includeFiles, + Include = include + }; + + mappings.Add(mappingKey, files); + } + } + break; + } + } + } + + [Obsolete] + private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec packageSpec) + { + var centralPackageVersionsManagementEnabled = false; + var centralPackageVersionOverrideDisabled = false; + var CentralPackageTransitivePinningEnabled = false; + List configFilePaths = null; + var crossTargeting = false; + List fallbackFolders = null; + List files = null; + var legacyPackagesDirectory = false; + ProjectRestoreMetadata msbuildMetadata = null; + List originalTargetFrameworks = null; + string outputPath = null; + string packagesConfigPath = null; + string packagesPath = null; + string projectJsonPath = null; + string projectName = null; + string projectPath = null; + ProjectStyle? projectStyle = null; + string projectUniqueName = null; + RestoreLockProperties restoreLockProperties = null; + var skipContentFileWrite = false; + List sources = null; + List targetFrameworks = null; + var validateRuntimeAssets = false; + WarningProperties warningProperties = null; + RestoreAuditProperties auditProperties = null; + + jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "centralPackageVersionsManagementEnabled": + centralPackageVersionsManagementEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "centralPackageVersionOverrideDisabled": + centralPackageVersionOverrideDisabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "CentralPackageTransitivePinningEnabled": + CentralPackageTransitivePinningEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "configFilePaths": + configFilePaths = jsonReader.ReadStringArrayAsList(); + break; + + case "crossTargeting": + crossTargeting = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "fallbackFolders": + fallbackFolders = jsonReader.ReadStringArrayAsList(); + break; + + case "files": + jsonReader.ReadObject(filePropertyName => + { + files = files ?? new List(); + + files.Add(new ProjectRestoreMetadataFile(filePropertyName, jsonReader.ReadNextTokenAsString())); + }); + break; + + case "frameworks": + targetFrameworks = ReadTargetFrameworks(jsonReader); + break; + + case "legacyPackagesDirectory": + legacyPackagesDirectory = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "originalTargetFrameworks": + originalTargetFrameworks = jsonReader.ReadStringArrayAsList(); + break; + + case "outputPath": + outputPath = jsonReader.ReadNextTokenAsString(); + break; + + case "packagesConfigPath": + packagesConfigPath = jsonReader.ReadNextTokenAsString(); + break; + + case "packagesPath": + packagesPath = jsonReader.ReadNextTokenAsString(); + break; + + case "projectJsonPath": + projectJsonPath = jsonReader.ReadNextTokenAsString(); + break; + + case "projectName": + projectName = jsonReader.ReadNextTokenAsString(); + break; + + case "projectPath": + projectPath = jsonReader.ReadNextTokenAsString(); + break; + + case "projectStyle": + string projectStyleString = jsonReader.ReadNextTokenAsString(); + + if (!string.IsNullOrEmpty(projectStyleString) + && Enum.TryParse(projectStyleString, ignoreCase: true, result: out ProjectStyle projectStyleValue)) + { + projectStyle = projectStyleValue; + } + break; + + case "projectUniqueName": + projectUniqueName = jsonReader.ReadNextTokenAsString(); + break; + + case "restoreLockProperties": + string nuGetLockFilePath = null; + var restoreLockedMode = false; + string restorePackagesWithLockFile = null; + + jsonReader.ReadObject(restoreLockPropertiesPropertyName => + { + switch (restoreLockPropertiesPropertyName) + { + case "nuGetLockFilePath": + nuGetLockFilePath = jsonReader.ReadNextTokenAsString(); + break; + + case "restoreLockedMode": + restoreLockedMode = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "restorePackagesWithLockFile": + restorePackagesWithLockFile = jsonReader.ReadNextTokenAsString(); + break; + } + }); + + restoreLockProperties = new RestoreLockProperties(restorePackagesWithLockFile, nuGetLockFilePath, restoreLockedMode); + break; + + case "restoreAuditProperties": + string enableAudit = null, auditLevel = null, auditMode = null; + jsonReader.ReadObject(auditPropertyName => + { + + switch (auditPropertyName) + { + case "enableAudit": + enableAudit = jsonReader.ReadNextTokenAsString(); + break; + + case "auditLevel": + auditLevel = jsonReader.ReadNextTokenAsString(); + break; + + case "auditMode": + auditMode = jsonReader.ReadNextTokenAsString(); + break; + } + }); + auditProperties = new RestoreAuditProperties() + { + EnableAudit = enableAudit, + AuditLevel = auditLevel, + AuditMode = auditMode, + }; + break; + + case "skipContentFileWrite": + skipContentFileWrite = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "sources": + jsonReader.ReadObject(sourcePropertyName => + { + sources = sources ?? new List(); + + sources.Add(new PackageSource(sourcePropertyName)); + }); + break; + + case "validateRuntimeAssets": + validateRuntimeAssets = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "warningProperties": + var allWarningsAsErrors = false; + var noWarn = new HashSet(); + var warnAsError = new HashSet(); + var warningsNotAsErrors = new HashSet(); + + jsonReader.ReadObject(warningPropertiesPropertyName => + { + switch (warningPropertiesPropertyName) + { + case "allWarningsAsErrors": + allWarningsAsErrors = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "noWarn": + ReadNuGetLogCodes(jsonReader, noWarn); + break; + + case "warnAsError": + ReadNuGetLogCodes(jsonReader, warnAsError); + break; + + case "warnNotAsError": + ReadNuGetLogCodes(jsonReader, warningsNotAsErrors); + break; + } + }); + + warningProperties = new WarningProperties(warnAsError, noWarn, allWarningsAsErrors, warningsNotAsErrors); + break; + } + }); + + if (projectStyle == ProjectStyle.PackagesConfig) + { + msbuildMetadata = new PackagesConfigProjectRestoreMetadata() + { + PackagesConfigPath = packagesConfigPath + }; + } + else + { + msbuildMetadata = new ProjectRestoreMetadata(); + } + + msbuildMetadata.CentralPackageVersionsEnabled = centralPackageVersionsManagementEnabled; + msbuildMetadata.CentralPackageVersionOverrideDisabled = centralPackageVersionOverrideDisabled; + msbuildMetadata.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; + msbuildMetadata.RestoreAuditProperties = auditProperties; + + if (configFilePaths != null) + { + msbuildMetadata.ConfigFilePaths = configFilePaths; + } + + msbuildMetadata.CrossTargeting = crossTargeting; + + if (fallbackFolders != null) + { + msbuildMetadata.FallbackFolders = fallbackFolders; + } + + if (files != null) + { + msbuildMetadata.Files = files; + } + + msbuildMetadata.LegacyPackagesDirectory = legacyPackagesDirectory; + + if (originalTargetFrameworks != null) + { + msbuildMetadata.OriginalTargetFrameworks = originalTargetFrameworks; + } + + msbuildMetadata.OutputPath = outputPath; + msbuildMetadata.PackagesPath = packagesPath; + msbuildMetadata.ProjectJsonPath = projectJsonPath; + msbuildMetadata.ProjectName = projectName; + msbuildMetadata.ProjectPath = projectPath; + + if (projectStyle.HasValue) + { + msbuildMetadata.ProjectStyle = projectStyle.Value; + } + + msbuildMetadata.ProjectUniqueName = projectUniqueName; + + if (restoreLockProperties != null) + { + msbuildMetadata.RestoreLockProperties = restoreLockProperties; + } + + msbuildMetadata.SkipContentFileWrite = skipContentFileWrite; + + if (sources != null) + { + msbuildMetadata.Sources = sources; + } + + if (targetFrameworks != null) + { + msbuildMetadata.TargetFrameworks = targetFrameworks; + } + + msbuildMetadata.ValidateRuntimeAssets = validateRuntimeAssets; + + if (warningProperties != null) + { + msbuildMetadata.ProjectWideWarningProperties = warningProperties; + } + + packageSpec.RestoreMetadata = msbuildMetadata; + } + + [Obsolete] + private static bool ReadNextTokenAsBoolOrFalse(JsonTextReader jsonReader, string filePath) + { + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.Boolean) + { + try + { + return (bool)jsonReader.Value; + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, jsonReader.LineNumber, jsonReader.LinePosition, filePath); + } + } + + return false; + } + + [Obsolete] + private static void ReadNuGetLogCodes(JsonTextReader jsonReader, HashSet hashCodes) + { + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) + { + while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) + { + if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) + { + hashCodes.Add(code); + } + } + } + } + + [Obsolete] + private static List ReadNuGetLogCodesList(JsonTextReader jsonReader) + { + List items = null; + + if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) + { + while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) + { + if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) + { + items = items ?? new List(); + + items.Add(code); + } + } + } + + return items; + } + + [Obsolete] + private static void ReadPackageTypes(PackageSpec packageSpec, JsonTextReader jsonReader) + { + var errorLine = 0; + var errorColumn = 0; + + IReadOnlyList packageTypes = null; + PackageType packageType = null; + + try + { + if (jsonReader.ReadNextToken()) + { + errorLine = jsonReader.LineNumber; + errorColumn = jsonReader.LinePosition; + + switch (jsonReader.TokenType) + { + case JsonToken.String: + packageType = CreatePackageType(jsonReader); + + packageTypes = new[] { packageType }; + break; + + case JsonToken.StartArray: + var types = new List(); + + while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) + { + if (jsonReader.TokenType != JsonToken.String) + { + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName), + errorLine, + errorColumn, + packageSpec.FilePath); + } + + packageType = CreatePackageType(jsonReader); + + types.Add(packageType); + } + + packageTypes = types; + break; + + case JsonToken.Null: + break; + + default: + throw new InvalidCastException(); + } + +#pragma warning disable CS0612 // Type or member is obsolete + if (packageTypes != null) + { + packageSpec.PackOptions.PackageType = packageTypes; + } +#pragma warning restore CS0612 // Type or member is obsolete + } + } + catch (Exception) + { + throw FileFormatException.Create( + string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidPackageType, + PackageSpec.PackageSpecFileName), + errorLine, + errorColumn, + packageSpec.FilePath); + } + } + + [Obsolete] + private static void ReadPackInclude(JsonTextReader jsonReader, PackageSpec packageSpec) + { + jsonReader.ReadObject(propertyName => + { + string propertyValue = jsonReader.ReadAsString(); + + packageSpec.PackInclude.Add(new KeyValuePair(propertyName, propertyValue)); + }); + } + + [Obsolete] + private static void ReadPackOptions(JsonTextReader jsonReader, PackageSpec packageSpec, ref bool isMappingsNull) + { + var wasMappingsRead = false; + + bool isPackOptionsValueAnObject = jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "files": + wasMappingsRead = ReadPackOptionsFiles(packageSpec, jsonReader, wasMappingsRead); + break; + + case "iconUrl": + packageSpec.IconUrl = jsonReader.ReadNextTokenAsString(); + break; + + case "licenseUrl": + packageSpec.LicenseUrl = jsonReader.ReadNextTokenAsString(); + break; + + case "owners": + string[] owners = ReadStringArray(jsonReader); + + if (owners != null) + { + packageSpec.Owners = owners; + } + break; + + case "packageType": + ReadPackageTypes(packageSpec, jsonReader); + break; + + case "projectUrl": + packageSpec.ProjectUrl = jsonReader.ReadNextTokenAsString(); + break; + + case "releaseNotes": + packageSpec.ReleaseNotes = jsonReader.ReadNextTokenAsString(); + break; + + case "requireLicenseAcceptance": + packageSpec.RequireLicenseAcceptance = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "summary": + packageSpec.Summary = jsonReader.ReadNextTokenAsString(); + break; + + case "tags": + string[] tags = ReadStringArray(jsonReader); + + if (tags != null) + { + packageSpec.Tags = tags; + } + break; + } + }); + + isMappingsNull = isPackOptionsValueAnObject && !wasMappingsRead; + } + + [Obsolete] + private static bool ReadPackOptionsFiles(PackageSpec packageSpec, JsonTextReader jsonReader, bool wasMappingsRead) + { + IReadOnlyList excludeFiles = null; + IReadOnlyList exclude = null; + IReadOnlyList includeFiles = null; + IReadOnlyList include = null; + + jsonReader.ReadObject(filesPropertyName => + { + switch (filesPropertyName) + { + case "excludeFiles": + excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "exclude": + exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "includeFiles": + includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "include": + include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); + break; + + case "mappings": + jsonReader.ReadObject(mappingsPropertyName => + { + wasMappingsRead = true; + + ReadMappings(jsonReader, mappingsPropertyName, packageSpec.PackOptions.Mappings); + }); + break; + } + }); + + if (include != null || includeFiles != null || exclude != null || excludeFiles != null) + { + packageSpec.PackOptions.IncludeExcludeFiles = new IncludeExcludeFiles() + { + ExcludeFiles = excludeFiles, + Exclude = exclude, + IncludeFiles = includeFiles, + Include = include + }; + } + + return wasMappingsRead; + } + + [Obsolete] + static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader jsonReader, string dependencySetName) + { + List dependencies = null; + + jsonReader.ReadObject(propertyName => + { + dependencies ??= new List(); + + var dependency = new RuntimePackageDependency(propertyName, VersionRange.Parse(jsonReader.ReadNextTokenAsString())); + + dependencies.Add(dependency); + }); + + return new RuntimeDependencySet( + dependencySetName, + dependencies); + } + + [Obsolete] + private static RuntimeDescription ReadRuntimeDescription(JsonTextReader jsonReader, string runtimeName) + { + List inheritedRuntimes = null; + List additionalDependencies = null; + + jsonReader.ReadObject(propertyName => + { + if (propertyName == "#import") + { + inheritedRuntimes = jsonReader.ReadStringArrayAsList(); + } + else + { + additionalDependencies ??= new List(); + + RuntimeDependencySet dependency = ReadRuntimeDependencySet(jsonReader, propertyName); + + additionalDependencies.Add(dependency); + } + }); + + return new RuntimeDescription( + runtimeName, + inheritedRuntimes, + additionalDependencies); + } + + [Obsolete] + private static List ReadRuntimes(JsonTextReader jsonReader) + { + var runtimeDescriptions = new List(); + + jsonReader.ReadObject(propertyName => + { + RuntimeDescription runtimeDescription = ReadRuntimeDescription(jsonReader, propertyName); + + runtimeDescriptions.Add(runtimeDescription); + }); + + return runtimeDescriptions; + } + + [Obsolete] + private static void ReadScripts(JsonTextReader jsonReader, PackageSpec packageSpec) + { + jsonReader.ReadObject(propertyName => + { + if (jsonReader.ReadNextToken()) + { + if (jsonReader.TokenType == JsonToken.String) + { + packageSpec.Scripts[propertyName] = new string[] { (string)jsonReader.Value }; + } + else if (jsonReader.TokenType == JsonToken.StartArray) + { + var list = new List(); + + while (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.String) + { + list.Add((string)jsonReader.Value); + } + + packageSpec.Scripts[propertyName] = list; + } + else + { + throw FileFormatException.Create( + string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName), + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpec.FilePath); + } + } + }); + } + + [Obsolete] + private static string[] ReadStringArray(JsonTextReader jsonReader) + { + List list = jsonReader.ReadStringArrayAsList(); + + return list?.ToArray(); + } + + [Obsolete] + private static List ReadSupports(JsonTextReader jsonReader) + { + var compatibilityProfiles = new List(); + + jsonReader.ReadObject(propertyName => + { + CompatibilityProfile compatibilityProfile = ReadCompatibilityProfile(jsonReader, propertyName); + + compatibilityProfiles.Add(compatibilityProfile); + }); + + return compatibilityProfiles; + } + + [Obsolete] + private static LibraryDependencyTarget ReadTarget( + JsonTextReader jsonReader, + string packageSpecPath, + LibraryDependencyTarget targetFlagsValue) + { + if (jsonReader.ReadNextToken()) + { + var targetString = (string)jsonReader.Value; + + targetFlagsValue = LibraryDependencyTargetUtils.Parse(targetString); + + // Verify that the value specified is package, project, or external project + if (!ValidateDependencyTarget(targetFlagsValue)) + { + string message = string.Format( + CultureInfo.CurrentCulture, + Strings.InvalidDependencyTarget, + targetString); + + throw FileFormatException.Create( + message, + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + } + + return targetFlagsValue; + } + + [Obsolete] + private static List ReadTargetFrameworks(JsonTextReader jsonReader) + { + var targetFrameworks = new List(); + + jsonReader.ReadObject(frameworkPropertyName => + { + NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); + var frameworkGroup = new ProjectRestoreMetadataFrameworkInfo(framework); + + jsonReader.ReadObject(propertyName => + { + if (propertyName == "projectReferences") + { + jsonReader.ReadObject(projectReferencePropertyName => + { + string excludeAssets = null; + string includeAssets = null; + string privateAssets = null; + string projectReferenceProjectPath = null; + + jsonReader.ReadObject(projectReferenceObjectPropertyName => + { + switch (projectReferenceObjectPropertyName) + { + case "excludeAssets": + excludeAssets = jsonReader.ReadNextTokenAsString(); + break; + + case "includeAssets": + includeAssets = jsonReader.ReadNextTokenAsString(); + break; + + case "privateAssets": + privateAssets = jsonReader.ReadNextTokenAsString(); + break; + + case "projectPath": + projectReferenceProjectPath = jsonReader.ReadNextTokenAsString(); + break; + } + }); + + frameworkGroup.ProjectReferences.Add(new ProjectRestoreReference() + { + ProjectUniqueName = projectReferencePropertyName, + ProjectPath = projectReferenceProjectPath, + + IncludeAssets = LibraryIncludeFlagUtils.GetFlags( + flags: includeAssets, + defaultFlags: LibraryIncludeFlags.All), + + ExcludeAssets = LibraryIncludeFlagUtils.GetFlags( + flags: excludeAssets, + defaultFlags: LibraryIncludeFlags.None), + + PrivateAssets = LibraryIncludeFlagUtils.GetFlags( + flags: privateAssets, + defaultFlags: LibraryIncludeFlagUtils.DefaultSuppressParent), + }); + }); + } + else if (propertyName == "targetAlias") + { + frameworkGroup.TargetAlias = jsonReader.ReadNextTokenAsString(); + } + }); + + targetFrameworks.Add(frameworkGroup); + }); + + return targetFrameworks; + } + + [Obsolete] + private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader jsonReader, out int frameworkLine, out int frameworkColumn) + { + frameworkLine = 0; + frameworkColumn = 0; + + NuGetFramework frameworkName = NuGetFramework.Parse((string)jsonReader.Value); + + var targetFrameworkInformation = new TargetFrameworkInformation(); + NuGetFramework secondaryFramework = default; + jsonReader.ReadObject(propertyName => + { + switch (propertyName) + { + case "assetTargetFallback": + targetFrameworkInformation.AssetTargetFallback = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + + case "secondaryFramework": + var secondaryFrameworkString = jsonReader.ReadAsString(); + if (!string.IsNullOrEmpty(secondaryFrameworkString)) + { + secondaryFramework = NuGetFramework.Parse(secondaryFrameworkString); + } + break; + + case "centralPackageVersions": + ReadCentralPackageVersions( + jsonReader, + targetFrameworkInformation.CentralPackageVersions, + packageSpec.FilePath); + break; + + case "dependencies": + ReadDependencies( + jsonReader, + targetFrameworkInformation.Dependencies, + packageSpec.FilePath, + isGacOrFrameworkReference: false); + break; + + case "downloadDependencies": + ReadDownloadDependencies( + jsonReader, + targetFrameworkInformation.DownloadDependencies, + packageSpec.FilePath); + break; + + case "frameworkAssemblies": + ReadDependencies( + jsonReader, + targetFrameworkInformation.Dependencies, + packageSpec.FilePath, + isGacOrFrameworkReference: true); + break; + + case "frameworkReferences": + ReadFrameworkReferences( + jsonReader, + targetFrameworkInformation.FrameworkReferences, + packageSpec.FilePath); + break; + + case "imports": + ReadImports(packageSpec, jsonReader, targetFrameworkInformation); + break; + + case "runtimeIdentifierGraphPath": + targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); + break; + + case "targetAlias": + targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); + break; + + case "warn": + targetFrameworkInformation.Warn = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); + break; + } + }, out frameworkLine, out frameworkColumn); + + NuGetFramework updatedFramework = frameworkName; + + if (targetFrameworkInformation.Imports.Count > 0) + { + NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); + + if (targetFrameworkInformation.AssetTargetFallback) + { + updatedFramework = new AssetTargetFallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); + } + else + { + updatedFramework = new FallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); + } + } + else + { + updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); + } + + targetFrameworkInformation.FrameworkName = updatedFramework; + + packageSpec.TargetFrameworks.Add(targetFrameworkInformation); + } + + [Obsolete] + private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) + { + if (secondaryFramework != default) + { + return new DualCompatibilityFramework(frameworkName, secondaryFramework); + } + + return frameworkName; + } + + [Obsolete] + private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue) + { + var isValid = false; + + switch (targetValue) + { + case LibraryDependencyTarget.Package: + case LibraryDependencyTarget.Project: + case LibraryDependencyTarget.ExternalProject: + isValid = true; + break; + } + + return isValid; + } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs index b33a2cb1bcd..f40c498518b 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/LockFile/LockFileFormat.cs @@ -938,7 +938,7 @@ private static List ReadProjectFileTransitiveD NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); var dependencies = new List(); - NjPackageSpecReader.ReadCentralTransitiveDependencyGroup( + JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( jsonReader: jsonReader, results: dependencies, packageSpecPath: path); diff --git a/src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs deleted file mode 100644 index 9df79f0fe08..00000000000 --- a/src/NuGet.Core/NuGet.ProjectModel/NjPackageSpecReader.cs +++ /dev/null @@ -1,1765 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using Newtonsoft.Json; -using NuGet.Common; -using NuGet.Configuration; -using NuGet.Frameworks; -using NuGet.LibraryModel; -using NuGet.Packaging.Core; -using NuGet.RuntimeModel; -using NuGet.Versioning; - -namespace NuGet.ProjectModel -{ - [Obsolete] - internal static class NjPackageSpecReader - { - private static readonly char[] DelimitedStringSeparators = { ' ', ',' }; - private static readonly char[] VersionSeparators = new[] { ';' }; - - internal static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, string snapshotValue = null) - { - using (var stringReader = new StringReader(json)) - using (var jsonReader = new JsonTextReader(stringReader)) - { - return GetPackageSpec(jsonReader, name, packageSpecPath, snapshotValue); - } - } - - internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string packageSpecPath) - { - return GetPackageSpec(jsonReader, name: null, packageSpecPath, snapshotValue: null); - } - - internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string name, string packageSpecPath, string snapshotValue) - { - var packageSpec = new PackageSpec(); - - List compatibilityProfiles = null; - List runtimeDescriptions = null; - var wasPackOptionsSet = false; - var isMappingsNull = false; - - string filePath = name == null ? null : Path.GetFullPath(packageSpecPath); - - jsonReader.ReadObject(propertyName => - { - if (string.IsNullOrWhiteSpace(propertyName)) - { - return; - } - - switch (propertyName) - { -#pragma warning disable CS0612 // Type or member is obsolete - case "authors": - packageSpec.Authors = ReadStringArray(jsonReader) ?? Array.Empty(); - break; - - case "buildOptions": - ReadBuildOptions(jsonReader, packageSpec); - break; - - case "contentFiles": - List contentFiles = jsonReader.ReadStringArrayAsList(); - - if (contentFiles != null) - { - packageSpec.ContentFiles = contentFiles; - } - break; - - case "copyright": - packageSpec.Copyright = jsonReader.ReadNextTokenAsString(); - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "dependencies": - ReadDependencies( - jsonReader, - packageSpec.Dependencies, - filePath, - isGacOrFrameworkReference: false); - break; - -#pragma warning disable CS0612 // Type or member is obsolete - case "description": - packageSpec.Description = jsonReader.ReadNextTokenAsString(); - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "frameworks": - ReadFrameworks(jsonReader, packageSpec); - break; - -#pragma warning disable CS0612 // Type or member is obsolete - case "language": - packageSpec.Language = jsonReader.ReadNextTokenAsString(); - break; - - case "packInclude": - ReadPackInclude(jsonReader, packageSpec); - break; - - case "packOptions": - ReadPackOptions(jsonReader, packageSpec, ref isMappingsNull); - wasPackOptionsSet = true; - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "restore": - ReadMSBuildMetadata(jsonReader, packageSpec); - break; - - case "runtimes": - runtimeDescriptions = ReadRuntimes(jsonReader); - break; - -#pragma warning disable CS0612 // Type or member is obsolete - case "scripts": - ReadScripts(jsonReader, packageSpec); - break; -#pragma warning restore CS0612 // Type or member is obsolete - - case "supports": - compatibilityProfiles = ReadSupports(jsonReader); - break; - - case "title": - packageSpec.Title = jsonReader.ReadNextTokenAsString(); - break; - - case "version": - string version = jsonReader.ReadAsString(); - - if (version != null) - { - try - { -#pragma warning disable CS0612 // Type or member is obsolete - packageSpec.HasVersionSnapshot = PackageSpecUtility.IsSnapshotVersion(version); -#pragma warning restore CS0612 // Type or member is obsolete - packageSpec.Version = PackageSpecUtility.SpecifySnapshot(version, snapshotValue); - } - catch (Exception ex) - { - throw FileFormatException.Create(ex, version, packageSpec.FilePath); - } - } - break; - } - }); - - packageSpec.Name = name; - packageSpec.FilePath = name == null ? null : Path.GetFullPath(packageSpecPath); - -#pragma warning disable CS0612 // Type or member is obsolete - if (!wasPackOptionsSet) - { - packageSpec.Owners = Array.Empty(); - packageSpec.PackOptions = new PackOptions() - { - PackageType = Array.Empty() - }; - packageSpec.Tags = Array.Empty(); - } - - if (isMappingsNull) - { - packageSpec.PackOptions.Mappings = null; - } -#pragma warning restore CS0612 // Type or member is obsolete - - packageSpec.RuntimeGraph = new RuntimeGraph( - runtimeDescriptions ?? Enumerable.Empty(), - compatibilityProfiles ?? Enumerable.Empty()); - - if (packageSpec.Name == null) - { - packageSpec.Name = packageSpec.RestoreMetadata?.ProjectName; - } - - // Use the project.json path if one is set, otherwise use the project path - if (packageSpec.FilePath == null) - { - packageSpec.FilePath = packageSpec.RestoreMetadata?.ProjectJsonPath - ?? packageSpec.RestoreMetadata?.ProjectPath; - } - - return packageSpec; - } - - - internal static void ReadCentralTransitiveDependencyGroup( - JsonTextReader jsonReader, - IList results, - string packageSpecPath) - { - jsonReader.ReadObject(propertyName => - { - if (string.IsNullOrEmpty(propertyName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve dependency ''.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - - if (jsonReader.ReadNextToken()) - { - int dependencyValueLine = jsonReader.LineNumber; - int dependencyValueColumn = jsonReader.LinePosition; - var versionLine = 0; - var versionColumn = 0; - - var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; - var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; - var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - string dependencyVersionValue = null; - - if (jsonReader.TokenType == JsonToken.String) - { - dependencyVersionValue = (string)jsonReader.Value; - } - else if (jsonReader.TokenType == JsonToken.StartObject) - { - jsonReader.ReadProperties(dependenciesPropertyName => - { - IEnumerable values = null; - - switch (dependenciesPropertyName) - { - case "exclude": - values = jsonReader.ReadDelimitedString(); - dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "include": - values = jsonReader.ReadDelimitedString(); - dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "suppressParent": - values = jsonReader.ReadDelimitedString(); - suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "version": - if (jsonReader.ReadNextToken()) - { - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - dependencyVersionValue = (string)jsonReader.Value; - } - break; - - default: - break; - } - }); - } - - VersionRange dependencyVersionRange = null; - - if (!string.IsNullOrEmpty(dependencyVersionValue)) - { - try - { - dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - versionLine, - versionColumn, - packageSpecPath); - } - } - - if (dependencyVersionRange == null) - { - throw FileFormatException.Create( - new ArgumentException(Strings.MissingVersionOnDependency), - dependencyValueLine, - dependencyValueColumn, - packageSpecPath); - } - - // the dependency flags are: Include flags - Exclude flags - var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency() - { - LibraryRange = new LibraryRange() - { - Name = propertyName, - TypeConstraint = LibraryDependencyTarget.Package, - VersionRange = dependencyVersionRange - }, - - IncludeType = includeFlags, - SuppressParent = suppressParentFlagsValue, - VersionCentrallyManaged = true, - ReferenceType = LibraryDependencyReferenceType.Transitive - }; - - results.Add(libraryDependency); - } - }); - } - - - private static PackageType CreatePackageType(JsonTextReader jsonReader) - { - var name = (string)jsonReader.Value; - - return new PackageType(name, Packaging.Core.PackageType.EmptyVersion); - } - - [Obsolete] - private static void ReadBuildOptions(JsonTextReader jsonReader, PackageSpec packageSpec) - { - packageSpec.BuildOptions = new BuildOptions(); - - jsonReader.ReadObject(buildOptionsPropertyName => - { - if (buildOptionsPropertyName == "outputName") - { - packageSpec.BuildOptions.OutputName = jsonReader.ReadNextTokenAsString(); - } - }); - } - - private static void ReadCentralPackageVersions( - JsonTextReader jsonReader, - IDictionary centralPackageVersions, - string filePath) - { - jsonReader.ReadObject(propertyName => - { - int line = jsonReader.LineNumber; - int column = jsonReader.LinePosition; - - if (string.IsNullOrEmpty(propertyName)) - { - throw FileFormatException.Create( - "Unable to resolve central version ''.", - line, - column, - filePath); - } - - string version = jsonReader.ReadNextTokenAsString(); - - if (string.IsNullOrEmpty(version)) - { - throw FileFormatException.Create( - "The version cannot be null or empty.", - line, - column, - filePath); - } - - centralPackageVersions[propertyName] = new CentralPackageVersion(propertyName, VersionRange.Parse(version)); - }); - } - - private static CompatibilityProfile ReadCompatibilityProfile(JsonTextReader jsonReader, string profileName) - { - List sets = null; - - jsonReader.ReadObject(propertyName => - { - sets = sets ?? new List(); - - IEnumerable profiles = ReadCompatibilitySets(jsonReader, propertyName); - - sets.AddRange(profiles); - }); - - return new CompatibilityProfile(profileName, sets ?? Enumerable.Empty()); - } - - private static IEnumerable ReadCompatibilitySets(JsonTextReader jsonReader, string compatibilitySetName) - { - NuGetFramework framework = NuGetFramework.Parse(compatibilitySetName); - - IReadOnlyList values = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList() ?? Array.Empty(); - - foreach (string value in values) - { - yield return new FrameworkRuntimePair(framework, value); - } - } - - private static void ReadDependencies( - JsonTextReader jsonReader, - IList results, - string packageSpecPath, - bool isGacOrFrameworkReference) - { - jsonReader.ReadObject(propertyName => - { - if (string.IsNullOrEmpty(propertyName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve dependency ''.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - - // Support - // "dependencies" : { - // "Name" : "1.0" - // } - - if (jsonReader.ReadNextToken()) - { - int dependencyValueLine = jsonReader.LineNumber; - int dependencyValueColumn = jsonReader.LinePosition; - var versionLine = 0; - var versionColumn = 0; - - var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; - var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; - var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - List noWarn = null; - - // This method handles both the dependencies and framework assembly sections. - // Framework references should be limited to references. - // Dependencies should allow everything but framework references. - LibraryDependencyTarget targetFlagsValue = isGacOrFrameworkReference - ? LibraryDependencyTarget.Reference - : LibraryDependencyTarget.All & ~LibraryDependencyTarget.Reference; - - var autoReferenced = false; - var generatePathProperty = false; - var versionCentrallyManaged = false; - string aliases = null; - string dependencyVersionValue = null; - VersionRange versionOverride = null; - - if (jsonReader.TokenType == JsonToken.String) - { - dependencyVersionValue = (string)jsonReader.Value; - } - else if (jsonReader.TokenType == JsonToken.StartObject) - { - jsonReader.ReadProperties(dependenciesPropertyName => - { - IEnumerable values = null; - - switch (dependenciesPropertyName) - { - case "autoReferenced": - autoReferenced = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); - break; - - case "exclude": - values = jsonReader.ReadDelimitedString(); - dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "generatePathProperty": - generatePathProperty = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); - break; - - case "include": - values = jsonReader.ReadDelimitedString(); - dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "noWarn": - noWarn = ReadNuGetLogCodesList(jsonReader); - break; - - case "suppressParent": - values = jsonReader.ReadDelimitedString(); - suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "target": - targetFlagsValue = ReadTarget(jsonReader, packageSpecPath, targetFlagsValue); - break; - - case "version": - if (jsonReader.ReadNextToken()) - { - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - - dependencyVersionValue = (string)jsonReader.Value; - } - break; - case "versionOverride": - if (jsonReader.ReadNextToken()) - { - try - { - versionOverride = VersionRange.Parse((string)jsonReader.Value); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - } - break; - case "versionCentrallyManaged": - versionCentrallyManaged = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpecPath); - break; - - case "aliases": - aliases = jsonReader.ReadAsString(); - break; - } - }); - } - - VersionRange dependencyVersionRange = null; - - if (!string.IsNullOrEmpty(dependencyVersionValue)) - { - try - { - dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - versionLine, - versionColumn, - packageSpecPath); - } - } - - // Projects and References may have empty version ranges, Packages may not - if (dependencyVersionRange == null) - { - if ((targetFlagsValue & LibraryDependencyTarget.Package) == LibraryDependencyTarget.Package) - { - throw FileFormatException.Create( - new ArgumentException(Strings.MissingVersionOnDependency), - dependencyValueLine, - dependencyValueColumn, - packageSpecPath); - } - else - { - // Projects and references with no version property allow all versions - dependencyVersionRange = VersionRange.All; - } - } - - // the dependency flags are: Include flags - Exclude flags - var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency() - { - LibraryRange = new LibraryRange() - { - Name = propertyName, - TypeConstraint = targetFlagsValue, - VersionRange = dependencyVersionRange - }, - IncludeType = includeFlags, - SuppressParent = suppressParentFlagsValue, - AutoReferenced = autoReferenced, - GeneratePathProperty = generatePathProperty, - VersionCentrallyManaged = versionCentrallyManaged, - Aliases = aliases, - // The ReferenceType is not persisted to the assets file - // Default to LibraryDependencyReferenceType.Direct on Read - ReferenceType = LibraryDependencyReferenceType.Direct, - VersionOverride = versionOverride - }; - - if (noWarn != null) - { - libraryDependency.NoWarn = noWarn; - } - - results.Add(libraryDependency); - } - }); - } - - private static void ReadDownloadDependencies( - JsonTextReader jsonReader, - IList downloadDependencies, - string packageSpecPath) - { - var seenIds = new HashSet(); - - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) - { - do - { - string name = null; - string versionValue = null; - var isNameDefined = false; - var isVersionDefined = false; - int line = jsonReader.LineNumber; - int column = jsonReader.LinePosition; - int versionLine = 0; - int versionColumn = 0; - - jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "name": - isNameDefined = true; - name = jsonReader.ReadNextTokenAsString(); - break; - - case "version": - isVersionDefined = true; - versionValue = jsonReader.ReadNextTokenAsString(); - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - break; - } - }, out line, out column); - - if (jsonReader.TokenType == JsonToken.EndArray) - { - break; - } - - if (!isNameDefined) - { - throw FileFormatException.Create( - "Unable to resolve downloadDependency ''.", - line, - column, - packageSpecPath); - } - - if (!seenIds.Add(name)) - { - // package ID already seen, only use first definition. - continue; - } - - if (string.IsNullOrEmpty(versionValue)) - { - throw FileFormatException.Create( - "The version cannot be null or empty", - isVersionDefined ? versionLine : line, - isVersionDefined ? versionColumn : column, - packageSpecPath); - } - - string[] versions = versionValue.Split(VersionSeparators, StringSplitOptions.RemoveEmptyEntries); - - foreach (string singleVersionValue in versions) - { - try - { - VersionRange version = VersionRange.Parse(singleVersionValue); - - downloadDependencies.Add(new DownloadDependency(name, version)); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - isVersionDefined ? versionLine : line, - isVersionDefined ? versionColumn : column, - packageSpecPath); - } - } - } while (jsonReader.TokenType == JsonToken.EndObject); - } - } - - private static IReadOnlyList ReadEnumerableOfString(JsonTextReader jsonReader) - { - string value = jsonReader.ReadNextTokenAsString(); - - return value.Split(DelimitedStringSeparators, StringSplitOptions.RemoveEmptyEntries); - } - - private static void ReadFrameworkReferences( - JsonTextReader jsonReader, - ISet frameworkReferences, - string packageSpecPath) - { - jsonReader.ReadObject(frameworkName => - { - if (string.IsNullOrEmpty(frameworkName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve frameworkReference.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - - var privateAssets = FrameworkDependencyFlagsUtils.Default; - - jsonReader.ReadObject(propertyName => - { - if (propertyName == "privateAssets") - { - IEnumerable strings = ReadEnumerableOfString(jsonReader); - - privateAssets = FrameworkDependencyFlagsUtils.GetFlags(strings); - } - }); - - frameworkReferences.Add(new FrameworkDependency(frameworkName, privateAssets)); - }); - } - - private static void ReadFrameworks(JsonTextReader jsonReader, PackageSpec packageSpec) - { - jsonReader.ReadObject(_ => - { - var frameworkLine = 0; - var frameworkColumn = 0; - - try - { - ReadTargetFrameworks(packageSpec, jsonReader, out frameworkLine, out frameworkColumn); - } - catch (Exception ex) - { - throw FileFormatException.Create(ex, frameworkLine, frameworkColumn, packageSpec.FilePath); - } - }); - } - - private static void ReadImports(PackageSpec packageSpec, JsonTextReader jsonReader, TargetFrameworkInformation targetFrameworkInformation) - { - int lineNumber = jsonReader.LineNumber; - int linePosition = jsonReader.LinePosition; - - IReadOnlyList imports = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - - if (imports != null && imports.Count > 0) - { - foreach (string import in imports.Where(element => !string.IsNullOrEmpty(element))) - { - NuGetFramework framework = NuGetFramework.Parse(import); - - if (!framework.IsSpecificFramework) - { - throw FileFormatException.Create( - string.Format( - CultureInfo.CurrentCulture, - Strings.Log_InvalidImportFramework, - import, - PackageSpec.PackageSpecFileName), - lineNumber, - linePosition, - packageSpec.FilePath); - } - - targetFrameworkInformation.Imports.Add(framework); - } - } - } - - private static void ReadMappings(JsonTextReader jsonReader, string mappingKey, IDictionary mappings) - { - if (jsonReader.ReadNextToken()) - { - switch (jsonReader.TokenType) - { - case JsonToken.String: - { - var files = new IncludeExcludeFiles() - { - Include = new[] { (string)jsonReader.Value } - }; - - mappings.Add(mappingKey, files); - } - break; - - case JsonToken.StartArray: - { - IReadOnlyList include = jsonReader.ReadStringArrayAsReadOnlyListFromArrayStart(); - - var files = new IncludeExcludeFiles() - { - Include = include - }; - - mappings.Add(mappingKey, files); - } - break; - - case JsonToken.StartObject: - { - IReadOnlyList excludeFiles = null; - IReadOnlyList exclude = null; - IReadOnlyList includeFiles = null; - IReadOnlyList include = null; - - jsonReader.ReadProperties(filesPropertyName => - { - switch (filesPropertyName) - { - case "excludeFiles": - excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "exclude": - exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "includeFiles": - includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "include": - include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - } - }); - - if (include != null || includeFiles != null || exclude != null || excludeFiles != null) - { - var files = new IncludeExcludeFiles() - { - ExcludeFiles = excludeFiles, - Exclude = exclude, - IncludeFiles = includeFiles, - Include = include - }; - - mappings.Add(mappingKey, files); - } - } - break; - } - } - } - - private static void ReadMSBuildMetadata(JsonTextReader jsonReader, PackageSpec packageSpec) - { - var centralPackageVersionsManagementEnabled = false; - var centralPackageVersionOverrideDisabled = false; - var CentralPackageTransitivePinningEnabled = false; - List configFilePaths = null; - var crossTargeting = false; - List fallbackFolders = null; - List files = null; - var legacyPackagesDirectory = false; - ProjectRestoreMetadata msbuildMetadata = null; - List originalTargetFrameworks = null; - string outputPath = null; - string packagesConfigPath = null; - string packagesPath = null; - string projectJsonPath = null; - string projectName = null; - string projectPath = null; - ProjectStyle? projectStyle = null; - string projectUniqueName = null; - RestoreLockProperties restoreLockProperties = null; - var skipContentFileWrite = false; - List sources = null; - List targetFrameworks = null; - var validateRuntimeAssets = false; - WarningProperties warningProperties = null; - RestoreAuditProperties auditProperties = null; - - jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "centralPackageVersionsManagementEnabled": - centralPackageVersionsManagementEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "centralPackageVersionOverrideDisabled": - centralPackageVersionOverrideDisabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "CentralPackageTransitivePinningEnabled": - CentralPackageTransitivePinningEnabled = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "configFilePaths": - configFilePaths = jsonReader.ReadStringArrayAsList(); - break; - - case "crossTargeting": - crossTargeting = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "fallbackFolders": - fallbackFolders = jsonReader.ReadStringArrayAsList(); - break; - - case "files": - jsonReader.ReadObject(filePropertyName => - { - files = files ?? new List(); - - files.Add(new ProjectRestoreMetadataFile(filePropertyName, jsonReader.ReadNextTokenAsString())); - }); - break; - - case "frameworks": - targetFrameworks = ReadTargetFrameworks(jsonReader); - break; - - case "legacyPackagesDirectory": - legacyPackagesDirectory = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "originalTargetFrameworks": - originalTargetFrameworks = jsonReader.ReadStringArrayAsList(); - break; - - case "outputPath": - outputPath = jsonReader.ReadNextTokenAsString(); - break; - - case "packagesConfigPath": - packagesConfigPath = jsonReader.ReadNextTokenAsString(); - break; - - case "packagesPath": - packagesPath = jsonReader.ReadNextTokenAsString(); - break; - - case "projectJsonPath": - projectJsonPath = jsonReader.ReadNextTokenAsString(); - break; - - case "projectName": - projectName = jsonReader.ReadNextTokenAsString(); - break; - - case "projectPath": - projectPath = jsonReader.ReadNextTokenAsString(); - break; - - case "projectStyle": - string projectStyleString = jsonReader.ReadNextTokenAsString(); - - if (!string.IsNullOrEmpty(projectStyleString) - && Enum.TryParse(projectStyleString, ignoreCase: true, result: out ProjectStyle projectStyleValue)) - { - projectStyle = projectStyleValue; - } - break; - - case "projectUniqueName": - projectUniqueName = jsonReader.ReadNextTokenAsString(); - break; - - case "restoreLockProperties": - string nuGetLockFilePath = null; - var restoreLockedMode = false; - string restorePackagesWithLockFile = null; - - jsonReader.ReadObject(restoreLockPropertiesPropertyName => - { - switch (restoreLockPropertiesPropertyName) - { - case "nuGetLockFilePath": - nuGetLockFilePath = jsonReader.ReadNextTokenAsString(); - break; - - case "restoreLockedMode": - restoreLockedMode = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "restorePackagesWithLockFile": - restorePackagesWithLockFile = jsonReader.ReadNextTokenAsString(); - break; - } - }); - - restoreLockProperties = new RestoreLockProperties(restorePackagesWithLockFile, nuGetLockFilePath, restoreLockedMode); - break; - - case "restoreAuditProperties": - string enableAudit = null, auditLevel = null, auditMode = null; - jsonReader.ReadObject(auditPropertyName => - { - - switch (auditPropertyName) - { - case "enableAudit": - enableAudit = jsonReader.ReadNextTokenAsString(); - break; - - case "auditLevel": - auditLevel = jsonReader.ReadNextTokenAsString(); - break; - - case "auditMode": - auditMode = jsonReader.ReadNextTokenAsString(); - break; - } - }); - auditProperties = new RestoreAuditProperties() - { - EnableAudit = enableAudit, - AuditLevel = auditLevel, - AuditMode = auditMode, - }; - break; - - case "skipContentFileWrite": - skipContentFileWrite = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "sources": - jsonReader.ReadObject(sourcePropertyName => - { - sources = sources ?? new List(); - - sources.Add(new PackageSource(sourcePropertyName)); - }); - break; - - case "validateRuntimeAssets": - validateRuntimeAssets = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "warningProperties": - var allWarningsAsErrors = false; - var noWarn = new HashSet(); - var warnAsError = new HashSet(); - var warningsNotAsErrors = new HashSet(); - - jsonReader.ReadObject(warningPropertiesPropertyName => - { - switch (warningPropertiesPropertyName) - { - case "allWarningsAsErrors": - allWarningsAsErrors = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "noWarn": - ReadNuGetLogCodes(jsonReader, noWarn); - break; - - case "warnAsError": - ReadNuGetLogCodes(jsonReader, warnAsError); - break; - - case "warnNotAsError": - ReadNuGetLogCodes(jsonReader, warningsNotAsErrors); - break; - } - }); - - warningProperties = new WarningProperties(warnAsError, noWarn, allWarningsAsErrors, warningsNotAsErrors); - break; - } - }); - - if (projectStyle == ProjectStyle.PackagesConfig) - { - msbuildMetadata = new PackagesConfigProjectRestoreMetadata() - { - PackagesConfigPath = packagesConfigPath - }; - } - else - { - msbuildMetadata = new ProjectRestoreMetadata(); - } - - msbuildMetadata.CentralPackageVersionsEnabled = centralPackageVersionsManagementEnabled; - msbuildMetadata.CentralPackageVersionOverrideDisabled = centralPackageVersionOverrideDisabled; - msbuildMetadata.CentralPackageTransitivePinningEnabled = CentralPackageTransitivePinningEnabled; - msbuildMetadata.RestoreAuditProperties = auditProperties; - - if (configFilePaths != null) - { - msbuildMetadata.ConfigFilePaths = configFilePaths; - } - - msbuildMetadata.CrossTargeting = crossTargeting; - - if (fallbackFolders != null) - { - msbuildMetadata.FallbackFolders = fallbackFolders; - } - - if (files != null) - { - msbuildMetadata.Files = files; - } - - msbuildMetadata.LegacyPackagesDirectory = legacyPackagesDirectory; - - if (originalTargetFrameworks != null) - { - msbuildMetadata.OriginalTargetFrameworks = originalTargetFrameworks; - } - - msbuildMetadata.OutputPath = outputPath; - msbuildMetadata.PackagesPath = packagesPath; - msbuildMetadata.ProjectJsonPath = projectJsonPath; - msbuildMetadata.ProjectName = projectName; - msbuildMetadata.ProjectPath = projectPath; - - if (projectStyle.HasValue) - { - msbuildMetadata.ProjectStyle = projectStyle.Value; - } - - msbuildMetadata.ProjectUniqueName = projectUniqueName; - - if (restoreLockProperties != null) - { - msbuildMetadata.RestoreLockProperties = restoreLockProperties; - } - - msbuildMetadata.SkipContentFileWrite = skipContentFileWrite; - - if (sources != null) - { - msbuildMetadata.Sources = sources; - } - - if (targetFrameworks != null) - { - msbuildMetadata.TargetFrameworks = targetFrameworks; - } - - msbuildMetadata.ValidateRuntimeAssets = validateRuntimeAssets; - - if (warningProperties != null) - { - msbuildMetadata.ProjectWideWarningProperties = warningProperties; - } - - packageSpec.RestoreMetadata = msbuildMetadata; - } - - private static bool ReadNextTokenAsBoolOrFalse(JsonTextReader jsonReader, string filePath) - { - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.Boolean) - { - try - { - return (bool)jsonReader.Value; - } - catch (Exception ex) - { - throw FileFormatException.Create(ex, jsonReader.LineNumber, jsonReader.LinePosition, filePath); - } - } - - return false; - } - - private static void ReadNuGetLogCodes(JsonTextReader jsonReader, HashSet hashCodes) - { - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) - { - while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) - { - if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) - { - hashCodes.Add(code); - } - } - } - } - - private static List ReadNuGetLogCodesList(JsonTextReader jsonReader) - { - List items = null; - - if (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.StartArray) - { - while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) - { - if (jsonReader.TokenType == JsonToken.String && Enum.TryParse((string)jsonReader.Value, out NuGetLogCode code)) - { - items = items ?? new List(); - - items.Add(code); - } - } - } - - return items; - } - - private static void ReadPackageTypes(PackageSpec packageSpec, JsonTextReader jsonReader) - { - var errorLine = 0; - var errorColumn = 0; - - IReadOnlyList packageTypes = null; - PackageType packageType = null; - - try - { - if (jsonReader.ReadNextToken()) - { - errorLine = jsonReader.LineNumber; - errorColumn = jsonReader.LinePosition; - - switch (jsonReader.TokenType) - { - case JsonToken.String: - packageType = CreatePackageType(jsonReader); - - packageTypes = new[] { packageType }; - break; - - case JsonToken.StartArray: - var types = new List(); - - while (jsonReader.ReadNextToken() && jsonReader.TokenType != JsonToken.EndArray) - { - if (jsonReader.TokenType != JsonToken.String) - { - throw FileFormatException.Create( - string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageType, - PackageSpec.PackageSpecFileName), - errorLine, - errorColumn, - packageSpec.FilePath); - } - - packageType = CreatePackageType(jsonReader); - - types.Add(packageType); - } - - packageTypes = types; - break; - - case JsonToken.Null: - break; - - default: - throw new InvalidCastException(); - } - -#pragma warning disable CS0612 // Type or member is obsolete - if (packageTypes != null) - { - packageSpec.PackOptions.PackageType = packageTypes; - } -#pragma warning restore CS0612 // Type or member is obsolete - } - } - catch (Exception) - { - throw FileFormatException.Create( - string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidPackageType, - PackageSpec.PackageSpecFileName), - errorLine, - errorColumn, - packageSpec.FilePath); - } - } - - [Obsolete] - private static void ReadPackInclude(JsonTextReader jsonReader, PackageSpec packageSpec) - { - jsonReader.ReadObject(propertyName => - { - string propertyValue = jsonReader.ReadAsString(); - - packageSpec.PackInclude.Add(new KeyValuePair(propertyName, propertyValue)); - }); - } - - [Obsolete] - private static void ReadPackOptions(JsonTextReader jsonReader, PackageSpec packageSpec, ref bool isMappingsNull) - { - var wasMappingsRead = false; - - bool isPackOptionsValueAnObject = jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "files": - wasMappingsRead = ReadPackOptionsFiles(packageSpec, jsonReader, wasMappingsRead); - break; - - case "iconUrl": - packageSpec.IconUrl = jsonReader.ReadNextTokenAsString(); - break; - - case "licenseUrl": - packageSpec.LicenseUrl = jsonReader.ReadNextTokenAsString(); - break; - - case "owners": - string[] owners = ReadStringArray(jsonReader); - - if (owners != null) - { - packageSpec.Owners = owners; - } - break; - - case "packageType": - ReadPackageTypes(packageSpec, jsonReader); - break; - - case "projectUrl": - packageSpec.ProjectUrl = jsonReader.ReadNextTokenAsString(); - break; - - case "releaseNotes": - packageSpec.ReleaseNotes = jsonReader.ReadNextTokenAsString(); - break; - - case "requireLicenseAcceptance": - packageSpec.RequireLicenseAcceptance = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "summary": - packageSpec.Summary = jsonReader.ReadNextTokenAsString(); - break; - - case "tags": - string[] tags = ReadStringArray(jsonReader); - - if (tags != null) - { - packageSpec.Tags = tags; - } - break; - } - }); - - isMappingsNull = isPackOptionsValueAnObject && !wasMappingsRead; - } - - [Obsolete] - private static bool ReadPackOptionsFiles(PackageSpec packageSpec, JsonTextReader jsonReader, bool wasMappingsRead) - { - IReadOnlyList excludeFiles = null; - IReadOnlyList exclude = null; - IReadOnlyList includeFiles = null; - IReadOnlyList include = null; - - jsonReader.ReadObject(filesPropertyName => - { - switch (filesPropertyName) - { - case "excludeFiles": - excludeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "exclude": - exclude = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "includeFiles": - includeFiles = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "include": - include = jsonReader.ReadStringOrArrayOfStringsAsReadOnlyList(); - break; - - case "mappings": - jsonReader.ReadObject(mappingsPropertyName => - { - wasMappingsRead = true; - - ReadMappings(jsonReader, mappingsPropertyName, packageSpec.PackOptions.Mappings); - }); - break; - } - }); - - if (include != null || includeFiles != null || exclude != null || excludeFiles != null) - { - packageSpec.PackOptions.IncludeExcludeFiles = new IncludeExcludeFiles() - { - ExcludeFiles = excludeFiles, - Exclude = exclude, - IncludeFiles = includeFiles, - Include = include - }; - } - - return wasMappingsRead; - } - - private static RuntimeDependencySet ReadRuntimeDependencySet(JsonTextReader jsonReader, string dependencySetName) - { - List dependencies = null; - - jsonReader.ReadObject(propertyName => - { - dependencies ??= new List(); - - var dependency = new RuntimePackageDependency(propertyName, VersionRange.Parse(jsonReader.ReadNextTokenAsString())); - - dependencies.Add(dependency); - }); - - return new RuntimeDependencySet( - dependencySetName, - dependencies); - } - - private static RuntimeDescription ReadRuntimeDescription(JsonTextReader jsonReader, string runtimeName) - { - List inheritedRuntimes = null; - List additionalDependencies = null; - - jsonReader.ReadObject(propertyName => - { - if (propertyName == "#import") - { - inheritedRuntimes = jsonReader.ReadStringArrayAsList(); - } - else - { - additionalDependencies ??= new List(); - - RuntimeDependencySet dependency = ReadRuntimeDependencySet(jsonReader, propertyName); - - additionalDependencies.Add(dependency); - } - }); - - return new RuntimeDescription( - runtimeName, - inheritedRuntimes, - additionalDependencies); - } - - private static List ReadRuntimes(JsonTextReader jsonReader) - { - var runtimeDescriptions = new List(); - - jsonReader.ReadObject(propertyName => - { - RuntimeDescription runtimeDescription = ReadRuntimeDescription(jsonReader, propertyName); - - runtimeDescriptions.Add(runtimeDescription); - }); - - return runtimeDescriptions; - } - - [Obsolete] - private static void ReadScripts(JsonTextReader jsonReader, PackageSpec packageSpec) - { - jsonReader.ReadObject(propertyName => - { - if (jsonReader.ReadNextToken()) - { - if (jsonReader.TokenType == JsonToken.String) - { - packageSpec.Scripts[propertyName] = new string[] { (string)jsonReader.Value }; - } - else if (jsonReader.TokenType == JsonToken.StartArray) - { - var list = new List(); - - while (jsonReader.ReadNextToken() && jsonReader.TokenType == JsonToken.String) - { - list.Add((string)jsonReader.Value); - } - - packageSpec.Scripts[propertyName] = list; - } - else - { - throw FileFormatException.Create( - string.Format(CultureInfo.CurrentCulture, "The value of a script in '{0}' can only be a string or an array of strings", PackageSpec.PackageSpecFileName), - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpec.FilePath); - } - } - }); - } - - private static string[] ReadStringArray(JsonTextReader jsonReader) - { - List list = jsonReader.ReadStringArrayAsList(); - - return list?.ToArray(); - } - - private static List ReadSupports(JsonTextReader jsonReader) - { - var compatibilityProfiles = new List(); - - jsonReader.ReadObject(propertyName => - { - CompatibilityProfile compatibilityProfile = ReadCompatibilityProfile(jsonReader, propertyName); - - compatibilityProfiles.Add(compatibilityProfile); - }); - - return compatibilityProfiles; - } - - private static LibraryDependencyTarget ReadTarget( - JsonTextReader jsonReader, - string packageSpecPath, - LibraryDependencyTarget targetFlagsValue) - { - if (jsonReader.ReadNextToken()) - { - var targetString = (string)jsonReader.Value; - - targetFlagsValue = LibraryDependencyTargetUtils.Parse(targetString); - - // Verify that the value specified is package, project, or external project - if (!ValidateDependencyTarget(targetFlagsValue)) - { - string message = string.Format( - CultureInfo.CurrentCulture, - Strings.InvalidDependencyTarget, - targetString); - - throw FileFormatException.Create( - message, - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - } - - return targetFlagsValue; - } - - private static List ReadTargetFrameworks(JsonTextReader jsonReader) - { - var targetFrameworks = new List(); - - jsonReader.ReadObject(frameworkPropertyName => - { - NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); - var frameworkGroup = new ProjectRestoreMetadataFrameworkInfo(framework); - - jsonReader.ReadObject(propertyName => - { - if (propertyName == "projectReferences") - { - jsonReader.ReadObject(projectReferencePropertyName => - { - string excludeAssets = null; - string includeAssets = null; - string privateAssets = null; - string projectReferenceProjectPath = null; - - jsonReader.ReadObject(projectReferenceObjectPropertyName => - { - switch (projectReferenceObjectPropertyName) - { - case "excludeAssets": - excludeAssets = jsonReader.ReadNextTokenAsString(); - break; - - case "includeAssets": - includeAssets = jsonReader.ReadNextTokenAsString(); - break; - - case "privateAssets": - privateAssets = jsonReader.ReadNextTokenAsString(); - break; - - case "projectPath": - projectReferenceProjectPath = jsonReader.ReadNextTokenAsString(); - break; - } - }); - - frameworkGroup.ProjectReferences.Add(new ProjectRestoreReference() - { - ProjectUniqueName = projectReferencePropertyName, - ProjectPath = projectReferenceProjectPath, - - IncludeAssets = LibraryIncludeFlagUtils.GetFlags( - flags: includeAssets, - defaultFlags: LibraryIncludeFlags.All), - - ExcludeAssets = LibraryIncludeFlagUtils.GetFlags( - flags: excludeAssets, - defaultFlags: LibraryIncludeFlags.None), - - PrivateAssets = LibraryIncludeFlagUtils.GetFlags( - flags: privateAssets, - defaultFlags: LibraryIncludeFlagUtils.DefaultSuppressParent), - }); - }); - } - else if (propertyName == "targetAlias") - { - frameworkGroup.TargetAlias = jsonReader.ReadNextTokenAsString(); - } - }); - - targetFrameworks.Add(frameworkGroup); - }); - - return targetFrameworks; - } - - private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader jsonReader, out int frameworkLine, out int frameworkColumn) - { - frameworkLine = 0; - frameworkColumn = 0; - - NuGetFramework frameworkName = NuGetFramework.Parse((string)jsonReader.Value); - - var targetFrameworkInformation = new TargetFrameworkInformation(); - NuGetFramework secondaryFramework = default; - jsonReader.ReadObject(propertyName => - { - switch (propertyName) - { - case "assetTargetFallback": - targetFrameworkInformation.AssetTargetFallback = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - - case "secondaryFramework": - var secondaryFrameworkString = jsonReader.ReadAsString(); - if (!string.IsNullOrEmpty(secondaryFrameworkString)) - { - secondaryFramework = NuGetFramework.Parse(secondaryFrameworkString); - } - break; - - case "centralPackageVersions": - ReadCentralPackageVersions( - jsonReader, - targetFrameworkInformation.CentralPackageVersions, - packageSpec.FilePath); - break; - - case "dependencies": - ReadDependencies( - jsonReader, - targetFrameworkInformation.Dependencies, - packageSpec.FilePath, - isGacOrFrameworkReference: false); - break; - - case "downloadDependencies": - ReadDownloadDependencies( - jsonReader, - targetFrameworkInformation.DownloadDependencies, - packageSpec.FilePath); - break; - - case "frameworkAssemblies": - ReadDependencies( - jsonReader, - targetFrameworkInformation.Dependencies, - packageSpec.FilePath, - isGacOrFrameworkReference: true); - break; - - case "frameworkReferences": - ReadFrameworkReferences( - jsonReader, - targetFrameworkInformation.FrameworkReferences, - packageSpec.FilePath); - break; - - case "imports": - ReadImports(packageSpec, jsonReader, targetFrameworkInformation); - break; - - case "runtimeIdentifierGraphPath": - targetFrameworkInformation.RuntimeIdentifierGraphPath = jsonReader.ReadNextTokenAsString(); - break; - - case "targetAlias": - targetFrameworkInformation.TargetAlias = jsonReader.ReadNextTokenAsString(); - break; - - case "warn": - targetFrameworkInformation.Warn = ReadNextTokenAsBoolOrFalse(jsonReader, packageSpec.FilePath); - break; - } - }, out frameworkLine, out frameworkColumn); - - NuGetFramework updatedFramework = frameworkName; - - if (targetFrameworkInformation.Imports.Count > 0) - { - NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); - - if (targetFrameworkInformation.AssetTargetFallback) - { - updatedFramework = new AssetTargetFallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); - } - else - { - updatedFramework = new FallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); - } - } - else - { - updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); - } - - targetFrameworkInformation.FrameworkName = updatedFramework; - - packageSpec.TargetFrameworks.Add(targetFrameworkInformation); - } - - private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) - { - if (secondaryFramework != default) - { - return new DualCompatibilityFramework(frameworkName, secondaryFramework); - } - - return frameworkName; - } - - private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue) - { - var isValid = false; - - switch (targetValue) - { - case LibraryDependencyTarget.Package: - case LibraryDependencyTarget.Project: - case LibraryDependencyTarget.ExternalProject: - isValid = true; - break; - } - - return isValid; - } - } -} diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index ed0c252d3d1..343959c278b 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -3871,7 +3871,7 @@ public void PackageSpecReader_Read(IEnvironmentVariableReader environmentVariabl { var dependencies = new List(); NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); - NjPackageSpecReader.ReadCentralTransitiveDependencyGroup( + JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( jsonReader: jsonReader, results: dependencies, packageSpecPath: "SomePath"); From 8e2c300325e3b0c11b86f2c5eaf367dc3e727b0c Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Fri, 15 Dec 2023 11:20:51 -0800 Subject: [PATCH 16/20] move ReadCentralTransitiveDependencyGroup to match previous location --- .../JsonPackageSpecReader.cs | 246 +++++++++--------- 1 file changed, 123 insertions(+), 123 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index 15a7da29801..7c4199dc590 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -253,129 +253,6 @@ internal static PackageSpec GetPackageSpec(JsonTextReader jsonReader, string nam return packageSpec; } - [Obsolete] - internal static void ReadCentralTransitiveDependencyGroup( - JsonTextReader jsonReader, - IList results, - string packageSpecPath) - { - jsonReader.ReadObject(propertyName => - { - if (string.IsNullOrEmpty(propertyName)) - { - // Advance the reader's position to be able to report the line and column for the property value. - jsonReader.ReadNextToken(); - - throw FileFormatException.Create( - "Unable to resolve dependency ''.", - jsonReader.LineNumber, - jsonReader.LinePosition, - packageSpecPath); - } - - if (jsonReader.ReadNextToken()) - { - int dependencyValueLine = jsonReader.LineNumber; - int dependencyValueColumn = jsonReader.LinePosition; - var versionLine = 0; - var versionColumn = 0; - - var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; - var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; - var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - string dependencyVersionValue = null; - - if (jsonReader.TokenType == JsonToken.String) - { - dependencyVersionValue = (string)jsonReader.Value; - } - else if (jsonReader.TokenType == JsonToken.StartObject) - { - jsonReader.ReadProperties(dependenciesPropertyName => - { - IEnumerable values = null; - - switch (dependenciesPropertyName) - { - case "exclude": - values = jsonReader.ReadDelimitedString(); - dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "include": - values = jsonReader.ReadDelimitedString(); - dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "suppressParent": - values = jsonReader.ReadDelimitedString(); - suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - break; - - case "version": - if (jsonReader.ReadNextToken()) - { - versionLine = jsonReader.LineNumber; - versionColumn = jsonReader.LinePosition; - dependencyVersionValue = (string)jsonReader.Value; - } - break; - - default: - break; - } - }); - } - - VersionRange dependencyVersionRange = null; - - if (!string.IsNullOrEmpty(dependencyVersionValue)) - { - try - { - dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - versionLine, - versionColumn, - packageSpecPath); - } - } - - if (dependencyVersionRange == null) - { - throw FileFormatException.Create( - new ArgumentException(Strings.MissingVersionOnDependency), - dependencyValueLine, - dependencyValueColumn, - packageSpecPath); - } - - // the dependency flags are: Include flags - Exclude flags - var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency() - { - LibraryRange = new LibraryRange() - { - Name = propertyName, - TypeConstraint = LibraryDependencyTarget.Package, - VersionRange = dependencyVersionRange - }, - - IncludeType = includeFlags, - SuppressParent = suppressParentFlagsValue, - VersionCentrallyManaged = true, - ReferenceType = LibraryDependencyReferenceType.Transitive - }; - - results.Add(libraryDependency); - } - }); - } - [Obsolete] private static PackageType CreatePackageType(JsonTextReader jsonReader) { @@ -663,6 +540,129 @@ private static void ReadDependencies( }); } + [Obsolete] + internal static void ReadCentralTransitiveDependencyGroup( + JsonTextReader jsonReader, + IList results, + string packageSpecPath) + { + jsonReader.ReadObject(propertyName => + { + if (string.IsNullOrEmpty(propertyName)) + { + // Advance the reader's position to be able to report the line and column for the property value. + jsonReader.ReadNextToken(); + + throw FileFormatException.Create( + "Unable to resolve dependency ''.", + jsonReader.LineNumber, + jsonReader.LinePosition, + packageSpecPath); + } + + if (jsonReader.ReadNextToken()) + { + int dependencyValueLine = jsonReader.LineNumber; + int dependencyValueColumn = jsonReader.LinePosition; + var versionLine = 0; + var versionColumn = 0; + + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + string dependencyVersionValue = null; + + if (jsonReader.TokenType == JsonToken.String) + { + dependencyVersionValue = (string)jsonReader.Value; + } + else if (jsonReader.TokenType == JsonToken.StartObject) + { + jsonReader.ReadProperties(dependenciesPropertyName => + { + IEnumerable values = null; + + switch (dependenciesPropertyName) + { + case "exclude": + values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "include": + values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "suppressParent": + values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + break; + + case "version": + if (jsonReader.ReadNextToken()) + { + versionLine = jsonReader.LineNumber; + versionColumn = jsonReader.LinePosition; + dependencyVersionValue = (string)jsonReader.Value; + } + break; + + default: + break; + } + }); + } + + VersionRange dependencyVersionRange = null; + + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + versionLine, + versionColumn, + packageSpecPath); + } + } + + if (dependencyVersionRange == null) + { + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + dependencyValueLine, + dependencyValueColumn, + packageSpecPath); + } + + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = propertyName, + TypeConstraint = LibraryDependencyTarget.Package, + VersionRange = dependencyVersionRange + }, + + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + VersionCentrallyManaged = true, + ReferenceType = LibraryDependencyReferenceType.Transitive + }; + + results.Add(libraryDependency); + } + }); + } + [Obsolete] private static void ReadDownloadDependencies( JsonTextReader jsonReader, From eef2428d9b2a3965d91db17780efc014c6123ddd Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Fri, 15 Dec 2023 11:23:05 -0800 Subject: [PATCH 17/20] formatting --- src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index 7c4199dc590..5fd68eee7ed 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -542,9 +542,9 @@ private static void ReadDependencies( [Obsolete] internal static void ReadCentralTransitiveDependencyGroup( - JsonTextReader jsonReader, - IList results, - string packageSpecPath) + JsonTextReader jsonReader, + IList results, + string packageSpecPath) { jsonReader.ReadObject(propertyName => { From 7eb51aeb352b68451e7e3b05f8fd0941cbb610ee Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Fri, 15 Dec 2023 12:10:25 -0800 Subject: [PATCH 18/20] convert to parial class --- ...PackageSpecReader.Utf8JsonStreamReader.cs} | 124 ++++-------------- .../JsonPackageSpecReader.cs | 11 +- .../JsonPackageSpecReaderTests.cs | 2 +- 3 files changed, 36 insertions(+), 101 deletions(-) rename src/NuGet.Core/NuGet.ProjectModel/{Utf8JsonStreamPackageSpecReader.cs => JsonPackageSpecReader.Utf8JsonStreamReader.cs} (95%) diff --git a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs similarity index 95% rename from src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs rename to src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs index e86efa5d073..28fa93ecc2c 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/Utf8JsonStreamPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs @@ -18,9 +18,8 @@ namespace NuGet.ProjectModel { - internal static class Utf8JsonStreamPackageSpecReader + public partial class JsonPackageSpecReader { - private static readonly char[] VersionSeparators = new[] { ';' }; private static readonly byte[] AuthorsPropertyName = Encoding.UTF8.GetBytes("authors"); private static readonly byte[] BuildOptionsPropertyName = Encoding.UTF8.GetBytes("buildOptions"); private static readonly byte[] ContentFilesPropertyName = Encoding.UTF8.GetBytes("contentFiles"); @@ -110,15 +109,7 @@ internal static class Utf8JsonStreamPackageSpecReader private static readonly byte[] ProjectReferencesPropertyName = Encoding.UTF8.GetBytes("projectReferences"); private static readonly byte[] EmptyStringPropertyName = Encoding.UTF8.GetBytes(string.Empty); - internal static PackageSpec GetPackageSpec(string json, string name, string packageSpecPath, string snapshotValue = null) - { - using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) - { - return GetPackageSpec(stream, name, packageSpecPath, snapshotValue); - } - } - - internal static PackageSpec GetPackageSpec(Stream stream, string name, string packageSpecPath, string snapshotValue) + internal static PackageSpec GetPackageSpecUtf8JsonStreamReader(Stream stream, string name, string packageSpecPath, string snapshotValue) { var reader = new Utf8JsonStreamReader(stream); PackageSpec packageSpec; @@ -162,10 +153,7 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, { packageSpec.Authors = jsonReader.ReadStringArrayAsIList()?.ToArray(); } - if (packageSpec.Authors == null) - { - packageSpec.Authors = Array.Empty(); - } + packageSpec.Authors ??= []; } else if (jsonReader.ValueTextEquals(BuildOptionsPropertyName)) { @@ -260,12 +248,12 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, #pragma warning disable CS0612 // Type or member is obsolete if (!wasPackOptionsSet) { - packageSpec.Owners = Array.Empty(); + packageSpec.Owners = []; packageSpec.PackOptions = new PackOptions() { PackageType = Array.Empty() }; - packageSpec.Tags = Array.Empty(); + packageSpec.Tags = []; } if (isMappingsNull) @@ -278,17 +266,11 @@ internal static PackageSpec GetPackageSpec(ref Utf8JsonStreamReader jsonReader, runtimeDescriptions ?? Enumerable.Empty(), compatibilityProfiles ?? Enumerable.Empty()); - if (packageSpec.Name == null) - { - packageSpec.Name = packageSpec.RestoreMetadata?.ProjectName; - } + packageSpec.Name ??= packageSpec.RestoreMetadata?.ProjectName; // Use the project.json path if one is set, otherwise use the project path - if (packageSpec.FilePath == null) - { - packageSpec.FilePath = packageSpec.RestoreMetadata?.ProjectJsonPath + packageSpec.FilePath ??= packageSpec.RestoreMetadata?.ProjectJsonPath ?? packageSpec.RestoreMetadata?.ProjectPath; - } return packageSpec; } @@ -325,21 +307,19 @@ internal static void ReadCentralTransitiveDependencyGroup( { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - IEnumerable values = null; - if (jsonReader.ValueTextEquals(ExcludePropertyName)) { - values = jsonReader.ReadDelimitedString(); + var values = jsonReader.ReadDelimitedString(); dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } else if (jsonReader.ValueTextEquals(IncludePropertyName)) { - values = jsonReader.ReadDelimitedString(); + var values = jsonReader.ReadDelimitedString(); dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } else if (jsonReader.ValueTextEquals(SuppressParentPropertyName)) { - values = jsonReader.ReadDelimitedString(); + var values = jsonReader.ReadDelimitedString(); suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } else if (jsonReader.ValueTextEquals(VersionPropertyName)) @@ -452,14 +432,13 @@ private static void ReadDependencies( { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - IEnumerable values = null; if (jsonReader.ValueTextEquals(AutoReferencedPropertyName)) { autoReferenced = jsonReader.ReadNextTokenAsBoolOrFalse(); } else if (jsonReader.ValueTextEquals(ExcludePropertyName)) { - values = jsonReader.ReadDelimitedString(); + var values = jsonReader.ReadDelimitedString(); dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } else if (jsonReader.ValueTextEquals(GeneratePathPropertyPropertyName)) @@ -468,7 +447,7 @@ private static void ReadDependencies( } else if (jsonReader.ValueTextEquals(IncludePropertyName)) { - values = jsonReader.ReadDelimitedString(); + var values = jsonReader.ReadDelimitedString(); dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } else if (jsonReader.ValueTextEquals(NoWarnPropertyName)) @@ -477,7 +456,7 @@ private static void ReadDependencies( } else if (jsonReader.ValueTextEquals(SuppressParentPropertyName)) { - values = jsonReader.ReadDelimitedString(); + var values = jsonReader.ReadDelimitedString(); suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); } else if (jsonReader.ValueTextEquals(TargetPropertyName)) @@ -651,7 +630,7 @@ private static CompatibilityProfile ReadCompatibilityProfile(ref Utf8JsonStreamR while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { var propertyName = jsonReader.GetString(); - sets = sets ?? new List(); + sets ??= []; IReadOnlyList values = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList() ?? Array.Empty(); @@ -926,7 +905,6 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac List fallbackFolders = null; List files = null; var legacyPackagesDirectory = false; - ProjectRestoreMetadata msbuildMetadata = null; List originalTargetFrameworks = null; string outputPath = null; string packagesConfigPath = null; @@ -981,7 +959,7 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { var filePropertyName = jsonReader.GetString(); - files = files ?? new List(); + files ??= []; files.Add(new ProjectRestoreMetadataFile(filePropertyName, jsonReader.ReadNextTokenAsString())); } @@ -1111,7 +1089,7 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { var sourcePropertyName = jsonReader.GetString(); - sources = sources ?? new List(); + sources ??= []; sources.Add(new PackageSource(sourcePropertyName)); jsonReader.Skip(); @@ -1165,6 +1143,7 @@ private static void ReadMSBuildMetadata(ref Utf8JsonStreamReader jsonReader, Pac } } + ProjectRestoreMetadata msbuildMetadata; if (projectStyle == ProjectStyle.PackagesConfig) { msbuildMetadata = new PackagesConfigProjectRestoreMetadata() @@ -1270,7 +1249,7 @@ private static List ReadNuGetLogCodesList(ref Utf8JsonStreamReader { if (jsonReader.TokenType == JsonTokenType.String && Enum.TryParse(jsonReader.GetString(), out NuGetLogCode code)) { - items = items ?? new List(); + items ??= []; items.Add(code); } @@ -1282,20 +1261,17 @@ private static List ReadNuGetLogCodesList(ref Utf8JsonStreamReader private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStreamReader jsonReader) { IReadOnlyList packageTypes = null; - PackageType packageType = null; - try { if (jsonReader.Read()) { + PackageType packageType; switch (jsonReader.TokenType) { case JsonTokenType.String: packageType = CreatePackageType(ref jsonReader); - packageTypes = new[] { packageType }; break; - case JsonTokenType.StartArray: var types = new List(); @@ -1312,13 +1288,10 @@ private static void ReadPackageTypes(PackageSpec packageSpec, ref Utf8JsonStream } packageType = CreatePackageType(ref jsonReader); - types.Add(packageType); } - packageTypes = types; break; - case JsonTokenType.Null: break; default: @@ -1442,7 +1415,6 @@ private static bool ReadPackOptionsFiles(PackageSpec packageSpec, ref Utf8JsonSt { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - var filesPropertyName = jsonReader.GetString(); if (jsonReader.ValueTextEquals(ExcludeFilesPropertyName)) { excludeFiles = jsonReader.ReadNextStringOrArrayOfStringsAsReadOnlyList(); @@ -1501,7 +1473,7 @@ private static RuntimeDependencySet ReadRuntimeDependencySet(ref Utf8JsonStreamR while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { var propertyName = jsonReader.GetString(); - dependencies ??= new List(); + dependencies ??= []; var dependency = new RuntimePackageDependency(propertyName, VersionRange.Parse(jsonReader.ReadNextTokenAsString())); @@ -1531,7 +1503,7 @@ private static RuntimeDescription ReadRuntimeDescription(ref Utf8JsonStreamReade else { var propertyName = jsonReader.GetString(); - additionalDependencies ??= new List(); + additionalDependencies ??= []; RuntimeDependencySet dependency = ReadRuntimeDependencySet(ref jsonReader, propertyName); @@ -1628,6 +1600,7 @@ private static LibraryDependencyTarget ReadTarget( targetFlagsValue = LibraryDependencyTargetUtils.Parse(targetString); // Verify that the value specified is package, project, or external project +#pragma warning disable CS0612 // Type or member is obsolete if (!ValidateDependencyTarget(targetFlagsValue)) { string message = string.Format( @@ -1638,6 +1611,7 @@ private static LibraryDependencyTarget ReadTarget( message, packageSpecPath); } +#pragma warning restore CS0612 // Type or member is obsolete } return targetFlagsValue; @@ -1819,55 +1793,9 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, ref Utf8JsonSt } } - NuGetFramework updatedFramework = frameworkName; - - if (targetFrameworkInformation.Imports.Count > 0) - { - NuGetFramework[] imports = targetFrameworkInformation.Imports.ToArray(); - - if (targetFrameworkInformation.AssetTargetFallback) - { - updatedFramework = new AssetTargetFallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); - } - else - { - updatedFramework = new FallbackFramework(GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework), imports); - } - } - else - { - updatedFramework = GetDualCompatibilityFrameworkIfNeeded(frameworkName, secondaryFramework); - } - - targetFrameworkInformation.FrameworkName = updatedFramework; - - packageSpec.TargetFrameworks.Add(targetFrameworkInformation); - } - - private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) - { - if (secondaryFramework != default) - { - return new DualCompatibilityFramework(frameworkName, secondaryFramework); - } - - return frameworkName; - } - - private static bool ValidateDependencyTarget(LibraryDependencyTarget targetValue) - { - var isValid = false; - - switch (targetValue) - { - case LibraryDependencyTarget.Package: - case LibraryDependencyTarget.Project: - case LibraryDependencyTarget.ExternalProject: - isValid = true; - break; - } - - return isValid; +#pragma warning disable CS0612 // Type or member is obsolete + AddTargetFramework(packageSpec, frameworkName, secondaryFramework, targetFrameworkInformation); +#pragma warning restore CS0612 // Type or member is obsolete } } } diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs index 5fd68eee7ed..489bf89ed54 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.cs @@ -19,7 +19,7 @@ namespace NuGet.ProjectModel { - public static class JsonPackageSpecReader + public static partial class JsonPackageSpecReader { private static readonly char[] DelimitedStringSeparators = { ' ', ',' }; private static readonly char[] VersionSeparators = new[] { ';' }; @@ -80,7 +80,7 @@ internal static PackageSpec GetPackageSpec(Stream stream, string name, string pa var useNj = environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING"); if (string.IsNullOrEmpty(useNj) || useNj.Equals("false", StringComparison.OrdinalIgnoreCase)) { - return Utf8JsonStreamPackageSpecReader.GetPackageSpec(stream, name, packageSpecPath, snapshotValue); + return GetPackageSpecUtf8JsonStreamReader(stream, name, packageSpecPath, snapshotValue); } else { @@ -1792,6 +1792,12 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader } }, out frameworkLine, out frameworkColumn); + AddTargetFramework(packageSpec, frameworkName, secondaryFramework, targetFrameworkInformation); + } + + [Obsolete] + private static void AddTargetFramework(PackageSpec packageSpec, NuGetFramework frameworkName, NuGetFramework secondaryFramework, TargetFrameworkInformation targetFrameworkInformation) + { NuGetFramework updatedFramework = frameworkName; if (targetFrameworkInformation.Imports.Count > 0) @@ -1817,6 +1823,7 @@ private static void ReadTargetFrameworks(PackageSpec packageSpec, JsonTextReader packageSpec.TargetFrameworks.Add(targetFrameworkInformation); } + [Obsolete] private static NuGetFramework GetDualCompatibilityFrameworkIfNeeded(NuGetFramework frameworkName, NuGetFramework secondaryFramework) { diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index 343959c278b..5099f459a54 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -3850,7 +3850,7 @@ public void PackageSpecReader_Read(IEnvironmentVariableReader environmentVariabl NuGetFramework framework = NuGetFramework.Parse(frameworkPropertyName); var dependencies = new List(); - Utf8JsonStreamPackageSpecReader.ReadCentralTransitiveDependencyGroup( + JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( jsonReader: ref reader, results: dependencies, packageSpecPath: "SomePath"); From 4db5fea899aa80ed51a4e8e432f78002cba27b63 Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Mon, 18 Dec 2023 12:46:30 -0800 Subject: [PATCH 19/20] restructure class --- ...nPackageSpecReader.Utf8JsonStreamReader.cs | 181 ++++++++++-------- .../JsonPackageSpecReaderTests.cs | 19 ++ 2 files changed, 120 insertions(+), 80 deletions(-) diff --git a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs index 28fa93ecc2c..c15205fd750 100644 --- a/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs +++ b/src/NuGet.Core/NuGet.ProjectModel/JsonPackageSpecReader.Utf8JsonStreamReader.cs @@ -284,8 +284,8 @@ internal static void ReadCentralTransitiveDependencyGroup( { while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) { - var propertyName = jsonReader.GetString(); - if (string.IsNullOrEmpty(propertyName)) + var libraryName = jsonReader.GetString(); + if (string.IsNullOrEmpty(libraryName)) { throw FileFormatException.Create( "Unable to resolve dependency ''.", @@ -294,91 +294,112 @@ internal static void ReadCentralTransitiveDependencyGroup( if (jsonReader.Read()) { - var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; - var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; - var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; - string dependencyVersionValue = null; + var libraryDependency = ReadLibraryDependency(ref jsonReader, packageSpecPath, libraryName); + results.Add(libraryDependency); + } + } + } + } - if (jsonReader.TokenType == JsonTokenType.String) - { - dependencyVersionValue = jsonReader.GetString(); - } - else if (jsonReader.TokenType == JsonTokenType.StartObject) - { - while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) - { - if (jsonReader.ValueTextEquals(ExcludePropertyName)) - { - var values = jsonReader.ReadDelimitedString(); - dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - } - else if (jsonReader.ValueTextEquals(IncludePropertyName)) - { - var values = jsonReader.ReadDelimitedString(); - dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - } - else if (jsonReader.ValueTextEquals(SuppressParentPropertyName)) - { - var values = jsonReader.ReadDelimitedString(); - suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); - } - else if (jsonReader.ValueTextEquals(VersionPropertyName)) - { - if (jsonReader.Read()) - { - dependencyVersionValue = jsonReader.GetString(); - } - } - else - { - jsonReader.Skip(); - } - } - } + private static LibraryDependency ReadLibraryDependency(ref Utf8JsonStreamReader jsonReader, string packageSpecPath, string libraryName) + { + var dependencyIncludeFlagsValue = LibraryIncludeFlags.All; + var dependencyExcludeFlagsValue = LibraryIncludeFlags.None; + var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent; + string dependencyVersionValue = null; - VersionRange dependencyVersionRange = null; + if (jsonReader.TokenType == JsonTokenType.String) + { + dependencyVersionValue = jsonReader.GetString(); + } + else if (jsonReader.TokenType == JsonTokenType.StartObject) + { + ReadCentralTransitiveDependencyGroupProperties( + ref jsonReader, + ref dependencyIncludeFlagsValue, + ref dependencyExcludeFlagsValue, + ref suppressParentFlagsValue, + ref dependencyVersionValue); + } - if (!string.IsNullOrEmpty(dependencyVersionValue)) - { - try - { - dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); - } - catch (Exception ex) - { - throw FileFormatException.Create( - ex, - packageSpecPath); - } - } + VersionRange dependencyVersionRange = null; - if (dependencyVersionRange == null) - { - throw FileFormatException.Create( - new ArgumentException(Strings.MissingVersionOnDependency), - packageSpecPath); - } + if (!string.IsNullOrEmpty(dependencyVersionValue)) + { + try + { + dependencyVersionRange = VersionRange.Parse(dependencyVersionValue); + } + catch (Exception ex) + { + throw FileFormatException.Create( + ex, + packageSpecPath); + } + } - // the dependency flags are: Include flags - Exclude flags - var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; - var libraryDependency = new LibraryDependency() - { - LibraryRange = new LibraryRange() - { - Name = propertyName, - TypeConstraint = LibraryDependencyTarget.Package, - VersionRange = dependencyVersionRange - }, + if (dependencyVersionRange == null) + { + throw FileFormatException.Create( + new ArgumentException(Strings.MissingVersionOnDependency), + packageSpecPath); + } - IncludeType = includeFlags, - SuppressParent = suppressParentFlagsValue, - VersionCentrallyManaged = true, - ReferenceType = LibraryDependencyReferenceType.Transitive - }; + // the dependency flags are: Include flags - Exclude flags + var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue; + var libraryDependency = new LibraryDependency() + { + LibraryRange = new LibraryRange() + { + Name = libraryName, + TypeConstraint = LibraryDependencyTarget.Package, + VersionRange = dependencyVersionRange + }, + + IncludeType = includeFlags, + SuppressParent = suppressParentFlagsValue, + VersionCentrallyManaged = true, + ReferenceType = LibraryDependencyReferenceType.Transitive + }; + + return libraryDependency; + } - results.Add(libraryDependency); + private static void ReadCentralTransitiveDependencyGroupProperties( + ref Utf8JsonStreamReader jsonReader, + ref LibraryIncludeFlags dependencyIncludeFlagsValue, + ref LibraryIncludeFlags dependencyExcludeFlagsValue, + ref LibraryIncludeFlags suppressParentFlagsValue, + ref string dependencyVersionValue) + { + while (jsonReader.Read() && jsonReader.TokenType == JsonTokenType.PropertyName) + { + if (jsonReader.ValueTextEquals(ExcludePropertyName)) + { + var values = jsonReader.ReadDelimitedString(); + dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(IncludePropertyName)) + { + var values = jsonReader.ReadDelimitedString(); + dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(SuppressParentPropertyName)) + { + var values = jsonReader.ReadDelimitedString(); + suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(values); + } + else if (jsonReader.ValueTextEquals(VersionPropertyName)) + { + if (jsonReader.Read()) + { + dependencyVersionValue = jsonReader.GetString(); } } + else + { + jsonReader.Skip(); + } } } @@ -511,8 +532,8 @@ private static void ReadDependencies( catch (Exception ex) { throw FileFormatException.Create( - ex, - packageSpecPath); + ex, + packageSpecPath); } } diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index 5099f459a54..6f54bb48d66 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -228,6 +228,24 @@ public void PackageSpecReader_PackOptions_Default(IEnvironmentVariableReader env Assert.Empty(actual.PackOptions.PackageType); } + + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader), @" + ""packOptions"": { + ""packageType"": ""foo"" + } + }")] + public void PackageSpecReader_Malformed_Default(IEnvironmentVariableReader environmentVariableReader, string json) + { + // Arrange & Act + var actual = GetPackageSpec(json, "TestProject", "project.json", null, environmentVariableReader); + + // Assert + Assert.NotNull(actual.PackOptions); + Assert.NotNull(actual.PackOptions.PackageType); + Assert.Empty(actual.PackOptions.PackageType); + } + [Theory] [MemberData(nameof(TestEnvironmentVariableReader), @"{ ""packOptions"": { @@ -270,6 +288,7 @@ public void PackageSpecReader_PackOptions_ValidPackageType(IEnvironmentVariableR Assert.Equal(expected, actual.PackOptions.PackageType.ToArray()); } + [Theory] [MemberData(nameof(TestEnvironmentVariableReader), @"{ ""packOptions"": { From c01a50910c9a67a0e536854c8c73263caf71c48a Mon Sep 17 00:00:00 2001 From: "Jonatan Gonzalez (HE/HIM) (from Dev Box)" Date: Mon, 18 Dec 2023 14:00:21 -0800 Subject: [PATCH 20/20] added unit test --- .../JsonPackageSpecReaderTests.cs | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs index 6f54bb48d66..ee0288bb3b9 100644 --- a/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs +++ b/test/NuGet.Core.Tests/NuGet.ProjectModel.Test/JsonPackageSpecReaderTests.cs @@ -3918,6 +3918,61 @@ public void PackageSpecReader_Read(IEnvironmentVariableReader environmentVariabl Assert.True(secondGroup.TransitiveDependencies.First().VersionCentrallyManaged); } + + [Theory] + [MemberData(nameof(TestEnvironmentVariableReader))] + public void PackageSpecReader_Malformed_Exception(IEnvironmentVariableReader environmentVariableReader) + { + // Arrange + var json = @" +{ + "".NETCoreApp,Version=v3.1"": { + ""Foo"":"; + + // Act + var results = new List(); + if (environmentVariableReader.GetEnvironmentVariable("NUGET_EXPERIMENTAL_USE_NJ_FOR_FILE_PARSING").Equals(bool.FalseString, StringComparison.OrdinalIgnoreCase)) + { + Assert.ThrowsAny(() => + { + using Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + var reader = new Utf8JsonStreamReader(stream); + + if (reader.TokenType == JsonTokenType.StartObject) + { + reader.Read(); + NuGetFramework framework = NuGetFramework.Parse(reader.GetString()); + var dependencies = new List(); + + JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( + jsonReader: ref reader, + results: dependencies, + packageSpecPath: "SomePath"); + results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); + } + }); + } + else + { + using (var stringReader = new StringReader(json.ToString())) + using (var jsonReader = new JsonTextReader(stringReader)) + { + jsonReader.Read(); + jsonReader.Read(); + var dependencies = new List(); + NuGetFramework framework = NuGetFramework.Parse((string)jsonReader.Value); + JsonPackageSpecReader.ReadCentralTransitiveDependencyGroup( + jsonReader: jsonReader, + results: dependencies, + packageSpecPath: "SomePath"); + results.Add(new CentralTransitiveDependencyGroup(framework, dependencies)); + } + // Assert + Assert.Equal(1, results.Count); + var firstGroup = results.ElementAt(0); + } + } + [Theory] [MemberData(nameof(TestEnvironmentVariableReader))] public void GetPackageSpec_WithSecondaryFrameworks_ReturnsTargetFrameworkInformationWithDualCompatibilityFramework(IEnvironmentVariableReader environmentVariableReader)