Skip to content

Commit

Permalink
Fixed issue with FastDynamicObject.CopyTo.
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshClose committed Apr 26, 2024
1 parent 83d3951 commit 78a0ac9
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 25 deletions.
17 changes: 15 additions & 2 deletions src/CsvHelper/FastDynamicObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Linq.Expressions;
Expand Down Expand Up @@ -83,9 +84,21 @@ DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)

void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
foreach (var item in array)
if (arrayIndex < 0 || arrayIndex >= array.Length)
{
SetValue(item.Key, item.Value);
throw new ArgumentOutOfRangeException($"{nameof(arrayIndex)} must be greater than or equal to 0 and less then {nameof(array)} length.");
}

if (dict.Count + arrayIndex > array.Length)
{
throw new ArgumentException($"The number of elements in {nameof(FastDynamicMetaObject)} is greater than the available space from {nameof(arrayIndex)} to the end of the destination {nameof(array)}.");
}

var i = arrayIndex;
foreach (var pair in dict)
{
array[i] = pair;
i++;
}
}

Expand Down
4 changes: 2 additions & 2 deletions tests/CsvHelper.Tests/CsvHelper.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0;net7.0;net6.0;net48;net47;net462</TargetFrameworks>
<!--<TargetFrameworks>net8.0</TargetFrameworks>-->
<!--<TargetFrameworks>net8.0;net7.0;net6.0;net48;net47;net462</TargetFrameworks>-->
<TargetFrameworks>net8.0</TargetFrameworks>
<LangVersion>preview</LangVersion>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>CsvHelper.snk</AssemblyOriginatorKeyFile>
Expand Down
21 changes: 0 additions & 21 deletions tests/CsvHelper.Tests/Dynamic/CsvRowDynamicObjectTests.cs

This file was deleted.

99 changes: 99 additions & 0 deletions tests/CsvHelper.Tests/Dynamic/FastDynamicTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using Xunit;

namespace CsvHelper.Tests.Dynamic
{
public class FastDynamicObjectTests
{
[Fact]
public void Dynamic_SetAndGet_Works()
{
dynamic obj = new FastDynamicObject();
obj.Id = 1;
obj.Name = "one";

var id = obj.Id;
var name = obj.Name;

Assert.Equal(1, id);
Assert.Equal("one", name);
}

[Fact]
public void CopyTo_NegativeIndex_Throws()
{
IDictionary<string, object> d = new FastDynamicObject();
var a = new KeyValuePair<string, object>[1];

Assert.Throws<ArgumentOutOfRangeException>(() => d.CopyTo(a, -1));
}

[Fact]
public void CopyTo_IndexLargerThanArrayLength_Throws()
{
IDictionary<string, object> d = new FastDynamicObject();
var a = new KeyValuePair<string, object>[1];

Assert.Throws<ArgumentOutOfRangeException>(() => d.CopyTo(a, a.Length));
}

[Fact]
public void CopyTo_SourceIsLargerThanDestination_Throws()
{
IDictionary<string, object> d = new FastDynamicObject();
d["a"] = 1;
d["b"] = 2;
var a = new KeyValuePair<string, object>[1];

Assert.Throws<ArgumentException>(() => d.CopyTo(a, 0));
}

[Fact]
public void CopyTo_IndexGreaterThanZeroAndSourceIsLargerThanDestination_Throws()
{
IDictionary<string, object> d = new FastDynamicObject();
d["a"] = 1;
d["b"] = 2;
var a = new KeyValuePair<string, object>[2];

Assert.Throws<ArgumentException>(() => d.CopyTo(a, 1));
}

[Fact]
public void CopyTo_StartAtZero_Copies()
{
IDictionary<string, object> d = new FastDynamicObject();
d["a"] = 1;
d["b"] = 2;
var a = new KeyValuePair<string, object>[2];

d.CopyTo(a, 0);

Assert.Equal("a", a[0].Key);
Assert.Equal(1, a[0].Value);
Assert.Equal("b", a[1].Key);
Assert.Equal(2, a[1].Value);
}

[Fact]
public void CopyTo_StartGreaterThanZero_Copies()
{
IDictionary<string, object> d = new FastDynamicObject();
d["a"] = 1;
d["b"] = 2;
var a = new KeyValuePair<string, object>[4];

d.CopyTo(a, 1);

Assert.Null(a[0].Key);
Assert.Null(a[0].Value);
Assert.Equal("a", a[1].Key);
Assert.Equal(1, a[1].Value);
Assert.Equal("b", a[2].Key);
Assert.Equal(2, a[2].Value);
Assert.Null(a[3].Key);
Assert.Null(a[3].Value);
}
}
}

0 comments on commit 78a0ac9

Please sign in to comment.