Skip to content

Commit 330c055

Browse files
authored
- Add unit test verifying how competing/overriding parameters would work in parameter sets (#518)
1 parent c8c213a commit 330c055

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

EasyPost.Tests/ParametersTests/ParametersTest.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,57 @@ public void TestReusingParameterSets()
145145
Assert.False(parametersDictionary.ContainsKey("before_id"));
146146
}
147147

148+
[Fact]
149+
[Testing.Logic]
150+
public void TestCompetingParameters()
151+
{
152+
var parametersWithCompetingParameters = new ParameterSetWithCompetingParameters
153+
{
154+
AParam = "location1",
155+
BParam = "location2",
156+
};
157+
158+
// Both values are serializing to the same location ("location") in the dictionary, so which wins?
159+
var dictionary = parametersWithCompetingParameters.ToDictionary();
160+
161+
// It seems that BParam here wins.
162+
Assert.Equal("location2", dictionary["location"]);
163+
164+
// Is it because the properties are serialized in alphabetical order, or because BParam is the last property in the code structure?
165+
// Let's test by reversing the order of the properties.
166+
var parametersWithCompetingParametersNonAlphabetic = new ParameterSetWithCompetingParametersNonAlphabetic
167+
{
168+
// The order the properties are set in the constructor shouldn't matter.
169+
// In the source code, BParam physically comes before AParam.
170+
// We'll replicate that order here just for readability sake
171+
BParam = "location1",
172+
AParam = "location2",
173+
};
174+
175+
var dictionaryNonAlphabetic = parametersWithCompetingParametersNonAlphabetic.ToDictionary();
176+
Assert.Equal("location2", dictionaryNonAlphabetic["location"]);
177+
178+
// Just one last confirmation, let's keep the flipped alphabetical order, but rule out that the constructor order matters.
179+
var parametersWithCompetingParametersNonAlphabetic2 = new ParameterSetWithCompetingParametersNonAlphabetic
180+
{
181+
// Again, AParam is physically located after BParam in the code structure, but it's set first in the constructor here.
182+
AParam = "location2",
183+
BParam = "location1",
184+
};
185+
186+
var dictionaryNonAlphabetic2 = parametersWithCompetingParametersNonAlphabetic2.ToDictionary();
187+
Assert.Equal("location2", dictionaryNonAlphabetic2["location"]);
188+
189+
// The constructor order doesn't seem to matter (which is a good thing because we can't control in what order end-users will set the properties).
190+
191+
// It seems the properties are in fact serialized not in alphabetical order, but in the order they are defined in the code structure.
192+
// If you need to add an override to a parameter, physically place it after the parameter it overrides in the code structure, to ensure it is serialized last.
193+
194+
// The downside to this is linting. Our linter rules like to order properties alphabetically in the code structure.
195+
// Meaning, to ensure that the override parameter is physically below the parameter it overrides, we either have to disable the linter rule for that file,
196+
// or the override parameter has to be alphabetically after the parameter it overrides, which limits us on naming choices.
197+
}
198+
148199
[Fact]
149200
[Testing.Exception]
150201
public void TestRequiredAndOptionalParameterValidation()
@@ -183,6 +234,24 @@ private sealed class ParameterSetWithRequiredAndOptionalParameters : Parameters.
183234
public string? OptionalParameter { get; set; }
184235
}
185236

237+
private sealed class ParameterSetWithCompetingParameters : Parameters.BaseParameters<EasyPostObject>
238+
{
239+
[TopLevelRequestParameter(Necessity.Optional, "location")]
240+
public string? AParam { get; set; }
241+
242+
[TopLevelRequestParameter(Necessity.Optional, "location")]
243+
public string? BParam { get; set; }
244+
}
245+
246+
private sealed class ParameterSetWithCompetingParametersNonAlphabetic : Parameters.BaseParameters<EasyPostObject>
247+
{
248+
[TopLevelRequestParameter(Necessity.Optional, "location")]
249+
public string? BParam { get; set; }
250+
251+
[TopLevelRequestParameter(Necessity.Optional, "location")]
252+
public string? AParam { get; set; }
253+
}
254+
186255
/// <summary>
187256
/// This test proves that we can reuse the Addresses.Create parameter object,
188257
/// with its serialization logic adapting to whether it is a top-level parameter object

0 commit comments

Comments
 (0)