Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Add new option --generate-integer-as #158

Merged
merged 12 commits into from
Oct 4, 2022

Conversation

shaopeng-gh
Copy link
Collaborator

FEATURE: Add new option --generateintegeras = int | long | biginteger | auto and
default as int to minimize impact to existing users.
Existing tests are passing and added test for the new option.
For SARIF SDK, we will be using auto to generate int/biginteger as appropriate.

@@ -108,7 +108,9 @@ public JsonSchema(JsonSchema other)
MinLength = other.MinLength;
Format = other.Format;
MultipleOf = other.MultipleOf;
Minimum = other.Minimum;
Copy link
Collaborator Author

@shaopeng-gh shaopeng-gh Aug 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minimum = other.Minimum;

This is an existing bug, it is not set.
So I can not use Max + Min for the auto #Resolved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch. So we clearly do not have sufficient tests. For this kind of testing, I typically use advanced reflection techniques to instantiate object instances. I'd populate them with random values. Then I'd test the ctor here and the basic equatable functionality. Something to keep in mind if we have time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a follow-up issue in the other comment.

"type": "integer",
"maximum": 0
},
"integerProperty_min_0_max_int64times10": {
Copy link
Collaborator Author

@shaopeng-gh shaopeng-gh Aug 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int64times10

for int32 it is add1, but int64 it is times10,
the reason is min and max is double type,
double is less accurate when number is big.

min and max can not be changed to BigInterger because
min and max definition is not integer only.
#Closed

/// Gets or sets a value indicating what C# type to generate for Json type
/// <code>Integer</code>.
/// </summary>
public string GenerateIntegerAs { get; set; }
Copy link
Contributor

@marmegh marmegh Aug 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string

Should this be a string or should it be an enum? #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, changed to enum.

@@ -1,5 +1,8 @@
# Microsoft Json Schema Packages

## **Unreleased**
* FEATURE: Add new option `--generateintegeras = int | long | biginteger | auto` and default as `int`. [#158](https://github.com/microsoft/jschema/pull/158)
Copy link
Contributor

@marmegh marmegh Aug 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generateintegeras

Please include the dashes as they appear in Options.cs, this should look something like --generate-integer-as to avoid confusion and help with readability. #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! fixed.

GeneratesPropertiesWithIntegerTypes_Helper(GenerateIntegerOption.Auto, ExpectedClass_Auto);
GeneratesPropertiesWithIntegerTypes_Helper(GenerateIntegerOption.BigInteger, ExpectedClass_BigInteger);
GeneratesPropertiesWithIntegerTypes_Helper(GenerateIntegerOption.Long, ExpectedClass_Long);
GeneratesPropertiesWithIntegerTypes_Helper(GenerateIntegerOption.Int, ExpectedClass_Int);
Copy link
Contributor

@marmegh marmegh Aug 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These all seem like happy path test cases. Can we explicitly have a test case where the user has set --generate-integer-as int but the actual value will cause an int overflow? #Closed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional test case needed: --generate-integer-as is not set and default applies. Both happy path and with an int overflow.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. the input is a .json schema, and output is C# classes files, there is no actual value involved, the goal is user specify to generate int in his C# class and we output int.
  2. added the test that when user does not include the parameter, we will be getting int.

GeneratesPropertiesWithIntegerTypes_Helper(GenerateIntegerOption.Int, ExpectedClass_Int);
}


Copy link
Contributor

@marmegh marmegh Aug 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: remote extra blank line. #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

@marmegh marmegh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@marmegh
Copy link
Contributor

marmegh commented Aug 24, 2022

Please have @cfaucon review before merging.


In reply to: 1226600870


In reply to: 1226600870

@shaopeng-gh shaopeng-gh changed the title FEATURE: Add new option --generateintegeras FEATURE: Add new option --generate-integer-as Aug 24, 2022
{
("--schema-name Sarif --schema-file-path \"C:\\sarif.json\" --output-directory \"C:\\Autogenerated\" --namespace-name Microsoft.CodeAnalysis.Sarif --root-class-name SarifLog", (GenerateIntegerOption?)GenerateIntegerOption.Int, null),
("--schema-name Sarif --schema-file-path \"C:\\sarif.json\" --output-directory \"C:\\Autogenerated\" --namespace-name Microsoft.CodeAnalysis.Sarif --root-class-name SarifLog --generate-integer-as=Int", (GenerateIntegerOption?)GenerateIntegerOption.Int, null),
("--schema-name Sarif --schema-file-path \"C:\\sarif.json\" --output-directory \"C:\\Autogenerated\" --namespace-name Microsoft.CodeAnalysis.Sarif --root-class-name SarifLog --generate-integer-as=int", (GenerateIntegerOption?)GenerateIntegerOption.Int, null),
Copy link

@cfaucon cfaucon Aug 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are there case variations for int type and not the others? Is there a more dynamic way you can generate these test inputs since the majority of the string is the same and at the same time have it generate all the case variants if you are looking to support case insensitivity #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did some reflector and removed the duplication and simplified the input.
The reason the case sensitive test does not cover all is I was just to simply verify the case insensitive flag is set, case insensitive is build-in option for the ConmandLine package. Let me know I can generate all possible case combination of all the cases if we like.

.MapResult(
options =>
{
testCase.expectedGenerateIntegerAs.Should().NotBeNull();
Copy link

@cfaucon cfaucon Aug 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first test case to failure its conditions fails the test as a whole, and the developer will not know if any other testcases in the test are broken too. What does the test failure output look like? Is it clear what test case failed?

Recommend making it do its verification checks and append to a failure string builder, and at the end of the test emits all test case failures in a clear manner that is easy to debug and ensure we tested everything. #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Fixed.


private void GeneratesPropertiesWithIntegerTypes_Helper(GenerateIntegerOption generateIntegerAs, string expectedClass)
{
// Arrange.
Copy link

@cfaucon cfaucon Aug 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these code comments necessary? #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

@@ -92,6 +92,13 @@ internal class Options
Required = false)]
public bool GenerateCloningCode { get; set; }

[Option(
"generate-integer-as",
Copy link

@cfaucon cfaucon Aug 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very meta question here. In terms of the option, generate-integer implies its an integer which in a way conflict with the fact it might be say a long. Is the proper term to use here number? as in --generate-number-as which could be set to integer, long, etc. Open to discussion this is very meta #Closed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question, add my inputs to the discussion:
I originally plan to use --generate-json-integer-type-as-csharp-type = long
This includes the full info but I think looks long so I tried to shorten it. logically I will also use --generate-number-as but it has a problem here because json schema has a type number so to avoid confusion we should avoid the word number,
Currently I think like generate-json-integer-as or some longer version that is more clear. @cfaucon let me know your take,

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the proposed change.

@@ -2,6 +2,7 @@

## **Unreleased**
* Loosen Newtonsoft.JSON minimum version requirement from v13.0.1 to v9.0.1 [Newtonsoft.Json](https://www.nuget.org/packages/Newtonsoft.Json/9.0.1). [#157](https://github.com/microsoft/jschema/pull/157)
* FEATURE: Add new option `--generate-json-integer-as = int | long | biginteger | auto` and default as `int`. [#158](https://github.com/microsoft/jschema/pull/158)
Copy link
Member

@michaelcfanning michaelcfanning Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add new option --generate-json-integer-as = int | long | biginteger | auto and default as int. #158

Please use this:

Add new option for specifying .NET type to express Json integers: --generate-json-integer-as = int | long | biginteger | auto with a default of int. #158 #Resolved

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice command-line argument name, by the way, very descriptive.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@michaelcfanning
Copy link
Member

michaelcfanning commented Sep 2, 2022

    public bool Equals(JsonSchema other)

Hey, is there a bug in this method due to failure to account for Minimum or ExclusiveMinimum??

If so, let's please do add some advanced tests (not hard-coded by member name) to find/fix this bug.

The reflection-based tests should trigger anytime we add a new property/member to this class without properly updating the object copying ctor/Equals methods.

You can take this in a follow on change...


In reply to: 1235698310


In reply to: 1235698310


Refers to: src/Json.Schema/JsonSchema.cs:621 in ea9eec9. [](commit_id = ea9eec9, deletion_comment = False)

@@ -82,6 +82,12 @@ public class DataModelGeneratorSettings
/// </summary>
public bool GenerateCloningCode { get; set; }

/// <summary>
/// Gets or sets a value indicating what C# type to generate for Json type
Copy link
Member

@michaelcfanning michaelcfanning Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gets or sets a value indicating what C# type to generate for Json type

Use this:

Gets or sets a value indicating what C# type to emit for Json integers. #Resolved

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

/// Gets or sets a value indicating what C# type to generate for Json type
/// <code>Integer</code>.
/// </summary>
public GenerateJsonIntegerOption GenerateJsonIntegerAs { get; set; }
Copy link
Member

@michaelcfanning michaelcfanning Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GenerateJsonIntegerOption

So where's our handling for the JSON 'number' type?

We need to first review our SARIF schema to make sure we don't need a number type. Look at this one 'rank'. The specification says it's a value from 0.0 to 100.0 and provides an explicit example of 0.7 which is conclusively not an integer (in JSON, a 0 decimal value, e.g., 100.0 can be interpreted as an integer).

I think it's clear we'll need generate-json-number-as. :)

https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317663 #Resolved

Copy link
Collaborator Author

@shaopeng-gh shaopeng-gh Sep 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -654,5 +668,50 @@ private TypeSyntax GetConcreteType(string propertyName, string interfaceName)

return type;
}

internal TypeSyntax MakeProperIntegerType(GenerateJsonIntegerOption generateJsonIntegerAs,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MakeProperIntegerType

I'm not entirely sure about this approach. Let me think about it. :) Let's get this change in, then work on guid & number and I will discuss this further with you.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Looking at UUID PR now. Thanks.

Copy link
Member

@michaelcfanning michaelcfanning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@shaopeng-gh
Copy link
Collaborator Author

shaopeng-gh commented Sep 2, 2022

    public bool Equals(JsonSchema other)

Created a issue to track: Examine Equals methods and add tests


In reply to: 1235698310


Refers to: src/Json.Schema/JsonSchema.cs:621 in ea9eec9. [](commit_id = ea9eec9, deletion_comment = False)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants