own test method in FunSuite in ScalaTest - scalatest

Currently FunSuite executes methods named as test as tests.
I would like to write a function mytest that wraps test. How can I make FunSuite recognise mytest as a test to be executed ?

FunSuite.test is defined in ScalaTest's FunSpecLike trait. It has the following definition:
protected def test(testName: String, testTags: Tag*)(testFun: => Any /* Assertion */)(implicit pos: source.Position): Unit = {
// SKIP-SCALATESTJS-START
val stackDepth = 4
val stackDepthAdjustment = -2
// SKIP-SCALATESTJS-END
//SCALATESTJS-ONLY val stackDepth = 6
//SCALATESTJS-ONLY val stackDepthAdjustment = -6
engine.registerTest(testName, Transformer(testFun _), Resources.testCannotAppearInsideAnotherTest, "FunSuiteLike.scala", "test", stackDepth, stackDepthAdjustment, None, None, Some(pos), None, testTags: _*)
}
The most important point is that it registers its payload for execution, via the engine.registerTest(...) call. Theoretically, you could have it recognize mytest by doing something like this:
class MyFunSuite
extends FunSuite {
// User-defined test named mytest
protected def mytest(testName: String, testTags: Tag*)(testFun: => Any /* Assertion */)(implicit pos: source.Position) = {
test(testName, testTags: _*)(testFun)(pos)
}
}
You would then use it as follows:
class MyTests
extends MyFunSuite {
mytest("This is one of my own tests.") {
// ...
}
mytest("This is another test.") {
// ...
}
// ...
}
That said, there's no added value here (as yet), and you're going to a lot of effort to just replicate the existing functionality. However, you could clearly modify the definition of mytest to perform some boilerplate actions that you may require.

Related

Flink KeyedCoProcessFunction working with state

I use KeyedCoProcessFunction function to enrich main datastream with data comes from another stream
Code:
class AssetDataEnrichment extends KeyedCoProcessFunction[String, PacketData, AssetCommandState, AssetData] with LazyLogging {
case class AssetStateDoc(assetId: Option[String])
private var associatedDevices: ValueState[AssetStateDoc] = _
override def open(parameters: Configuration): Unit = {
val associatedDevicesDescriptor =
new ValueStateDescriptor[AssetStateDoc]("associatedDevices", classOf[AssetStateDoc])
associatedDevices = getRuntimeContext.getState[AssetStateDoc](associatedDevicesDescriptor)
}
override def processElement1(
packet: PacketData,
ctx: KeyedCoProcessFunction[String, PacketData, AssetCommandState, AssetData]#Context,
out: Collector[AssetData]): Unit = {
val tmpState = associatedDevices.value
val state = if (tmpState == null) AssetStateDoc(None) else tmpState
state.assetId match {
case Some(assetId) =>
logger.debug(s"There are state for ${packet.tag.externalId} = $assetId")
out.collect(AssetData(assetId, packet.tag.externalId.get, packet.toString))
case None => logger.debug(s"No state for a packet ${packet.tag.externalId}")
case _ => logger.debug("Smth went wrong")
}
}
override def processElement2(
value: AssetCommandState,
ctx: KeyedCoProcessFunction[String, PacketData, AssetCommandState, AssetData]#Context,
out: Collector[AssetData]): Unit = {
value.command match {
case CREATE =>
logger.debug(s"Got command to CREATE state for tag: ${value.id} with value: ${value.assetId}")
logger.debug(s"current state is ${associatedDevices.value()}")
associatedDevices.update(AssetStateDoc(Some(value.assetId)))
logger.debug(s"new state is ${associatedDevices.value()}")
case _ =>
logger.error("Got unknown AssetCommandState command")
}
}
}
processElement2() works good, it's accept data and update a state.
but in a processElement1() I am always hitting case None => logger.debug(s"No state for a packet ${packet.tag.externalId}")
although I expect that there will be a value that was set in processElement2 function
as an example I used this guide - https://nightlies.apache.org/flink/flink-docs-master/docs/dev/datastream/fault-tolerance/state/
processElement1 and processElement2 do share state, but keep in mind that this is key-partitioned state. This means that a value set in processElement2 when processing a given value v2 will only be seen in processElement1 when it is called later with a value v1 having the same key as v2.
Also keep in mind that you have no control over the race condition between the two streams coming into processElement1 and processElement2.
The RidesAndFares exercise from the official Apache Flink training is all about learning to work with this part of the API. https://nightlies.apache.org/flink/flink-docs-stable/docs/learn-flink/etl/ is the home for the corresponding tutorial.

Custom Layer with kwargs in tfjs

I'm new to tensorflowjs and I'm struggling to implement some custom layers, if someone could point me in the right direction that would be really helpful!
For example, I have a layer in InceptionResnetV1 architecture where I'm multiplying the layer by a constant scale (this was originally an unsupported Lambda layer which I'm switching out for a custom layer), but the value of this scale changes per block. This works fine in Keras with an implementation such as below, and using load_model with ScaleLayer in the custom objects
class ScaleLayer(tensorflow.keras.layers.Layer):
def __init__(self, **kwargs):
super(ScaleLayer, self).__init__(**kwargs)
def call(self, inputs, **kwargs):
return tensorflow.multiply(inputs, kwargs.get('scale'))
def get_config(self):
return {}
x = ScaleLayer()(x, scale = tensorflow.constant(scale))
I tried defining this in a similar way in javascript and then registered the class
class ScaleLayer extends tf.layers.Layer {
constructor(config?: any) {
super(config || {});
}
call(input: tf.Tensor, kwargs: Kwargs) {
return tf.tidy(() => {
this.invokeCallHook(input, kwargs);
const a = input;
const b = kwargs['scale'];
return tf.mul(a, b);
});
}
static get className() {
return 'ScaleLayer';
}
}
tf.serialization.registerClass(ScaleLayer);
However I'm finding that the kwargs are always empty. I tried another similar method where I passed scale as another dimension of the input, then did input[0] * input[1], which again worked fine for the keras model but not in javascript.
I feel like I'm missing something key on the way to defining this kind of custom layer with a changing value per block on the javascript end, so if someone would be able to point me in the right direction it would be much appreciated! Thanks.
constructor(config?: any) {
super(config || {});
}
The config are passed to the parent constructor. But as indicated by the question, the ScaleLayer layer also needs to keep some config properties
constructor(config?: any) {
super(config || {});
// this.propertyOfInterest = config.propertyOfInterest
// make sure that config is an object;
this.scale = config.scale
}
Then for the computation, the ScaleLayer property propertyOfInterest can be used
call(input: tf.Tensor) {
return tf.tidy(() => {
this.invokeCallHook(input, kwargs);
const a = input;
return tf.mul(a, this.scale);
});
}
Use the layer this way:
const model = tf.sequential();
...
model.add(new ScaleLayer({scale: 1}));
...

Extending class with no copying constructor (with private param)

During trying to enhance Angular's ComponetFixture I noticed that this can not be done because of no copying constructor for this class. (Or am I wrong?)
Let's suppose we have a class:
class A
{
constructor(public pub, private priv) { }
}
And I want to create class BetterA based on class A, so:
class BetterA extends A
{
constructor(a: A)
{
// super(a); <----- this can not be done, so maybe...
// super(a.pub, a.priv) // ...this could be better option, but...
}
myFunction(a: string) { return a; }
}
...second parameter is PRIVATE. I can not access it ;/
What can I do in that case?
I know that one of solutions is to use prototype like this:
A.prototype['myFunction'] = function(a: string) { return a; } // this must be done with function keyword, it's not working with ()=>{} !!! /there are problem with this pointer/
But then I have to write something weird like this:
console.log( classAobject['myFunction']("abc") );
Instead of
console.log( classAobject.myFunction("abc") );
or
I can do it by composition:
class B
{
public a: A; // or constructor(public a: A)
myFunction(a) { return a; }
}
But is seems not too elegant.
Is there any better solution?
Edit #1
I've just discovered that this syntax:
Class.prototype.NewFunction = function() { this.x.y.z = 123 }
is valid but it produces compiler errors, code works but we get:
'Property 'TextOf' does not exist on type 'Class'
and when you try to call it like this:
objectOfClass.NewFunction()
makes:
'Property 'NewFunction' does not exist on type 'Class'
BUT
It's gonna working only when we use function keyword. When we use lambda expression there will be same strange invisible problems with some functions.
I think composition is the way to go here. please remember that you are building a class and not a method which requires the new operator in order to instantiate your object. this may be what your looking for
class A{
tPub;
constructor(public pub, private priv) {
this.tPub=pub
}
}
class B extends A{
constructor(pub){
super(pub)
}
myFunc(){} //equiv to B.prototype.myFunc
}
export const myClass=new B();
//another file
import {myClass} from './file'
let m=myClass.myFunc();
unfortunately, by setting priv to private it will do exactly what it is told and make it a private object. you also could do without the constructor depending on what you would like to do with your class.

Waiting until static variable completes initialization in constructor

If i have classes like the following:
export class ClassA{
static Alpha: string;
static Beta: string[];
constructor(jsonData: any){
ClassA.Alpha = jsonData.alpha;
ClassA.Beta = new Array<string>();
for(let i=0; i<jsonData.betaList.length; i++){
ClassA.Beta.push(jsonData.betaList[i]);
}
//do whatever it takes that takes a really long time
}
}
export function foo(list: string[]){
//something
}
and when i write a code like the following:
let dat = //whatever to parse a certain json file
new ClassA(dat);
foo(ClassA.Beta);
I want to make sure that the initialization of ClassA.Beta is finished before foo() is called. is it possible? or does Typescript automatically handle such cases already?
You can be sure foo() will be executed after ClassA constructor is finished. Unless it uses any kind of async calls (Promises, setTimeout, etc.).
Having said that I think that current design is not the best one. Do you really want to initialize class static properties each time the constructor is called?
The better approach would be to have separate static initialization logic into Init() static method and call it in the proper place of your application:
export class ClassA{
static Alpha: string;
static Beta: string[];
public static Init(jsonData: any): void
{
ClassA.Alpha = jsonData.alpha;
ClassA.Beta = new Array<string>();
for(let i=0; i<jsonData.betaList.length; i++)
{
ClassA.Beta.push(jsonData.betaList[i]);
}
//do whatever it takes that takes a really long time
}
constructor()
{
//Initialize instance members here. Not static
}
}
export function foo(list: string[])
{
//something
}
let dat = {};//whatever to parse a certain json file
ClassA.Init(dat);
foo(ClassA.Beta);
This approach will allow you later to make Init() return Promise to make your code async if you will need to.

What is the difference between setting a default value of a class property inside or outside of the constructor?

My code looks like this:
interface IConfigService {
admin: {
x: number;
}
class ConfigService implements IConfigService {
admin = this.getDefaultAdminConfigs();
constructor() {
this.admin = this.getDefaultAdminConfigs();
}
private getDefaultAdminConfigs = () => {
return {
x: 99
};
}
}
Can someone tell me is there any difference between setting the value of admin outside or inside the constructor when I am using AngularJS to set up my configService?
Not in your case. It is simply a matter of what gets executed last. The constructor body is executed after the inline initialization e.g. :
class Foo {
admin = 123;
constructor() {
this.admin = 456;
}
}
var foo = new Foo();
console.log(foo.admin); // 456
It might more relevant when you have an XHR in the constructor or some other property you want to init before this one.
Note: Inline initialization is also executed in order of definition.

Resources