Ballerina-lang: Annotation access doesn't work in a module's tests

Created on 1 May 2020  路  2Comments  路  Source: ballerina-platform/ballerina-lang

Description:
$title.

Steps to reproduce:

Annotation Definition:-

// annotaions.bal
public type EntityType record {|
    string primary;
    string tableName;
|};

public annotation EntityType Entity on type;

Test Case:-

// tests/testannotations.bal
import ballerina/io;
import ballerina/test;

@Entity{ 
    primary:"id" ,
    tableName: "Actor"
}
type Actor record {
    string name;
    int id;
};

// Test function.
@test:Config {}
function testFunction1() {
    Actor a1 = {
        name: "Irrfan Khan",
        id: 1
    };

    typedesc<Actor> td = typeof a1;

    io:println(td);// typedesc foo:Actor
    io:println(td.@Entity);// Nothing

    string? tableName = td.@Entity?.tableName;

    test:assertEquals(tableName, "Actor");
}

_Originally posted by @whizsid in https://github.com/ballerina-platform/ballerina-spec/issues/503#issuecomment-622288276_

Affected Versions:
1.2.1

PrioritHigh TeaTestFramework TeajBallerina TypBug

Most helpful comment

@whizsid I'm afraid this is a bug, and will require a fix to get this working in tests.

All, debugged this a bit based on the following sample.

Create a project and introduce a module foo.

Define an annotation in the module's source

public type Annotation record {
    int id;
};

public annotation Annotation ann on type;

Attempt accessing annotations in the module's tests.

import ballerina/io;
import ballerina/test;

@ann {
    id: 1
}
type Employee record {
    int id;
};

@test:Config {}
function testFunction1() {
    Employee e = {
        id: 4567
    };

    typedesc<Employee> td = typeof e;

    io:println(td); // typedesc foo:Employee
    io:println(td.@ann); // empty - nil

    test:assertEquals(td.@ann?.id, 1); // Assertion Failed!: expected '1' but found ''
}

For this sample, we reach the code generation check to load annotations for three "init" functions.

  1. maryam/foo:0.1.0.<init> - seems to be the init for the source and generateAnnotLoad is called.

  2. maryam/foo:0.1.0.<init> again but seems to be for a combination of source + tests. generateAnnotLoad is called again and codegen happens for annotation load for Employee too.

  3. maryam/foo:0.1.0.<testinit> - generateAnnotLoad is not called because isModuleInitFunction evaluates to false. Expected name maryam/foo:0.1.0.<init>, actual name maryam/foo:0.1.0.<testinit>. Calling generateAnnotLoad explicitly here seems to result in the expected output, i.e., the annotations are set and access prints id=1.

All 2 comments

@whizsid I'm afraid this is a bug, and will require a fix to get this working in tests.

All, debugged this a bit based on the following sample.

Create a project and introduce a module foo.

Define an annotation in the module's source

public type Annotation record {
    int id;
};

public annotation Annotation ann on type;

Attempt accessing annotations in the module's tests.

import ballerina/io;
import ballerina/test;

@ann {
    id: 1
}
type Employee record {
    int id;
};

@test:Config {}
function testFunction1() {
    Employee e = {
        id: 4567
    };

    typedesc<Employee> td = typeof e;

    io:println(td); // typedesc foo:Employee
    io:println(td.@ann); // empty - nil

    test:assertEquals(td.@ann?.id, 1); // Assertion Failed!: expected '1' but found ''
}

For this sample, we reach the code generation check to load annotations for three "init" functions.

  1. maryam/foo:0.1.0.<init> - seems to be the init for the source and generateAnnotLoad is called.

  2. maryam/foo:0.1.0.<init> again but seems to be for a combination of source + tests. generateAnnotLoad is called again and codegen happens for annotation load for Employee too.

  3. maryam/foo:0.1.0.<testinit> - generateAnnotLoad is not called because isModuleInitFunction evaluates to false. Expected name maryam/foo:0.1.0.<init>, actual name maryam/foo:0.1.0.<testinit>. Calling generateAnnotLoad explicitly here seems to result in the expected output, i.e., the annotations are set and access prints id=1.

@MaryamZi, shall we prioritize this issue, this is a bottleneck for stdlib migration(https://github.com/ballerina-platform/ballerina-lang/issues/21313).

Was this page helpful?
0 / 5 - 0 ratings