Say that a null is no string, except where an array or an object holds it - #2477
Merged
Merged
Conversation
…s it Nullable_null_at_top_level says a null asked for as an int? at the top level comes to nothing: there is no enclosing structure to hold it, and TryTransform cannot report one. Nothing said the same of a string, the one scalar that can hold a null without a Nullable<> around it - nor what becomes of a null that is asked for as a string further in. Thirteen contract tests pin it: - String_from_null, Uri_from_null and Person_from_null: at the top level there is none, whatever the type. - String_from_single_item_array_with_null, String_from_typed_value_with_null, String_from_Property_with_null_value and String_from_VertexProperty_with_null_value: unwrapping a null does not make it a string. - Property_of_string_from_null and VertexProperty_of_string_from_null: nor is it the value of a property that a scalar is wrapped into. - Strings_from_Array_with_null: in an array it survives as a null, as Nullable_null has it for an int?. - Constructor_arguments_from_null, Member_from_null and Language_with_null_property_value: in an object, a constructor argument is passed the null and a member is left as it was. A snapshot leaves out a member that is null and writes one that is empty, so these tell the two apart. Tests only: this implementation already answers all thirteen. Measured against the other one before its fix, it answered ten of them with the empty string in place of the null - all but Uri_from_null, Person_from_null and Strings_from_Array_with_null. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 14.x #2477 +/- ##
==========================================
+ Coverage 93.59% 93.64% +0.05%
==========================================
Files 279 279
Lines 7903 7903
Branches 885 885
==========================================
+ Hits 7397 7401 +4
+ Misses 313 311 -2
+ Partials 193 191 -2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
A JSON
nullthat is asked for as astringis no string: at the top level it declines, as it does for anint?, aUrior aPerson, and it is never read as the empty string. Inside an array it stays a null, and inside an object it leaves the member it belongs to as it was. That is the answer this implementation already gives. Until now nothing pinned it, and the System.Text.Json implementation in Gremlinq.Extensions read such a null as"", so a vertex whose string property is null came back with an empty string in its place.Tests only.
Changes
Nullable_null_at_top_level, which says the same of anint?:String_from_null,Uri_from_nullandPerson_from_null: at the top level there is nothing to hold a null, whatever the requested type.String_from_single_item_array_with_null,String_from_typed_value_with_null,String_from_Property_with_null_valueandString_from_VertexProperty_with_null_value: unwrapping a null does not make it a string.Property_of_string_from_nullandVertexProperty_of_string_from_null: a null is not the value of a property that a scalar is wrapped into either.Strings_from_Array_with_null: in an array the null survives, asNullable_nullhas it for anint?.Constructor_arguments_from_null,Member_from_nullandLanguage_with_null_property_value: a constructor argument is passed the null, and a member is left as it was, also when the null arrives inside a vertex property. A snapshot leaves out a member that is null and writes one that is empty, so these tell the two apart.Notes
version.jsonis left alone.Uri_from_null,Person_from_nullandStrings_from_Array_with_nullit already answered the same way. Its fix is Gremlinq.Extensions#214.Property<string>orVertexProperty<string>whosevalueis null throws theArgumentNullExceptionof its constructor, here and for any other value type that can hold a null (Property<int?>). Declining instead would need a change to this implementation.Dictionary<string, string>orDictionary<string, int?>is kept as a null entry, while in ag:Mapthe entry is left out; read as aDictionary<string, int>the plain object throws anArgumentNullException.Support.NewtonsoftJson.Testson net10.0: 312, up from 299, all green.dotnet build ExRam.Gremlinq.slnxsucceeds with 0 warnings.🤖 Generated with Claude Code