118 lines
3.7 KiB
C#
118 lines
3.7 KiB
C#
// 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.Dynamic;
|
|
|
|
namespace Microsoft.AspNetCore.JsonPatch.Internal
|
|
{
|
|
/// <remarks>
|
|
/// <para>
|
|
/// This class is used specifically to test that JSON patch "replace" operations are functionally equivalent to
|
|
/// "add" and "remove" operations applied sequentially using the same path.
|
|
/// </para>
|
|
/// <para>
|
|
/// This is done by asserting that no value exists for a particular key before setting its value. To replace the
|
|
/// value for a key, the key must first be removed, and then re-added with the new value.
|
|
/// </para>
|
|
/// <para>
|
|
/// See JsonPatch#110 for further details.
|
|
/// </para>
|
|
/// </remarks>
|
|
public class WriteOnceDynamicTestObject : DynamicObject
|
|
{
|
|
private Dictionary<string, object> _dictionary = new Dictionary<string, object>();
|
|
|
|
public object this[string key] { get => ((IDictionary<string, object>)_dictionary)[key]; set => SetValueForKey(key, value); }
|
|
|
|
public ICollection<string> Keys => ((IDictionary<string, object>)_dictionary).Keys;
|
|
|
|
public ICollection<object> Values => ((IDictionary<string, object>)_dictionary).Values;
|
|
|
|
public int Count => ((IDictionary<string, object>)_dictionary).Count;
|
|
|
|
public bool IsReadOnly => ((IDictionary<string, object>)_dictionary).IsReadOnly;
|
|
|
|
public void Add(string key, object value)
|
|
{
|
|
SetValueForKey(key, value);
|
|
}
|
|
|
|
public void Add(KeyValuePair<string, object> item)
|
|
{
|
|
SetValueForKey(item.Key, item.Value);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
((IDictionary<string, object>)_dictionary).Clear();
|
|
}
|
|
|
|
public bool Contains(KeyValuePair<string, object> item)
|
|
{
|
|
return ((IDictionary<string, object>)_dictionary).Contains(item);
|
|
}
|
|
|
|
public bool ContainsKey(string key)
|
|
{
|
|
return ((IDictionary<string, object>)_dictionary).ContainsKey(key);
|
|
}
|
|
|
|
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
|
|
{
|
|
((IDictionary<string, object>)_dictionary).CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
|
|
{
|
|
return ((IDictionary<string, object>)_dictionary).GetEnumerator();
|
|
}
|
|
|
|
public bool Remove(string key)
|
|
{
|
|
return ((IDictionary<string, object>)_dictionary).Remove(key);
|
|
}
|
|
|
|
public bool Remove(KeyValuePair<string, object> item)
|
|
{
|
|
return ((IDictionary<string, object>)_dictionary).Remove(item);
|
|
}
|
|
|
|
public bool TryGetValue(string key, out object value)
|
|
{
|
|
return ((IDictionary<string, object>)_dictionary).TryGetValue(key, out value);
|
|
}
|
|
|
|
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
|
{
|
|
var name = binder.Name;
|
|
|
|
return TryGetValue(name, out result);
|
|
}
|
|
|
|
public override bool TrySetMember(SetMemberBinder binder, object value)
|
|
{
|
|
SetValueForKey(binder.Name, value);
|
|
|
|
return true;
|
|
}
|
|
|
|
private void SetValueForKey(string key, object value)
|
|
{
|
|
if (value == null)
|
|
{
|
|
_dictionary.Remove(key);
|
|
return;
|
|
}
|
|
|
|
if (_dictionary.ContainsKey(key))
|
|
{
|
|
throw new ArgumentException($"Value for {key} already exists");
|
|
}
|
|
|
|
_dictionary[key] = value;
|
|
}
|
|
}
|
|
}
|