Skip to content

Commit 180e194

Browse files
authored
Merge pull request #6 from Cysharp/fix/tree-structure
fix: make recursive count works with tree structure
2 parents aec976b + 6c5025b commit 180e194

File tree

12 files changed

+655
-119
lines changed

12 files changed

+655
-119
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
using System;
2+
using FluentAssertions;
3+
using System.Collections.Generic;
4+
using System.Text;
5+
using Xunit;
6+
using System.Linq;
7+
using System.Collections.Concurrent;
8+
using System.Threading.Tasks;
9+
10+
namespace RandomFixtureKit.Tests
11+
{
12+
public class TreeStructureTest
13+
{
14+
[Fact]
15+
public void CheckArray()
16+
{
17+
FixtureFactory.Create<ArrayTreeNode>();
18+
}
19+
20+
[Fact]
21+
public void CheckArraySegment() {
22+
FixtureFactory.Create<ArraySegmentTreeNode>();
23+
}
24+
25+
[Fact]
26+
public void CheckList() {
27+
FixtureFactory.Create<ListTreeNode>();
28+
}
29+
30+
[Fact]
31+
public void CheckLinkedList() {
32+
FixtureFactory.Create<LinkedListTreeNode>();
33+
}
34+
35+
[Fact]
36+
public void CheckStack() {
37+
FixtureFactory.Create<StackTreeNode>();
38+
}
39+
40+
[Fact]
41+
public void CheckQueue() {
42+
FixtureFactory.Create<QueueTreeNode>();
43+
}
44+
45+
[Fact]
46+
public void CheckConcurrentQueue() {
47+
FixtureFactory.Create<ConcurrentQueueTreeNode>();
48+
}
49+
50+
[Fact]
51+
public void CheckConcurrentStack() {
52+
FixtureFactory.Create<ConcurrentStackTreeNode>();
53+
}
54+
55+
[Fact]
56+
public void CheckICollection() {
57+
FixtureFactory.Create<ICollectionTreeNode>();
58+
}
59+
60+
[Fact]
61+
public void CheckIEnumerable() {
62+
FixtureFactory.Create<IEnumerableTreeNode>();
63+
}
64+
65+
[Fact]
66+
public void CheckIList() {
67+
FixtureFactory.Create<IListTreeNode>();
68+
}
69+
70+
[Fact]
71+
public void CheckIReadOnlyCollection() {
72+
FixtureFactory.Create<IReadOnlyCollectionTreeNode>();
73+
}
74+
75+
[Fact]
76+
public void CheckIReadOnlyList() {
77+
FixtureFactory.Create<IReadOnlyListTreeNode>();
78+
}
79+
80+
[Fact]
81+
public void CheckDictionary() {
82+
FixtureFactory.Create<DictionaryTreeNode>();
83+
}
84+
85+
[Fact]
86+
public void CheckSortedDictionary() {
87+
FixtureFactory.Create<SortedDictionaryTreeNode>();
88+
}
89+
90+
[Fact]
91+
public void CheckSortedList() {
92+
FixtureFactory.Create<SortedListTreeNode>();
93+
}
94+
95+
[Fact]
96+
public void CheckIDictionary() {
97+
FixtureFactory.Create<IDictionaryTreeNode>();
98+
}
99+
100+
[Fact]
101+
public void CheckIReadOnlyDictionary() {
102+
FixtureFactory.Create<IReadOnlyDictionaryTreeNode>();
103+
}
104+
105+
}
106+
107+
108+
class ArrayTreeNode
109+
{
110+
public string Name { get; set; }
111+
public ArrayTreeNode[] Children { get; set; }
112+
}
113+
114+
115+
class ArraySegmentTreeNode {
116+
public string Name { get; set; }
117+
public ArraySegment<ArraySegmentTreeNode> Children { get; set; }
118+
}
119+
120+
class ListTreeNode {
121+
public string Name { get; set; }
122+
public List<ListTreeNode> Children { get; set; }
123+
}
124+
125+
class LinkedListTreeNode {
126+
public string Name { get; set; }
127+
public LinkedList<LinkedListTreeNode> Children { get; set; }
128+
}
129+
130+
class StackTreeNode {
131+
public string Name { get; set; }
132+
public Stack<StackTreeNode> Children { get; set; }
133+
}
134+
135+
class QueueTreeNode {
136+
public string Name { get; set; }
137+
public Queue<QueueTreeNode> Children { get; set; }
138+
}
139+
140+
class ConcurrentQueueTreeNode {
141+
public string Name { get; set; }
142+
public ConcurrentQueue<ConcurrentQueueTreeNode> Children { get; set; }
143+
}
144+
145+
class ConcurrentStackTreeNode {
146+
public string Name { get; set; }
147+
public ConcurrentStack<ConcurrentStackTreeNode> Children { get; set; }
148+
}
149+
150+
class ICollectionTreeNode {
151+
public string Name { get; set; }
152+
public ICollection<ICollectionTreeNode> Children { get; set; }
153+
}
154+
155+
class IEnumerableTreeNode {
156+
public string Name { get; set; }
157+
public IEnumerable<IEnumerableTreeNode> Children { get; set; }
158+
}
159+
160+
class IListTreeNode {
161+
public string Name { get; set; }
162+
public IList<IListTreeNode> Children { get; set; }
163+
}
164+
165+
class IReadOnlyCollectionTreeNode {
166+
public string Name { get; set; }
167+
public IReadOnlyCollection<IReadOnlyCollectionTreeNode> Children { get; set; }
168+
}
169+
170+
class IReadOnlyListTreeNode {
171+
public string Name { get; set; }
172+
public IReadOnlyList<IReadOnlyListTreeNode> Children { get; set; }
173+
}
174+
175+
176+
class DictionaryTreeNode {
177+
public string Name { get; set; }
178+
public Dictionary<string, DictionaryTreeNode> Children { get; set; }
179+
}
180+
181+
class SortedDictionaryTreeNode {
182+
public string Name { get; set; }
183+
public SortedDictionary<string, SortedDictionaryTreeNode> Children { get; set; }
184+
}
185+
186+
class SortedListTreeNode {
187+
public string Name { get; set; }
188+
public SortedList<string, SortedListTreeNode> Children { get; set; }
189+
}
190+
191+
class IDictionaryTreeNode {
192+
public string Name { get; set; }
193+
public IDictionary<string, IDictionaryTreeNode> Children { get; set; }
194+
}
195+
196+
class IReadOnlyDictionaryTreeNode {
197+
public string Name { get; set; }
198+
public IReadOnlyDictionary<string, IReadOnlyDictionaryTreeNode> Children { get; set; }
199+
}
200+
}

src/RandomFixtureKit.Unity/Assets/Scripts/RandomFixtureKit.Tests/Tests/TreeStructureTest.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RandomFixtureKit.Unity/Assets/Scripts/RandomFixtureKit/Generators/CollectionGenerators.cs

Lines changed: 68 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ public ArrayGenerator(Type type, int length)
1919

2020
public object Generate(in GenerationContext context)
2121
{
22-
var elemType = Type.GetElementType();
23-
var generator = context.GetGenerator(elemType);
24-
var rank = Type.GetArrayRank();
25-
26-
var array = Array.CreateInstance(elemType, Enumerable.Range(0, rank).Select(_ => length).ToArray());
27-
switch (rank)
22+
using (var scope = context.TypeStack.Enter(Type))
2823
{
29-
case 1: SetOne(array, generator, context); break;
30-
case 2: SetTwo(array, generator, context); break;
31-
case 3: SetThree(array, generator, context); break;
32-
default:
33-
throw new InvalidOperationException($"Array rank:{rank} is not supported.");
34-
}
24+
var elemType = Type.GetElementType();
25+
var generator = context.GetGenerator(elemType);
26+
var rank = Type.GetArrayRank();
27+
28+
var array = Array.CreateInstance(elemType, Enumerable.Range(0, rank).Select(_ => length).ToArray());
29+
switch (rank)
30+
{
31+
case 1: SetOne(array, generator, context); break;
32+
case 2: SetTwo(array, generator, context); break;
33+
case 3: SetThree(array, generator, context); break;
34+
default:
35+
throw new InvalidOperationException($"Array rank:{rank} is not supported.");
36+
}
3537

36-
return array;
38+
return array;
39+
}
3740
}
3841

3942
void SetOne(Array array, IGenerator generator, GenerationContext context)
@@ -85,11 +88,14 @@ public ArraySegmentGenerator(Type type, int length)
8588

8689
public object Generate(in GenerationContext context)
8790
{
88-
var elemType = type.GetGenericArguments()[0];
89-
var arrayGenerator = context.GetGenerator(elemType.MakeArrayType());
91+
using (var scope = context.TypeStack.Enter(Type))
92+
{
93+
var elemType = type.GetGenericArguments()[0];
94+
var arrayGenerator = context.GetGenerator(elemType.MakeArrayType());
9095

91-
var innerArray = arrayGenerator.Generate(context);
92-
return ReflectionHelper.CreateInstance(type, new[] { innerArray });
96+
var innerArray = arrayGenerator.Generate(context);
97+
return ReflectionHelper.CreateInstance(type, new[] { innerArray });
98+
}
9399
}
94100
}
95101

@@ -109,16 +115,19 @@ public ListGenerator(Type type, int length)
109115

110116
public object Generate(in GenerationContext context)
111117
{
112-
var elemType = type.GetGenericArguments()[0];
113-
var generator = context.GetGenerator(elemType);
114-
115-
var list = ReflectionHelper.CreateInstance(type) as IList;
116-
for (int i = 0; i < length; i++)
118+
using (var scope = context.TypeStack.Enter(Type))
117119
{
118-
list.Add(generator.Generate(context));
119-
}
120+
var elemType = type.GetGenericArguments()[0];
121+
var generator = context.GetGenerator(elemType);
120122

121-
return list;
123+
var list = ReflectionHelper.CreateInstance(type) as IList;
124+
for (int i = 0; i < length; i++)
125+
{
126+
list.Add(generator.Generate(context));
127+
}
128+
129+
return list;
130+
}
122131
}
123132
}
124133

@@ -138,19 +147,22 @@ public DictionaryGenerator(Type type, int length)
138147

139148
public object Generate(in GenerationContext context)
140149
{
141-
var genArgs = type.GetGenericArguments();
142-
var keyType = genArgs[0];
143-
var valueType = genArgs[1];
144-
var keyGenerator = context.GetGenerator(keyType);
145-
var valueGenerator = context.GetGenerator(valueType);
146-
147-
var dict = ReflectionHelper.CreateInstance(type) as IDictionary;
148-
for (int i = 0; i < length; i++)
150+
using (var scope = context.TypeStack.Enter(Type))
149151
{
150-
dict[keyGenerator.Generate(context)] = valueGenerator.Generate(context);
151-
}
152+
var genArgs = type.GetGenericArguments();
153+
var keyType = genArgs[0];
154+
var valueType = genArgs[1];
155+
var keyGenerator = context.GetGenerator(keyType);
156+
var valueGenerator = context.GetGenerator(valueType);
157+
158+
var dict = ReflectionHelper.CreateInstance(type) as IDictionary;
159+
for (int i = 0; i < length; i++)
160+
{
161+
dict[keyGenerator.Generate(context)] = valueGenerator.Generate(context);
162+
}
152163

153-
return dict;
164+
return dict;
165+
}
154166
}
155167
}
156168

@@ -169,18 +181,21 @@ public GenericReflectionCollectionGeneratorBase(Type type, int length)
169181

170182
public object Generate(in GenerationContext context)
171183
{
172-
var elemType = Type.GetGenericArguments()[0];
173-
var generator = context.GetGenerator(elemType);
184+
using (var scope = context.TypeStack.Enter(Type))
185+
{
186+
var elemType = Type.GetGenericArguments()[0];
187+
var generator = context.GetGenerator(elemType);
174188

175-
var add = Type.GetMethod(AddMethodName, new[] { elemType });
189+
var add = Type.GetMethod(AddMethodName, new[] { elemType });
176190

177-
var collection = ReflectionHelper.CreateInstance(Type);
178-
for (int i = 0; i < length; i++)
179-
{
180-
add.Invoke(collection, new[] { generator.Generate(context) });
181-
}
191+
var collection = ReflectionHelper.CreateInstance(Type);
192+
for (int i = 0; i < length; i++)
193+
{
194+
add.Invoke(collection, new[] { generator.Generate(context) });
195+
}
182196

183-
return collection;
197+
return collection;
198+
}
184199
}
185200
}
186201

@@ -249,12 +264,15 @@ public InterfaceLookupGenerator(Type type, int length)
249264

250265
public object Generate(in GenerationContext context)
251266
{
252-
var genType = type.GenericTypeArguments;
253-
var generator = context.GetGenerator(typeof(Dictionary<,>).MakeGenericType(new[] { genType[0], genType[1].MakeArrayType() }));
254-
var dictionary = generator.Generate(context);
267+
using (var scope = context.TypeStack.Enter(Type))
268+
{
269+
var genType = type.GenericTypeArguments;
270+
var generator = context.GetGenerator(typeof(Dictionary<,>).MakeGenericType(new[] { genType[0], genType[1].MakeArrayType() }));
271+
var dictionary = generator.Generate(context);
255272

256-
var lookup = ReflectionHelper.CreateInstance(typeof(PseudoLookup<,>).MakeGenericType(genType), new[] { dictionary });
257-
return lookup;
273+
var lookup = ReflectionHelper.CreateInstance(typeof(PseudoLookup<,>).MakeGenericType(genType), new[] { dictionary });
274+
return lookup;
275+
}
258276
}
259277

260278
// require to type hint to use in IL2CPP

0 commit comments

Comments
 (0)