Skip to content

Commit

Permalink
Merge pull request #45 from SasinduDilshara/fix_7253
Browse files Browse the repository at this point in the history
Fix the invalid error for readonly record types
  • Loading branch information
SasinduDilshara authored Oct 31, 2024
2 parents 4791e2b + 9d9653c commit 2e473c5
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
# See: https://help.github.com/articles/about-codeowners/

# These owners will be the default owners for everything in the repo.
* @gimantha @MaryamZi @hasithaa
* @gimantha @MaryamZi @hasithaa @SasinduDilshara
55 changes: 55 additions & 0 deletions ballerina/tests/from_json_string_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,61 @@ isolated function testSimpleJsonStringToRecord() returns Error? {
test:assertEquals(recC.get("b"), 1);
}

@test:Config
isolated function testSimpleJsonStringToRecord2() returns Error? {
string user = string `{"id": 4012}`;
ReadOnlyUserRecord r = check parseString(user);
test:assertEquals(r, {id: 4012});
}

@test:Config
isolated function testSimpleJsonStringToRecord3() returns Error? {
string user = string `{"id": 4012, "name": {"firstname": "John", "lastname": "Doe"}, "age": 27}`;
ReadOnlyUserRecord2 r = check parseString(user);
test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}});
}

@test:Config
isolated function testSimpleJsonStringToRecord4() returns Error? {
string user = string `{"id": 4012, "name": {"firstname": "John", "lastname": "Doe"}, "age": 27}`;
UserRecord3 r = check parseString(user);
test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}});
}

@test:Config
isolated function testSimpleJsonStringToRecord5() returns Error? {
string user = string `{"id": 4012, "name": {"firstname": "John", "lastname": "Doe"}, "age": 27}`;
ReadOnlyUserRecord2 r = check parseString(user);
test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}});
}

@test:Config
isolated function testSimpleJsonStringToRecord6() returns Error? {
string user = string `{"ids": [4012, 4013], "names": [{"firstname": "John", "lastname": "Doe"},
{"firstname": "Jane", "lastname": "Doe"}], "age": 27}`;
ReadOnlyUsersRecord3 r = check parseString(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
}

@test:Config
isolated function testSimpleJsonStringToRecord7() returns Error? {
string user = string `{"ids": [4012, 4013], "names": [{"firstname": "John", "lastname": "Doe"},
{"firstname": "Jane", "lastname": "Doe"}], "age": 27}`;
ReadOnlyUsersRecord4 r = check parseString(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
}

@test:Config
isolated function testSimpleJsonStringToRecord8() returns Error? {
string user = string `{"ids": [4012, 4013], "names": [{"firstname": "John", "lastname": "Doe"},
{"firstname": "Jane", "lastname": "Doe"}], "age": 27}`;
ReadOnlyUsersRecord5 r = check parseString(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
}

@test:Config
isolated function testSimpleJsonStringToRecordWithProjection() returns Error? {
string str = string `{"a": "hello", "b": 1}`;
Expand Down
115 changes: 115 additions & 0 deletions ballerina/tests/from_json_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,121 @@ isolated function testSimpleJsonToRecord() returns Error? {
test:assertEquals(recC.get("b"), 1);
}

type ReadOnlyUserRecord readonly & record {|
int id;
|};

@test:Config
isolated function testSimpleJsonToRecord2() returns Error? {
json user = {id: 4012};
ReadOnlyUserRecord r = check parseAsType(user);
test:assertEquals(r, {id: 4012});
}

public type ReadonlyUserId readonly & int;

public type ReadonlyUserName readonly & record {
string firstname;
string lastname;
};

type ReadOnlyUserRecord2 readonly & record {|
ReadonlyUserId id;
ReadonlyUserName name;
int age;
|};

@test:Config
isolated function testSimpleJsonToRecord3() returns Error? {
json user = {id: 4012, name: {firstname: "John", lastname: "Doe"}, age: 27};
ReadOnlyUserRecord2 r = check parseAsType(user);
test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}});
}

type UserRecord3 ReadOnlyUserRecord2;

@test:Config
isolated function testSimpleJsonToRecord4() returns Error? {
json user = {id: 4012, name: {firstname: "John", lastname: "Doe"}, age: 27};
UserRecord3 r = check parseAsType(user);
test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}});
}

@test:Config
isolated function testSimpleJsonToRecord5() returns Error? {
ReadonlyUserName username = {firstname: "John", lastname: "Doe"};
record{string firstname; string lastname;} nameRec = username;
json user = {id: 4012, name: nameRec.toJson(), age: 27};
ReadOnlyUserRecord2 r = check parseAsType(user);
test:assertEquals(r, {id: 4012, age: 27, name: {firstname: "John", lastname: "Doe"}});
}

type ReadOnlyUsersRecord3 readonly & record {|
ReadonlyUserId[] ids;
ReadonlyUserName[] names;
|};

@test:Config
isolated function testSimpleJsonToRecord6() returns Error? {
json user = {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}], age: 27};
ReadOnlyUsersRecord3 r = check parseAsType(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
test:assertTrue(r.ids is readonly);
test:assertTrue(r.names is readonly);
test:assertTrue(r is ReadOnlyUsersRecord5 & readonly);
}

type ReadOnlyUsersRecord4 readonly & record {|
ReadonlyUserId[] & readonly ids;
ReadonlyUserName[] & readonly names;
|};

@test:Config
isolated function testSimpleJsonToRecord7() returns Error? {
json user = {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}], age: 27};
ReadOnlyUsersRecord4 r = check parseAsType(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
}

type ReadOnlyUsersRecord5 record {|
ReadonlyUserId[] & readonly ids;
ReadonlyUserName[] & readonly names;
|};

@test:Config
isolated function testSimpleJsonToRecord8() returns Error? {
json user = {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}], age: 27};
ReadOnlyUsersRecord5 r = check parseAsType(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
test:assertTrue(r.ids is readonly);
test:assertTrue(r.names is readonly);
}

type ReadonlyUserIdArray ReadonlyUserId[] & readonly;
type ReadonlyUserNameArray ReadonlyUserName[] & readonly;

type ReadOnlyUsersRecord6 record {|
ReadonlyUserIdArray ids;
ReadonlyUserNameArray names;
|};

@test:Config
isolated function testSimpleJsonToRecord9() returns Error? {
json user = {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}], age: 27};
ReadOnlyUsersRecord6 r = check parseAsType(user);
test:assertEquals(r, {ids: [4012, 4013], names: [{firstname: "John", lastname: "Doe"},
{firstname: "Jane", lastname: "Doe"}]});
test:assertTrue(r.ids is readonly);
test:assertTrue(r.names is readonly);
}

@test:Config
isolated function testSimpleJsonToRecordWithProjection() returns Error? {
json j = {"a": "hello", "b": 1};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,9 @@ static Type getMemberType(Type expectedType, int index, boolean allowDataProject
}

Type referredType = TypeUtils.getReferredType(expectedType);
if (referredType.getTag() == TypeTags.INTERSECTION_TAG) {
return getMemberType(((IntersectionType) referredType).getEffectiveType(), index, allowDataProjection);
}
if (referredType.getTag() == TypeTags.ARRAY_TAG) {
ArrayType arrayType = (ArrayType) referredType;
if (arrayType.getState() == ArrayType.ArrayState.OPEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ public Object execute(Reader reader, BMap<BString, Object> options, Type type) t
}
case TypeTags.INTERSECTION_TAG -> {
Type effectiveType = ((IntersectionType) type).getEffectiveType();
if (!SymbolFlags.isFlagOn(SymbolFlags.READONLY, effectiveType.getFlags())) {
if (!effectiveType.isReadOnly()) {
throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE, type);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private Object traverseJson(Object json, Type type) {
}
case TypeTags.INTERSECTION_TAG -> {
Type effectiveType = ((IntersectionType) referredType).getEffectiveType();
if (!SymbolFlags.isFlagOn(SymbolFlags.READONLY, effectiveType.getFlags())) {
if (!effectiveType.isReadOnly()) {
throw DiagnosticLog.error(DiagnosticErrorCode.UNSUPPORTED_TYPE, type);
}
for (Type constituentType : ((IntersectionType) referredType).getConstituentTypes()) {
Expand Down

0 comments on commit 2e473c5

Please sign in to comment.