Ballerina range expression implemenation problem with Iterator object. Incompatible types error - wso2

I'm trying to understand the way this example code works in the Range Expressions Example on Ballerina By Example. I'm using Ballerina 1.0.5.
I'm facing an issue at the line } iterableObj = 25 ..< 28; where I get an incompatible types error. I've tried to replicate the type that it needs by trying various things including switching between exclusive and inclusive record descriptors but I can't seem to be able to figure it out. I'm also new to this language.
When I run the code below. It gives me the error as follows:
Error
error: .::range_expressions.bal:20:21: incompatible types: expected 'object { public function __iterator () returns (object { public function next () returns (record {| int value; |}?); }); }', found 'object { public function next () returns (record {| int value; |}?); }'
Code
import ballerina/io;
public function main() {
io:println("foreach for 25 ... 28");
foreach int i in 25 ... 28 {
io:println(i);
}
io:println("\nforeach for 25 ..< 28");
foreach int i in 25 ..< 28 {
io:println(i);
}
abstract object {
public function __iterator() returns
abstract object {
public function next() returns record {|int value;|}?;
};
} iterableObj = 25 ..< 28; // facing an issue here
abstract object {
public function next() returns (record {|int value;|}?);
} iterator = iterableObj.__iterator();
io:println("\niterable object for 25 ..< 28");
while (true) {
record {| int value; |}? r = iterator.next();
if (r is record {| int value; |}) {
io:println(r.value);
} else {
break;
}
}
}
Misc. Info
I'm having a similar issue with the example Iterable Objects. I get an incompatible types error when I try to execute the code in that example as well and I think the underlying problem is the implementation of iterator objects. I don't think I should post the code here or the question will seem far too long.
Per the info:
Any subtype of abstract object {public next() returns record {| T value; |}?;}, is called Iterator.
Main Question
I've gone through what I can glean from the language specifications and I can't seem to figure this out. Could you please tell me how to fix this error and if possible, a small explanation of the way the example works?

I think the issue is that the code you are trying to implement is a new addition in 1.1.0 release, 1.1.0 was release on 19/12/2019.
You can either download the 1.1.0 or use the version selector in the web site to get pre 1.1.0 documentation. There should be a version selector in top right of the webpage, from there you can select 1.0 to get the documentation for 1.0.5 compiler.
Edit:
There seems to be a bug in the website that prevent you from accessing versioned Ballerina by examples. Please use the source code of them for now. https://github.com/ballerina-platform/ballerina-lang/tree/release-1.0.5/examples

Related

FluentAssertions ShouldBeEquivalentTo() versus Should().BeEquivalentTo()

I have a test that verifies the collection output of a method. This variation of the test passes:
[TestMethod, TestCategory("BVT")]
public void TheStatusesAreReturned()
{
var expectedUnprocessedStatuses = new List<FileUploadStatus>
{
FileUploadStatus.InProcess,
FileUploadStatus.Pending,
};
Sut.GetUnprocessedStatuses()
.Should()
.BeEquivalentTo(expectedUnprocessedStatuses);
}
This variation of the test fails, with the error "Expected item[0] to be InProcess, but found Pending":
[TestMethod, TestCategory("BVT")]
public void TheStatusesAreReturned2()
{
var expectedUnprocessedStatuses = new List<FileUploadStatus>
{
FileUploadStatus.InProcess,
FileUploadStatus.Pending,
};
Sut.GetUnprocessedStatuses()
.ShouldBeEquivalentTo(expectedUnprocessedStatuses);
}
Clearly, ShouldBeEquivalentTo cares about collection item order, whereas BeEquivalentTo does not. Why is the notion of equivalency different between the 2 methods?
You're correct. Should().BeEquivalentTo() is using the individual items Equals() implementation to verify equivalence and has been around since version 1. The newer ShouldBeEquivalentTo() introduced in FA 2.0 is doing an in-depth structural comparison and also reporting on any differences. For 2.1 I'm going to change the behavior to be more like the collection equivalency by default

NULL POINTER error when using ObjectLoad(ObjectSave())

Update this has been filed as a bug in ColdFusion, https://bugbase.adobe.com/index.cfm?event=bug&id=3546237
I've been having a problem with CF9 and NULL POINTER errors that do not appear to be an issue within Railo. I created a simple CFC and associated mxunit unit test to confirm this with.
On Railo (4.0.4) both unit tests pass. On Coldfusion (9.0.1), the unit test getMetaDataBeforeMethodInvocation fails with NULL POINTER error on the GetMetaData call.
At present I can only surmise that CF9 does not have access to the full metadata following ObjectLoad until a method within that component is called. Is anyone able to shed more light on this problem, and/or offer a better solution than to ensure that a method within the object is called prior to doing getMetaData?
Here is the CFC
// NullError.cfc
component {
public NullError function init() {
variables.uuid = CreateUUID();
return this;
}
public string function getUUID() {
return uuid;
}
}
and associated unit test
// NullErrorTest.cfc
component extends='mxunit.framework.TestCase' {
private any function setupTheTests() {
var o = new NullError();
debug(o.getUUID());
// Dump meta data
debug(GetMetaData(o));
// Save and load it, and return
return ObjectLoad(ObjectSave(o));
}
public void function getMetaDataBeforeMethodInvocation() {
var o = setupTheTests();
// Get meta data, and then get uuid, expecting this to ERROR (NULL POINTER)
debug(GetMetaData(o)); // CF FAILS HERE, RAILO DOES NOT
debug(o.getUUID());
}
public void function getMetaDataAfterMethodInvocation() {
var o = setupTheTests();
// Get uuid, and then get meta data, expecting this to be ok
debug(o.getUUID());
debug(GetMetaData(o));
}
}
I can confirm this buggy behaviour in both CF 9.0.2 and 10.0.9.
I'd raise a bug if I was you.
The repro case can be simplified a lot from what you have:
// C.cfc
component {}
<!--- test.cfm --->
<cfscript>
o1 = new C();
writeDump(getMetaData(o1)); // OK
o2 = objectLoad(objectSave(o1));
writeDump(getMetadata(o2)); // breaks
</cfscript>
I don't know what to suggest by way of work-around, given it's so clearly and fundamentally broken.

TypeScript or JavaScript type casting

How does one handle type casting in TypeScript or Javascript?
Say I have the following TypeScript code:
module Symbology {
export class SymbolFactory {
createStyle( symbolInfo : SymbolInfo) : any {
if (symbolInfo == null)
{
return null;
}
if (symbolInfo.symbolShapeType === "marker") {
// how to cast to MarkerSymbolInfo
return this.createMarkerStyle((MarkerSymbolInfo) symbolInfo);
}
}
createMarkerStyle(markerSymbol : MarkerSymbolInfo ): any {
throw "createMarkerStyle not implemented";
}
}
}
where SymbolInfo is a base class. How do I handle typecasting from SymbolInfo to MarkerSymbolInfo in TypeScript or Javascript?
You can cast like this:
return this.createMarkerStyle(<MarkerSymbolInfo> symbolInfo);
Or like this if you want to be compatible with tsx mode:
return this.createMarkerStyle(symbolInfo as MarkerSymbolInfo);
Just remember that this is a compile-time cast, and not a runtime cast.
This is called type assertion in TypeScript, and since TypeScript 1.6, there are two ways to express this:
// Original syntax
var markerSymbolInfo = <MarkerSymbolInfo> symbolInfo;
// Newer additional syntax
var markerSymbolInfo = symbolInfo as MarkerSymbolInfo;
Both alternatives are functionally identical. The reason for introducing the as-syntax is that the original syntax conflicts with JSX, see the design discussion here.
If you are in a position to choose, just use the syntax that you feel more comfortable with. I personally prefer the as-syntax as it feels more fluent to read and write.
In typescript it is possible to do an instanceof check in an if statement and you will have access to the same variable with the Typed properties.
So let's say MarkerSymbolInfo has a property on it called marker. You can do the following:
if (symbolInfo instanceof MarkerSymbol) {
// access .marker here
const marker = symbolInfo.marker
}
It's a nice little trick to get the instance of a variable using the same variable without needing to reassign it to a different variable name.
Check out these two resources for more information:
TypeScript instanceof &
JavaScript instanceof

Execute #PostLoad _after_ eagerly fetching?

Using JPA2/Hibernate, I've created an entity A that has a uni-directional mapping to an entity X (see below). Inside A, I also have a transient member "t" that I am trying to calculate using a #PostLoad method. The calculation requires access to the assosiated Xs:
#Entity
public class A {
// ...
#Transient
int t;
#OneToMany(orphanRemoval = false, fetch = FetchType.EAGER)
private List listOfX;
#PostLoad
public void calculateT() {
t = 0;
for (X x : listOfX)
t = t + x.someMethod();
}
}
However, when I try to load this entity, I get a "org.hibernate.LazyInitializationException: illegal access to loading collection" error.
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:363)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
at org.hibernate.collection.PersistentBag.get(PersistentBag.java:445)
at java.util.Collections$UnmodifiableList.get(Collections.java:1154)
at mypackage.A.calculateT(A.java:32)
Looking at hibernate's code (AbstractPersistentCollection.java) while debugging, I found that:
1) My #PostLoad method is called BEFORE the "listOfX" member is initialized
2) Hibernate's code has an explicit check to prevent initialization of an eagerly fetched collection during a #PostLoad:
protected final void initialize(boolean writing) {
if (!initialized) {
if (initializing) {
throw new LazyInitializationException("illegal access to loading collection");
}
throwLazyInitializationExceptionIfNotConnected();
session.initializeCollection(this, writing);
}
}
The only way I'm thinking to fix this is to stop using #PostLoad and move the initialization code into the getT() accessor, adding a synchronized block. However, I want to avoid that.
So, is there a way to have eager fetching executed prior to #PostLoad being called? I don't know of a JPA facility to do that, so I'm hoping there's something I don't know.
Also, perhaps Hibernate's proprietary API has something to control this behaviour?
This might be too late, but hibernate seems not to support the default jpa fetchtype option
#OneToMany(orphanRemoval = false, fetch = FetchType.EAGER)
You must use the hibernate specific one:
#LazyCollection(LazyCollectionOption.FALSE)
I don't know how to fix this but I think a little refactoring might help, the idea would be to move the code to a #PostConstruct
so for example your class would be:
#Entity
public class A {
// ...
#Transient
int t;
#OneToMany(orphanRemoval = false, fetch = FetchType.EAGER)
private List listOfX;
#PostConstruct
public void calculateT() {
t = 0;
for (X x : listOfX)
t = t + x.someMethod();
}
}
The server will call PostConstruct as soon as it has completed initializing all the container services for the bean.
Updated link to bug report:
https://hibernate.atlassian.net/browse/HHH-6043
This is fixed in 4.1.8 and 4.3.0 or later

Moq tests using ExpectSet() with It.Is<T>() aren't behaving as... expected

I've isolated the behaviour into the following test case. I'd be grateful to anyone who can tell me how to expect/verify a property set for a List<T> property - it appears there's something going on inside It.Is<T>(predicate) that isn't making a whole lot of sense to me right now. Sample code will run as a console app from VS2008 - you'll need to add a reference to Moq 2.6 (I'm on 2.6.1014.1) - please try uncommenting the different ExpectSet statements to see what's happening...
using System;
using Moq;
using System.Collections.Generic;
namespace MoqDemo {
public interface IView {
List<string> Names { get; set; }
}
public class Controller {
private IView view;
public Controller(IView view) {
this.view = view;
}
public void PopulateView() {
List<string> names = new List<string>() { "Hugh", "Pugh", "Barney McGrew" };
view.Names = names;
}
public class MyApp {
public static void Main() {
Mock<IView> mockView = new Mock<IView>();
// This works - and the expectation is verifiable.
mockView.ExpectSet(mv => mv.Names);
// None of the following can be verified.
// mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null));
// mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3));
// mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>());
Controller controller = new Controller(mockView.Object);
controller.PopulateView();
try {
mockView.VerifyAll();
Console.WriteLine("Verified OK!");
} catch (MockException ex) {
Console.WriteLine("Verification failed!");
Console.WriteLine(ex.Message);
}
Console.ReadKey(false);
}
}
}
}
I'm not using the very latest version of Moq, so I don't have an overload of ExpectSet that takes two parameters, but I've had some success with this pattern:
mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null));
The Assert (from NUnit) call in the callback will throw an exception if the value assigned to .Names doesn't match the predicate. It does make it hard to trace when a test fails, though. I agree that the ability to pass an It.Is or It.IsAny as the second parameter would be handy.
The second parameter of ExpectSet() is the value you're expecting. You can't use It.Is<T> in this case as there's no overload that takes a predicate - though it would be nice ;) Here's a (simplified) excerpt from your sample, illustrating the use of a value:
var mockView = new Mock<IView>();
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" };
mockView.ExpectSet(mv => mv.Names, list);
mockView.Object.Names = list;
Hope that helps.
Edit: fixed typo.
BTW, It.Is is not supported on ExpectSet. Your code compiles just because they are regular method invocations when used as values (as opposed to expressions), whereas when used in an Expect expression they are pre-processed by Moq and given specific meaning (rather than the null/default value that all It.Is members actually return).
You could use the stub behavior on the given property (mockView.Stub(mv => mv.Names)) and later assert directly for its value after execution.
Moq doesn't provide an overload receiving It.IsAny as it's effectively the same as calling ExpectSet without passing an expected value ;)