How to unit test a cross-contract call using NEAR (AssemblyScript)? - nearprotocol

I'm trying to follow this example on how to create a unit test for a cross-contract call.
I have a cross-contract call like this
// Class with cross-contract calls
export class CalculatorApi {
add(a: string, b: string): ContractPromise {
let args: AddArgs = { a, b };
let promise = ContractPromise.create(OTHER_CONTRACT, "addLongNumbers", args.encode(), 100000000000000);
return promise;
}
}
// function to unit test
export function calculate(a: string , b: string): void { // Need to return void according to current spec
let calculator = new CalculatorApi();
let promise = calculator.add(a, b);
promise.returnAsResult();
}
You may notice this function returns void, which is a bit confusing because the contract is returning a promise. This is because it's calling a function elsewhere and the compiler thinks it's void.
(In future releases this will be changed.)
And a test like this
// VS Code complains about the async word
it("add one digit", async function() {
const params = { a: "1", b: "99" };
const result = await contract.calculate(params);
expect(result).toBe("100");
});
However, the above test complains about the syntax with the following error:
An async function or method must return a 'Promise'. Make sure you
have a declaration for 'Promise' or include 'ES2015' in your '--lib'
option.ts(2697)
I'm not sure, but maybe it has something to do with my tsconfig.json file, which looks like this:
{
"extends": "../node_modules/assemblyscript/std/assembly.json",
"include": ["./**/*.ts"]
}
I tried to add the following, but it didn't work
"compilerOptions": {
"lib": ["es2020"]
}

Related

Prae:Wrapper: need to use iter_mut of interior Vec but Prae:Wrapper only provides immutable access

I'm using the prae crate for validation and the following function gives me errors:
fn advance_rotors(&mut self) {
self.rotors.get()[0].rotate();
let mut iterhandle = self.rotors.iter_mut().peekable(); // Error at iter_mut() #0599
while let Some(el) = iterhandle.next() {
match iterhandle.peek_mut() {
Some(next_rotor) => match el.should_advance_next() {
true => {
next_rotor.rotate(); // This line requires mutable access to next_rotor
}
false => (),
},
None => (),
}
}
}
and the definition of my struct here:
pub struct Enigma {
reflector: Reflector,
rotors: RotorConfig, // Only mutable via getter and setter functions
}
the struct of interest here is RotorConfig which is generated using the define! macro from prae. Here's the code:
prae::define! {
#[derive(Debug)]
RotorConfig: Vec<Rotor>; // I need to be able to call the rotate method of each rotor in this vec. This requires mutability
validate(RotorConfigError) |config| {
match config.len(){
3..=4 => (),
_ => return Err(RotorConfigError::Size)
}
match config.iter().unique().count(){
3..=4 =>(),
_ => return Err(RotorConfigError::Duplicate)
}
Ok(())
};
}
the issue stems from the fact that prae only allows for immutable access to the internal representation via getter and setter functions so as to ensure the validity of the values inside. As you can see in my advance_rotors function I wrote before implementing validation I'm getting an error because I need to call rotor.rotate mutably. I'm at a loss as to how to accomplish this
After posting this I realized that I can simply provide interior mutability by using the following impl block
impl RotorConfig{
fn advance_rotors(&mut self)
{
self.0[0].rotate();
let mut iterhandle = self.0.iter_mut().peekable();
while let Some(el) = iterhandle.next() {
match iterhandle.peek_mut() {
Some(next_rotor) => match el.should_advance_next() {
true => {
next_rotor.rotate();
}
false => (),
},
None => (),
}
}
}
}
As you can see the function largely remains unchanged except that we replace self.rotors with self.0

Kotlin coroutines within a Spring REST endpoint

Given a REST endpoint and two asynchronous coroutines each returning an integer, I want this endpoint to return their sum. The two functions (funA and funB) should run in parallel, in such a way that the whole computation should take ~3secs.
I'm using SpringBoot 2.6.3 and Kotlin Coroutines 1.6.0. Here is my attempt:
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
#RestController
class Controllers {
#GetMapping(
value = ["/summing"]
)
fun summing(): String {
val finalResult = runBlocking {
val result = async { sum() }
println("Your result: ${result.await()}")
return#runBlocking result
}
println("Final Result: $finalResult")
return "$finalResult"
}
suspend fun funA(): Int {
delay(3000)
return 10
}
suspend fun funB(): Int {
delay(2000)
return 90
}
fun sum() = runBlocking {
val resultSum = async { funA().await() + funB().await() }
return#runBlocking resultSum
}
}
The problem is that this code does not compile as await() is not recognised as a valid method. If I remove await() the two functions are executed in series (total time ~5 secs) and instead of the expected result (100), I get:
Your result: DeferredCoroutine{Completed}#1c1fe804
Final Result: DeferredCoroutine{Completed}#48a622de
and so the endpoint returns "DeferredCoroutine{Completed}#48a622de".
I want the endpoint to return "100" instead and within ~3secs. How can I achieve this?
You really messed this up ;-) There are several problems with your code:
Use runBlocking() only to use another runBlocking() inside it.
Use async() and immediately call await() on it (in summing()) - it does nothing.
funA().await() and funB().await() don't make any sense really. These functions return integers, you can't await() on already acquired integers.
Generally, using much more code than needed.
The solution is pretty simple: use runBlocking() once to jump into coroutine world and then use async() to start both functions concurrently to each other:
runBlocking {
val a = async { funA() }
val b = async { funB() }
a.await() + b.await()
}
Or alternatively:
runBlocking {
listOf(
async { funA() },
async { funB() },
).awaitAll().sum()
}
Or (a little shorter, but I consider this less readable):
runBlocking {
val a = async { funA() }
funB() + a.await()
}
Also,runBlocking() is not ideal. I believe Spring has support for coroutines, so it would be better to make summing() function suspend and use coroutineScope() instead of runBlocking() - this way the code won't block any threads.

rxswift bind(onNext: VS subscribe(onNext:

I have 2 questions:
What difference between 'bind(onNext:' and 'subscribe(onNext:'?
struct Info {
var index: Int?
var data: String?
}
let infoData: BehaviorRelay<Info> = BehaviorRelay<Info>(value: Info())
var osInfo: Observable<String> { return self.infoData.map({ return $0.data }).distinctUntilChanged() }
osInfo.bind { (target) in
print("bind!")
}.disposed(by: self.disposeBag)
osInfo.subscribe { (target) in
print("subscribe!")
}
.disposed(by: self.disposeBag)
a has no asObservable(), but well executable. What is difference a and b?
a. var osInfo: Observable<String> { return self.infoData.map({ return $0.data }).distinctUntilChanged() }
b. var osInfo: Observable<String> { return self.infoData.asObservable().map({ return $0.data }).distinctUntilChanged() }
What difference between 'bind(onNext:' and 'subscribe(onNext:'?
If we check out implementation of bind(...) we found that it does nothing else but just uses subscribe(...) underhood and crashes in Debug with error:
/**
Subscribes an element handler to an observable sequence.
In case error occurs in debug mode, `fatalError` will be raised.
In case error occurs in release mode, `error` will be logged.
- parameter onNext: Action to invoke for each element in the observable sequence.
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
public func bind(onNext: #escaping (E) -> Void) -> Disposable {
return subscribe(onNext: onNext, onError: { error in
rxFatalErrorInDebug("Binding error: \(error)")
})
}
By using bind(onNext) you can express that stream should never emit error and you interested only in item events.
So you should use subscribe(onNext:...) when you interested in error / complete / disposed events and bind(onNext...) otherwise. But since it is part of RxCocoa and not RxSwift I usually use subscribe everywhere.
a has no asObservable(), but well executable. What is difference a and b?
map(...) is function declared on ObservableType and returning new Observable
Let's start from ObservableType.
ObservableType is protocol that require only one method: subscribe(...), this allow him to create default implementation of func asObservable().
For you it means that you can create Observable from any type that conform to ObservableType.
/// Represents a push style sequence.
public protocol ObservableType : ObservableConvertibleType {
func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E
}
extension ObservableType {
/// Default implementation of converting `ObservableType` to `Observable`.
public func asObservable() -> Observable<E> {
// temporary workaround
//return Observable.create(subscribe: self.subscribe)
return Observable.create { o in
return self.subscribe(o)
}
}
}
So each time you call asObservable() underhood RxSwift just creates new Observable wrapper around your stream.
And if you check source of BehaviourRelay you will find that it conform to ObservableType as well. So you can create Observable from it anytime:
public final class BehaviorRelay<Element>: ObservableType { ... }
Now lets check map function:
extension ObservableType {
/**
Projects each element of an observable sequence into a new form.
- seealso: [map operator on reactivex.io](http://reactivex.io/documentation/operators/map.html)
- parameter transform: A transform function to apply to each source element.
- returns: An observable sequence whose elements are the result of invoking the transform function on each element of source.
*/
public func map<R>(_ transform: #escaping (E) throws -> R)
-> Observable<R> {
return self.asObservable().composeMap(transform)
}
}
As expected map just call asObservable() inside and operate on new Observable.
If we "unwrap" map call we will get:
var osInfoA: Observable<String> {
return infoData
.asObservable()
.composeMap { $0.data }
.distinctUntilChanged()
}
var osInfoB: Observable<String> {
return infoData
.asObservable()
.asObservable()
.composeMap { $0.data }
.distinctUntilChanged()
}
Sure it will not compile since composeMap is internal function but you got main idea.
Calling asObservable before other operators is redundant (most operators defined on ObservableType) and just add small overhead.

How to create a Promise from the nested kotlin.js.Promise?

kotlin.js.Promise has function then with this declaration:
open fun <S> then(
onFulfilled: (T) -> S,
onRejected: (Throwable) -> S = definedExternally
): Promise<S>
I have two functions a() and b(). They both return a Promise<Int>. (They represent some requests to the server.) I need to combine them and create a new function like:
fun c(): Promise<Int> {
a().then({
b()
})
}
But it is not possible, because return type is Promise<Promise<Int>> and not Promise<Int>.
I think this is possible in Javascript. How can I chain promises in Kotlin?
you need an additional Promise for that, for example:
fun c(): Promise<Int> {
return Promise({ resolve, reject ->
a().then({
b().then(resolve, reject);
});
})
}
the code above also can simplified by using single-expression function as below:
fun c() = Promise({ resolve, reject ->
a().then({
b().then(resolve, reject);
});
});
fun c(): Promise<Int> {
return a().then ({
b().unsafeCast<Int>()
//Result of b is Promise<Int>, not Int, but then has bad type declaration
})
}

Javascript refactor oftenly called function

I'm working with javascript for quite a long time, but it happens to me often that I come up with the following code:
function1 () {
// do stuff
...
end_function();
}
function2 () {
// do stuff
...
end_function();
}
function3 () {
// do stuff
...
end_function();
}
I know this is in conflict with the DRY principles, but unfortunately, I don't know what to do with it to remove the repetitions. Does anyone know the answer?
There is so many solutions.
One way is wrap function like "am not i am's" answer,
another is use higher-order function.
var end_function = function(callback){
callback.call();
// do some stuff
};
var stuff1 = function(){};
var stuff2 = function(){}:
end_function(stuff1);
end_function(stuff2);
It would be in conflict with DRY if you code the end_function directly into the other functions. Ultimately you do need some syntax to invoke the code that you abstracted into its own function.
If functions are grouped together into an Object, I suppose you could enumerate the properties of the object, and wrap each function, but that's probably only worth it you have many of these functions.
var funcs = {
function1 () {
// do stuff
},
function2 () {
// do stuff
},
function3 () {
// do stuff
}
};
Object.keys(funcs).forEach(function(key) {
var orig = funcs[key];
funcs[key] = function() {
orig.apply(this, arguments);
end_function();
};
});

Resources