-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add unit test for https://github.com/dotnet/msbuild/pull/8870 #8961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
2ad1376
Add unit test for https://github.com/dotnet/msbuild/pull/8870
JaynieBai 0b33dbe
Merge branch 'main' of https://github.com/jehhynes/msbuild into jenny…
JaynieBai 2ed3327
Add the output verification
JaynieBai 3a406e0
write an entirely new, minimal IDictionary implementation
JaynieBai 25179b4
Merge branch 'main' of https://github.com/dotnet/msbuild into jennyba…
JaynieBai File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
210 changes: 210 additions & 0 deletions
210
src/Build.UnitTests/BackEnd/TaskThatReturnsDictionaryTaskItem.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System; | ||
| using System.Collections; | ||
| using System.Collections.Generic; | ||
| using Microsoft.Build.Framework; | ||
|
|
||
| #nullable disable | ||
|
|
||
| namespace Microsoft.Build.Engine.UnitTests; | ||
| /// <summary> | ||
| /// Task that returns a custom ITaskItem implementation that has a custom IDictionary type returned from CloneCustomMetadata() | ||
| /// </summary> | ||
| public sealed class TaskThatReturnsDictionaryTaskItem : Utilities.Task | ||
| { | ||
| public string Key { get; set; } | ||
| public string Value { get; set; } | ||
|
|
||
| public override bool Execute() | ||
| { | ||
| var metaValue = new MinimalDictionary<string, string> | ||
| { | ||
| { Key, Value } | ||
| }; | ||
| DictionaryTaskItemOutput = new MinimalDictionaryTaskItem(metaValue); | ||
| return true; | ||
| } | ||
|
|
||
| [Output] | ||
| public ITaskItem DictionaryTaskItemOutput { get; set; } | ||
|
|
||
| internal sealed class MinimalDictionaryTaskItem : ITaskItem | ||
| { | ||
| private MinimalDictionary<string, string> _metaData = new MinimalDictionary<string, string>(); | ||
|
|
||
| public MinimalDictionaryTaskItem(MinimalDictionary<string, string> metaValue) | ||
| { | ||
| _metaData = metaValue; | ||
| } | ||
|
|
||
| public string ItemSpec { get => $"{nameof(MinimalDictionaryTaskItem)}spec"; set => throw new NotImplementedException(); } | ||
|
|
||
| public ICollection MetadataNames => throw new NotImplementedException(); | ||
|
|
||
| public int MetadataCount => throw new NotImplementedException(); | ||
|
|
||
| ICollection ITaskItem.MetadataNames => throw new NotImplementedException(); | ||
|
|
||
| public IDictionary CloneCustomMetadata() => _metaData; | ||
|
|
||
| public string GetMetadata(string metadataName) | ||
| { | ||
| if (String.IsNullOrEmpty(metadataName)) | ||
| { | ||
| throw new ArgumentNullException(nameof(metadataName)); | ||
| } | ||
|
|
||
| string value = (string)_metaData[metadataName]; | ||
| return value; | ||
| } | ||
|
|
||
| public void SetMetadata(string metadataName, string metadataValue) => throw new NotImplementedException(); | ||
| public void RemoveMetadata(string metadataName) => throw new NotImplementedException(); | ||
| public void CopyMetadataTo(ITaskItem destinationItem) => throw new NotImplementedException(); | ||
| } | ||
| } | ||
|
|
||
| public sealed class MinimalDictionary<TKey, TValue> : IDictionary | ||
| { | ||
| private List<TKey> _keys = new List<TKey>(); | ||
| private List<TValue> _values = new List<TValue>(); | ||
|
|
||
| public object this[object key] | ||
| { | ||
| get | ||
| { | ||
| int index = _keys.IndexOf((TKey)key); | ||
| return index == -1 ? throw new KeyNotFoundException() : (object)_values[index]; | ||
| } | ||
| set | ||
| { | ||
| int index = _keys.IndexOf((TKey)key); | ||
| if (index == -1) | ||
| { | ||
| _keys.Add((TKey)key); | ||
| _values.Add((TValue)value); | ||
| } | ||
| else | ||
| { | ||
| _values[index] = (TValue)value; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public bool IsFixedSize => false; | ||
|
|
||
| public bool IsReadOnly => false; | ||
|
|
||
| public ICollection Keys => _keys; | ||
|
|
||
| public ICollection Values => _values; | ||
|
|
||
| public int Count => _keys.Count; | ||
|
|
||
| public bool IsSynchronized => false; | ||
|
|
||
| public object SyncRoot => throw new NotSupportedException(); | ||
|
|
||
| public void Add(object key, object value) | ||
| { | ||
| if (_keys.Contains((TKey)key)) | ||
| { | ||
| throw new ArgumentException("An item with the same key has already been added."); | ||
| } | ||
|
|
||
| _keys.Add((TKey)key); | ||
| _values.Add((TValue)value); | ||
| } | ||
|
|
||
| public void Clear() | ||
| { | ||
| _keys.Clear(); | ||
| _values.Clear(); | ||
| } | ||
|
|
||
| public bool Contains(object key) | ||
| { | ||
| return _keys.Contains((TKey)key); | ||
| } | ||
|
|
||
| public void CopyTo(Array array, int index) | ||
| { | ||
| if (array == null) | ||
| { | ||
| throw new ArgumentNullException(nameof(array)); | ||
| } | ||
|
|
||
| if (array.Rank != 1) | ||
| { | ||
| throw new ArgumentException("Array must be one-dimensional.", nameof(array)); | ||
| } | ||
|
|
||
| if (index < 0 || index > array.Length) | ||
| { | ||
| throw new ArgumentOutOfRangeException(nameof(index)); | ||
| } | ||
|
|
||
| if (array.Length - index < Count) | ||
| { | ||
| throw new ArgumentException("The number of elements in the source is greater than the available space from index to the end of the destination array."); | ||
| } | ||
|
|
||
| for (int i = 0; i < Count; i++) | ||
| { | ||
| array.SetValue(new KeyValuePair<TKey, TValue>(_keys[i], _values[i]), index + i); | ||
| } | ||
| } | ||
|
|
||
| public IDictionaryEnumerator GetEnumerator() => new MinimalDictionaryEnumerator(_keys, _values); | ||
|
|
||
| public void Remove(object key) | ||
| { | ||
| int index = _keys.IndexOf((TKey)key); | ||
| if (index != -1) | ||
| { | ||
| _keys.RemoveAt(index); | ||
| _values.RemoveAt(index); | ||
| } | ||
| } | ||
|
|
||
| IEnumerator IEnumerable.GetEnumerator() | ||
| { | ||
| for (int i = 0; i < Count; i++) | ||
| { | ||
| yield return new KeyValuePair<TKey, TValue>(_keys[i], _values[i]); | ||
| } | ||
| } | ||
|
|
||
| private sealed class MinimalDictionaryEnumerator : IDictionaryEnumerator | ||
| { | ||
| private List<TKey> _keys; | ||
| private List<TValue> _values; | ||
| private int _index = -1; | ||
|
|
||
| public MinimalDictionaryEnumerator(List<TKey> keys, List<TValue> values) | ||
| { | ||
| _keys = keys; | ||
| _values = values; | ||
| } | ||
|
|
||
| public object Current => Entry; | ||
|
|
||
| public object Key => _keys[_index]; | ||
|
|
||
| public object Value => _values[_index]; | ||
|
|
||
| public DictionaryEntry Entry => new DictionaryEntry(Key, Value); | ||
|
|
||
| public bool MoveNext() | ||
| { | ||
| return ++_index < _keys.Count; | ||
| } | ||
|
|
||
| public void Reset() | ||
| { | ||
| _index = -1; | ||
| } | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.