How to force order of execution? - swift3

I have the following class and need to ensure the caller first calls init():
class MyClass: NSObject {
static var myArray:[String] = []
init() {
//load array
}
}
//then flow from caller should be
MyClass.init()
let someItem = MyClass.items[2]
However, the caller doesn't have to call init() and in that case will get an empty array. Is there a way to force calling init() first? Or some way to do it implicitly without creating a function to retrieve the array?
I'd like the caller syntax to remain MyClass.items[x]. That's why I don't want to do a function.

Related

how can i store the value returned by my init to be used in my functions

I have the init code and it returns me a structure
public any function init() {
httpService = new http();
httpService.setUrl("#Application.baseURL#security/oauth2/token");
httpService.setMethod("POST");
httpService.addParam(type="header", name="Content-Type", value="application/x-www-form-urlencoded");
httpService.addParam(type="body", value="client_id=#application.clientID#&client_secret=#application.clientsecretID#&grant_type=#application.grant_type#");
result = httpService.send().getPrefix();
return this;
}
problem how can i use the token returned by the method in other methods, if i dump the init, i am just getting the functions, how can i use the data returned by the http
just not getting in my head, because the token is alive for 3600
Thanks
As James says, you should store the result of the http call as an instance variable. Here's one way of doing it using a property and specifying accessors=true for the component so that you can call setHttpResult() and getHttpResult() without having to write those methods. using the variables scope which will make it available to other methods within the component, but not outside.
/* Test.cfc */
component name="test"{
property name="httpResult" type="struct";
public any function init(){
//use "var" to ensure the variable is local to the function only
var httpService = new http();
httpService.setUrl("#Application.baseURL#security/oauth2/token");
httpService.setMethod("POST");
httpService.addParam(type="header", name="Content-Type", value="application/x-www-form-urlencoded");
httpService.addParam(type="body", value="client_id=#application.clientID#&client_secret=#application.clientsecretID#&grant_type=#application.grant_type#");
//store the result privately in the instance
variables.httpResult = httpService.send().getPrefix();
return this;
}
public void function someOtherMethod(){
// this method can access the result struct
var returnedContent = variables.httpResult.fileContent;
}
}
You can then use getHttpResult() inside or outside your component. For example from an external script:
test = New test(); // calls the init() method
WriteDump( test.getHttpResult() ); //auto-generated "getter"

What makes safe call (question mark) to be interpreted differently from classic if?

In Kotlin, if we declare a class member as var and nullable type, compiler doesn't allow us to run the member function although we put an if statement before calling the function because the compiler can't guarantee that the member isn't been set to null after checking against null and before calling the method.
But if we are using a safe call compiler approves our code.
My question, how the compiler makes the safe call atomic? Isn't a second thread can change the variable between checking for null and calling the method (eat method in the example)?
Code for first situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
if (w != null)
{
w.eat()
}
}
}
class Wolf
{
fun eat() : Unit
println("wolf is eating")
}
Code for second situation:
class MyWolf
{
var w : Wolf? = Wolf()
fun myFunction()
{
w?.eat()
}
}
class Wolf
{
fun eat():Unit
{
//code
}
}
The compiler puts the contents of the field to the local variable and then compares it with null. You can clearly see it if you decompile Kotlin bytecode.

static initialization inside lambda (or function) C++

How do I ensure that the initialization of a static field happens only once inside a lambda's body (or a function's)?
[] (string foo) {
static flat_hash_set<string> set;
// code to populate the set with some items.
// Question: how do I ensure this population code executed exactly once?
return set.contains(foo);
}
Static local variables are initialized only once, i.e. only the first time control passes through their declaration. On all further calls, the declaration is skipped. So you can put the code which populates the set into a function (or another lambda), and invoke it and use the returned set as the initializer.
[] (string foo) {
static flat_hash_set<string> set = populate_the_set();
return set.contains(foo);
}
or
[] (string foo) {
static flat_hash_set<string> set = [] () {
flat_hash_set<string> set;
// code to populate the set with some items.
return set;
} ();
return set.contains(foo);
}
One way to do this is to use a helper function that returns the set and initialize the set in the lambda with this
static flat_hash_set<string> set = MyHelperFunction();
You could also use a lambda instead of a helper function to keep the code local to the lambda like
flat_hash_set<string> set = []() { /* populate and return set here */ }();
Another way to do this is use std::call_once and pass a lambda to that which initializes the set.
Personally I would use the second option as it keeps the code local to the lambda and you don't need a global helper function or std::once_flag object

Non virtual methods can not be intercepted

I am new to FakeItEasy and try solve a problem.
I have a class
public class Events
{
public List<Events> SaveEvents()
{
// Call to repository and return 1(success) or -1(fail)
//If the repository return 1 then need to make another call to save the action in db
//Sample Code here
AuditLogService log = new AuditLogService();
log.CallLog();
}
}
Here is the Test Code:
[TestMethod]
public void EventValidation()
{
//Arrange
var Fakeevents = A.Fake<Events>();
var log = A.Fake<AuditLogService>();
var _EventsController = new EventsController(Fakeevents);
_EventsController.SaveEvents();
A.CallTo(
() => Fakeevents.SaveEvents().Retunr(1).AssignsOutAndRefParameters(status)
A.CallTo(
() => log.CallLog()).MustHaveHappened(Repeated.AtLeast.Once);
}
I am getting error like "Non virtual methods can not be intercepted"
I want to check whether the Calllog method is called after success or not.
Can anyone please help me on this.
I have a method and inside a method i am initiating another class and calling a method of the class. I want to check from fakeItEasy whether the method is called.
Unfortunately, your title says it all. Non-virtual members cannot be faked, configured, or intercepted, as noted in the documentation under "What members can be overridden?".
There's nothing that FakeItEasy can do for you unless you make the member virtual (or promote it to an interface and fake the interface, or something similar).
Have you tried to use function?
Like this:
Func<YourReturnType> action = () => YourMethod(params); // Act
action.Should().Throw<Exception>(); // Assert
var log = A.Fake();
Use interface instead of AuditLogService. And have this class implement that interface
var log = A.Fake();

Looking for testable design in described case

I have a system, which gets lists of objects from external system in some ABC-format, converts it to internal representation and passes to external service:
class ABCService() {
public ABCService(ExtService extService) {
this.extService = extService;
}
public void do(ABCData [] abcObjs) throws NoDataException {
if (abcObjs.length == 0) {
throw NoDataException();
} else {
List<Data> objs = new ArrayList<>();
for (ABCData abcObj : abcObjs) {
Data obj = Parser.parse(abcObj); // static call
objs.add(obj);
}
extService.do(objs);
}
}
}
When it comes to testing ABCService, we can test two things:
If no data is passed to "do", service throws an exception;
If some data is passed to "do", service should call extService and pass exactly the same number of objects, it has received from test caller.
But, though Parser factory is also tested, there is no guarantee, that output "objs" array is somehow connected to input abcObjs (e.g. method has created list with the predefined length, but method "forgets" to populate the list).
I my opinion those two test cases don't fully cover method's workflow leaving some of it dangerously untested.
How to modify ABCService design to increase it's testability?
The major testing difficulty in this code is that you have two collaborators and one of them is static.
If you can convert your Parser to a non-static (or perhaps wrap it in a non-static) and inject that as you do the extService, you could test that the parser is called the right number of times with the right arguments. Stubbing in the return values from the parser, you could also verify that your extService is called with the appropriately transformed objects instead of just the correct number of objects.
The problem you encountered is trying to handle two tasks in one function. The function do can be logically separated into two different member functions, so that you can use unittest for each of them.
By using refactoring, you can extract out the parsing and populating logic into another member function.
class ABCService() {
public void do(ABCData [] abcObjs) throws NoDataException {
extService.do(populateList(abcObjs));
}
List<Data> popuateList(ABCData[] abcObjs) {
if (abcObjs.length == 0) {
throw NoDataException();
} else {
List<Data> objs = new ArrayList<>();
for (ABCData abcObj : abcObjs) {
Data obj = Parser.parse(abcObj); // static call
objs.add(obj);
return objs;
}
}
}
while your current unittest can still remain for the "do" function, and additionally, you can add a unittest case for "populateList" function to ensure it generate correct data list