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

fix: "Malformed enum value" when using @scoped packages #139

Merged
merged 4 commits into from
Aug 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/jsii-calc-lib/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,12 @@ export interface StructWithOnlyOptionals {
optional2?: number
optional3?: boolean
}

/**
* Check that enums from @scoped packages can be references.
* See awslabs/jsii#138
*/
export enum EnumFromScopedModule {
Value1,
Value2
}
20 changes: 19 additions & 1 deletion packages/jsii-calc-lib/test/assembly.jsii
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"fingerprint": "GbVnxjsdaq598NCRdOJ8entjQRwThRmFgdeLNaQbIZY=",
"fingerprint": "yzHGjyI4/53o87fPNjR/Nz/4G58kg5jVoKtgwdqaEU8=",
"author": {
"name": "Amazon Web Services",
"organization": true,
Expand Down Expand Up @@ -73,6 +73,24 @@
}
},
"types": {
"@scope/jsii-calc-lib.EnumFromScopedModule": {
"assembly": "@scope/jsii-calc-lib",
"docs": {
"comment": "Check that enums from @scoped packages can be references.\nSee awslabs/jsii#138"
},
"fqn": "@scope/jsii-calc-lib.EnumFromScopedModule",
"kind": "enum",
"members": [
{
"name": "Value1"
},
{
"name": "Value2"
}
],
"name": "EnumFromScopedModule",
"namespace": "@scope/jsii-calc-lib"
},
"@scope/jsii-calc-lib.IFriendly": {
"assembly": "@scope/jsii-calc-lib",
"docs": {
Expand Down
17 changes: 16 additions & 1 deletion packages/jsii-calc/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// tslint:disable
import { Operation, Value, Number, IFriendly, MyFirstStruct, StructWithOnlyOptionals } from '@scope/jsii-calc-lib'
import { Operation, Value, Number, IFriendly, MyFirstStruct, StructWithOnlyOptionals, EnumFromScopedModule } from '@scope/jsii-calc-lib'
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
Expand Down Expand Up @@ -1101,4 +1101,19 @@ export class UseCalcBase {

export interface ImplictBaseOfBase extends base.BaseProps {
goo: Date;
}

/**
* See awslabs/jsii#138
*/
export class ReferenceEnumFromScopedPackage {
public foo?: EnumFromScopedModule = EnumFromScopedModule.Value2;

public loadFoo(): EnumFromScopedModule | undefined {
return this.foo;
}

public saveFoo(value: EnumFromScopedModule) {
this.foo = value;
}
}
44 changes: 43 additions & 1 deletion packages/jsii-calc/test/assembly.jsii
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"fingerprint": "ZR90w/OQ/vVxm0Cg1sicOKwbZxbGK43MXqj2ksUyCrk=",
"fingerprint": "ENUxKESaYuaH8SRuMSsikJscFgsj+E8Ey1WvHIsNsZg=",
"author": {
"name": "Amazon Web Services",
"organization": true,
Expand Down Expand Up @@ -1919,6 +1919,48 @@
}
]
},
"jsii-calc.ReferenceEnumFromScopedPackage": {
"assembly": "jsii-calc",
"docs": {
"comment": "See awslabs/jsii#138"
},
"fqn": "jsii-calc.ReferenceEnumFromScopedPackage",
"initializer": {
"initializer": true
},
"kind": "class",
"methods": [
{
"name": "loadFoo",
"returns": {
"fqn": "@scope/jsii-calc-lib.EnumFromScopedModule",
"optional": true
}
},
{
"name": "saveFoo",
"parameters": [
{
"name": "value",
"type": {
"fqn": "@scope/jsii-calc-lib.EnumFromScopedModule"
}
}
]
}
],
"name": "ReferenceEnumFromScopedPackage",
"namespace": "jsii-calc",
"properties": [
{
"name": "foo",
"type": {
"fqn": "@scope/jsii-calc-lib.EnumFromScopedModule",
"optional": true
}
}
]
},
"jsii-calc.ReturnsNumber": {
"assembly": "jsii-calc",
"fqn": "jsii-calc.ReturnsNumber",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public EnumValue(string value)
{
Value = value ?? throw new ArgumentNullException(nameof(value));

string[] valueTokens = value.Split('/');
if (valueTokens.Length != 2)
int sep = value.LastIndexOf('/');
if (sep == -1)
{
throw new ArgumentException($"Unexpected format for enum value: {value}", nameof(value));
}

FullyQualifiedName = valueTokens[0];
MemberName = valueTokens[1];
FullyQualifiedName = value.Substring(0, sep);
MemberName = value.Substring(sep + 1);
}

public EnumValue(string fullyQualifiedName, string memberName) : this($"{fullyQualifiedName}/{memberName}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,17 @@ public void GetAndSetEnumValues()
Assert.Equal("<<[[{{(((1 * (0 + 9)) * (0 + 9)) * (0 + 9))}}]]>>", calc.ToString());
}

[Fact(DisplayName = Prefix + nameof(EnumFromScopedModule))]
public void UseEnumFromScopedModule()
{
ReferenceEnumFromScopedPackage obj = new ReferenceEnumFromScopedPackage();
Assert.Equal(EnumFromScopedModule.Value2, obj.Foo);
obj.Foo = EnumFromScopedModule.Value1;
Assert.Equal(EnumFromScopedModule.Value1, obj.LoadFoo());
obj.SaveFoo(EnumFromScopedModule.Value2);
Assert.Equal(EnumFromScopedModule.Value2, obj.Foo);
}

[Fact(DisplayName = Prefix + nameof(UndefinedAndNull))]
public void UndefinedAndNull()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
import software.amazon.jsii.tests.calculator.NumberGenerator;
import software.amazon.jsii.tests.calculator.Polymorphism;
import software.amazon.jsii.tests.calculator.Power;
import software.amazon.jsii.tests.calculator.ReferenceEnumFromScopedPackage;
import software.amazon.jsii.tests.calculator.Statics;
import software.amazon.jsii.tests.calculator.Sum;
import software.amazon.jsii.tests.calculator.SyncVirtualMethods;
import software.amazon.jsii.tests.calculator.UnionProperties;
import software.amazon.jsii.tests.calculator.UsesInterfaceWithProperties;
import software.amazon.jsii.tests.calculator.composition.CompositionStringStyle;
import software.amazon.jsii.tests.calculator.lib.EnumFromScopedModule;
import software.amazon.jsii.tests.calculator.lib.IFriendly;
import software.amazon.jsii.tests.calculator.lib.MyFirstStruct;
import software.amazon.jsii.tests.calculator.lib.Number;
Expand Down Expand Up @@ -242,6 +244,16 @@ public void getAndSetEnumValues() {
assertEquals("<<[[{{(((1 * (0 + 9)) * (0 + 9)) * (0 + 9))}}]]>>", calc.toString());
}

@Test
public void useEnumFromScopedModule() {
ReferenceEnumFromScopedPackage obj = new ReferenceEnumFromScopedPackage();
assertEquals(EnumFromScopedModule.Value2, obj.getFoo());
obj.setFoo(EnumFromScopedModule.Value1);
assertEquals(EnumFromScopedModule.Value1, obj.loadFoo());
obj.saveFoo(EnumFromScopedModule.Value2);
assertEquals(EnumFromScopedModule.Value2, obj.getFoo());
}

@Test
public void undefinedAndNull() {
Calculator calculator = new Calculator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,13 @@ private JsiiObject createNative(final String fqn) {
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Enum<?> findEnumValue(final String enumRef) {
String[] parts = enumRef.split("/");
if (parts.length != 2) {
int sep = enumRef.lastIndexOf('/');
if (sep == -1) {
throw new JsiiException("Malformed enum reference: " + enumRef);
}

String typeName = parts[0];
String valueName = parts[1];
String typeName = enumRef.substring(0, sep);
String valueName = enumRef.substring(sep + 1);

String enumClass = resolveJavaClassName(typeName);
try {
Expand Down
15 changes: 11 additions & 4 deletions packages/jsii-kernel/lib/kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,14 +855,21 @@ export class Kernel {
// enums
if (typeof v === 'object' && TOKEN_ENUM in v) {
this._debug('Enum:', v);
const parts = v[TOKEN_ENUM].split('/');
if (parts.length !== 2) {

const value = v[TOKEN_ENUM] as string;
const sep = value.lastIndexOf('/');
if (sep === -1) {
throw new Error(`Malformed enum value: ${v[TOKEN_ENUM]}`);
}
const typeName = parts[0];
const valueName = parts[1];

const typeName = value.substr(0, sep);
const valueName = value.substr(sep + 1);

const enumValue = this._findSymbol(typeName)[valueName];
if (enumValue === undefined) {
throw new Error(`No enum member named ${valueName} in ${typeName}`);
}

this._debug('resolved enum value:', enumValue);
return enumValue;
}
Expand Down
23 changes: 23 additions & 0 deletions packages/jsii-kernel/test/test.kernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,29 @@ defineTest('in/out enum values', async (test, sandbox) => {
test.deepEqual(sandbox.get({ objref: alltypes, property: 'enumProperty' }).value, { '$jsii.enum': 'jsii-calc.AllTypesEnum/ThisIsGreat' });
});

defineTest('enum values from @scoped packages awslabs/jsii#138', async (test, sandbox) => {
const objref = sandbox.create({ fqn: 'jsii-calc.ReferenceEnumFromScopedPackage' });

const value = sandbox.get({ objref, property: 'foo' });
test.deepEqual(value, { value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/Value2' } });

sandbox.set({ objref, property: 'foo', value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/Value1' }});
const ret = sandbox.invoke({ objref, method: 'loadFoo' });
test.deepEqual(ret, { result: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/Value1' } });

sandbox.invoke({ objref, method: 'saveFoo', args: [ { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/Value2' } ] });
const value2 = sandbox.get({ objref, property: 'foo' });
test.deepEqual(value2, { value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/Value2' } });
});

defineTest('fails for invalid enum member name', async (test, sandbox) => {
const objref = sandbox.create({ fqn: 'jsii-calc.ReferenceEnumFromScopedPackage' });

test.throws(() => {
sandbox.set({ objref, property: 'foo', value: { '$jsii.enum': '@scope/jsii-calc-lib.EnumFromScopedModule/ValueX' }});
}, /No enum member named ValueX/);
});

defineTest('set for a non existing property', async (test, sandbox) => {
const obj = sandbox.create({ fqn: 'jsii-calc.SyncVirtualMethods' });
test.throws(() => sandbox.set({ objref: obj, property: 'idontexist', value: 'Foo' }));
Expand Down
2 changes: 2 additions & 0 deletions packages/jsii-pacmak/bin/jsii-pacmak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ import { VERSION } from '../lib/version';
return; // already built
}

visited.add(packageDir);

// read package.json and extract the "jsii" configuration from it.
const pkg = await fs.readJson(path.join(packageDir, 'package.json'));
if (!pkg.jsii || !pkg.jsii.outdir || !pkg.jsii.targets) {
Expand Down
2 changes: 1 addition & 1 deletion packages/jsii-pacmak/test/diff-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function assert-generator() {
echo "The diff-test.sh harness will replace it with the real expected tarball" >> ${tarball_placeholder}
done

if ! diff -arq ${outdir} ${expected}; then
if ! diff --strip-trailing-cr -arq ${outdir} ${expected}; then
echo
echo "------------------------------------------------------------------------"
echo " diff-test for pacmak generator ${module} failed"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"fingerprint": "GbVnxjsdaq598NCRdOJ8entjQRwThRmFgdeLNaQbIZY=",
"fingerprint": "yzHGjyI4/53o87fPNjR/Nz/4G58kg5jVoKtgwdqaEU8=",
"author": {
"name": "Amazon Web Services",
"organization": true,
Expand Down Expand Up @@ -73,6 +73,24 @@
}
},
"types": {
"@scope/jsii-calc-lib.EnumFromScopedModule": {
"assembly": "@scope/jsii-calc-lib",
"docs": {
"comment": "Check that enums from @scoped packages can be references.\nSee awslabs/jsii#138"
},
"fqn": "@scope/jsii-calc-lib.EnumFromScopedModule",
"kind": "enum",
"members": [
{
"name": "Value1"
},
{
"name": "Value2"
}
],
"name": "EnumFromScopedModule",
"namespace": "@scope/jsii-calc-lib"
},
"@scope/jsii-calc-lib.IFriendly": {
"assembly": "@scope/jsii-calc-lib",
"docs": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Amazon.JSII.Runtime.Deputy;

namespace Amazon.JSII.Tests.Calculator.Lib
{
/// <summary>
/// Check that enums from @scoped packages can be references.
/// See awslabs/jsii#138
/// </summary>
[JsiiEnum(typeof(EnumFromScopedModule), "@scope/jsii-calc-lib.EnumFromScopedModule")]
public enum EnumFromScopedModule
{
[JsiiEnumMember("Value1")]
Value1,
[JsiiEnumMember("Value2")]
Value2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package software.amazon.jsii.tests.calculator.lib;
/**
* Check that enums from @scoped packages can be references.
* See awslabs/jsii#138
*/
@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.lib.$Module.class, fqn = "@scope/jsii-calc-lib.EnumFromScopedModule")
public enum EnumFromScopedModule {
Value1,
Value2,
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ Reference

.. py:module:: @scope/jsii-calc-lib

EnumFromScopedModule (enum)
^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. py:class:: EnumFromScopedModule

.. py:data:: Value1

.. py:data:: Value2


IFriendly (interface)
^^^^^^^^^^^^^^^^^^^^^

Expand Down
Loading