Skip to content

Commit 18dc8c0

Browse files
committed
Make casting to string non nullable, make casting null byte[] throw, make (string null) constructor throw, fix add methods to not store raw nulls
1 parent 790d82d commit 18dc8c0

6 files changed

Lines changed: 54 additions & 25 deletions

File tree

ValveKeyValue/ValveKeyValue.Test/ConversionCoverageTestCase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,9 @@ public void ImplicitByteArrayToKVObject()
213213
}
214214

215215
[Test]
216-
public void NullByteArrayToKVObjectIsNull()
216+
public void NullByteArrayToKVObjectThrows()
217217
{
218-
KVObject v = (byte[])null;
219-
Assert.That(v.IsNull, Is.True);
218+
Assert.That(() => { KVObject v = (byte[])null!; }, Throws.ArgumentNullException);
220219
}
221220

222221
#endregion

ValveKeyValue/ValveKeyValue.Test/EdgeCaseTestCase.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,16 @@ public void EmptyArrayIteratesEmpty()
336336
Assert.That(items, Is.Empty);
337337
}
338338

339+
[Test]
340+
public void AddNullElementToArrayStoresNullType()
341+
{
342+
var obj = KVObject.Array();
343+
obj.Add((KVObject)null!);
344+
345+
Assert.That(obj.Count, Is.EqualTo(1));
346+
Assert.That(obj[0].IsNull, Is.True);
347+
}
348+
339349
#endregion
340350

341351
#region KVObject flag mutation
@@ -501,6 +511,26 @@ public void TryAddAlwaysReturnsTrueForListCollection()
501511
Assert.That(obj.Count, Is.EqualTo(2));
502512
}
503513

514+
[Test]
515+
public void AddNullValueStoresNullType()
516+
{
517+
var obj = KVObject.ListCollection();
518+
obj.Add("key", null!);
519+
520+
Assert.That(obj.Count, Is.EqualTo(1));
521+
Assert.That(obj["key"].IsNull, Is.True);
522+
}
523+
524+
[Test]
525+
public void TryAddNullValueStoresNullType()
526+
{
527+
var obj = KVObject.Collection();
528+
obj.TryAdd("key", null!);
529+
530+
Assert.That(obj.Count, Is.EqualTo(1));
531+
Assert.That(obj["key"].IsNull, Is.True);
532+
}
533+
504534
#endregion
505535

506536
#region CreateArray from KVObject enumerable

ValveKeyValue/ValveKeyValue.Test/KVObjectApiTestCase.cs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,9 @@ public void ConstructorWithIntPtr()
130130
}
131131

132132
[Test]
133-
public void ConstructorWithNullString()
133+
public void ConstructorWithNullStringThrows()
134134
{
135-
var obj = new KVObject((string)null);
136-
Assert.That(obj.ValueType, Is.EqualTo(KVValueType.Null));
137-
Assert.That(obj.IsNull, Is.True);
135+
Assert.That(() => new KVObject((string)null!), Throws.ArgumentNullException);
138136
}
139137

140138
#endregion
@@ -580,12 +578,9 @@ public void KV3DeserializationChildrenIterable()
580578
#region Null string handling
581579

582580
[Test]
583-
public void NullStringProducesNullTypedKVObject()
581+
public void NullStringImplicitOperatorThrows()
584582
{
585-
KVObject value = (string)null;
586-
587-
Assert.That(value.ValueType, Is.EqualTo(KVValueType.Null));
588-
Assert.That(value.IsNull, Is.True);
583+
Assert.That(() => { KVObject value = (string)null!; }, Throws.ArgumentNullException);
589584
}
590585

591586
#endregion

ValveKeyValue/ValveKeyValue.Test/KVObjectCastTestCase.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,18 @@ static IEnumerable CommonFailures
264264
}
265265
}
266266

267+
[Test]
268+
public void CastingNullKVObjectToStringThrows()
269+
{
270+
Assert.That(() => (string)(KVObject)null!, Throws.InstanceOf<NullReferenceException>());
271+
}
272+
273+
[Test]
274+
public void CastingNullKVObjectToInt32Throws()
275+
{
276+
Assert.That(() => (int)(KVObject)null!, Throws.InstanceOf<NullReferenceException>());
277+
}
278+
267279
[TestCase(typeof(bool))]
268280
[TestCase(typeof(byte))]
269281
[TestCase(typeof(char))]

ValveKeyValue/ValveKeyValue/KVObject.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,10 @@ public KVObject()
6969

7070
/// <summary>
7171
/// Initializes a new instance of the <see cref="KVObject"/> class with a string value.
72-
/// If <paramref name="value"/> is <c>null</c>, creates a null-valued instance.
7372
/// </summary>
7473
public KVObject(string value)
7574
{
76-
if (value is null)
77-
{
78-
ValueType = KVValueType.Null;
79-
return;
80-
}
81-
75+
ArgumentNullException.ThrowIfNull(value);
8276
ValueType = KVValueType.String;
8377
_ref = value;
8478
}
@@ -322,7 +316,7 @@ public bool ContainsKey(string name)
322316
public void Add(string key, KVObject value)
323317
{
324318
ArgumentNullException.ThrowIfNull(key);
325-
TryInsert(key, value, InsertionBehavior.ThrowOnExisting);
319+
TryInsert(key, value ?? Null(), InsertionBehavior.ThrowOnExisting);
326320
}
327321

328322
/// <summary>
@@ -333,7 +327,7 @@ public void Add(string key, KVObject value)
333327
public bool TryAdd(string key, KVObject value)
334328
{
335329
ArgumentNullException.ThrowIfNull(key);
336-
return TryInsert(key, value, InsertionBehavior.None);
330+
return TryInsert(key, value ?? Null(), InsertionBehavior.None);
337331
}
338332

339333
/// <summary>
@@ -346,7 +340,7 @@ public void Add(KVObject value)
346340
throw new InvalidOperationException($"Cannot add an array element to a {ValueType} value.");
347341
}
348342

349-
GetArrayList().Add(value);
343+
GetArrayList().Add(value ?? Null());
350344
}
351345

352346
/// <summary>

ValveKeyValue/ValveKeyValue/KVObject_operators.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,14 @@ public partial class KVObject
4444
public static implicit operator KVObject(IntPtr value) => new(value);
4545

4646
/// <summary>Implicit cast from <see langword="byte[]"/> to <see cref="KVObject"/>.</summary>
47-
public static implicit operator KVObject(byte[] value)
48-
=> value is null ? Null() : Blob(value);
47+
public static implicit operator KVObject(byte[] value) => Blob(value);
4948

5049
#endregion
5150

5251
#region Explicit operators (TO primitives)
5352

5453
/// <summary>Explicit cast from <see cref="KVObject"/> to <see cref="string"/>.</summary>
55-
public static explicit operator string?(KVObject obj) => obj?.ToString(null); // TODO: Perhaps this should throw like the rest of the operators
54+
public static explicit operator string(KVObject obj) => obj.ToString(null);
5655

5756
/// <summary>Explicit cast from <see cref="KVObject"/> to <see cref="int"/>.</summary>
5857
public static explicit operator int(KVObject obj) => obj.ToInt32(null);

0 commit comments

Comments
 (0)