I'm not sure if I'm doing it right but I'm trying to stub an NSNumber property on a core data object.
Here's my test example:
it(#"should say 1 / ? with 1 point", ^{
mockCard = [KWMock nullMockForClass:[Card class]];
[mockCard stub:#selector(points) andReturn:[NSNumber numberWithInt:1]];
controller.card = mockCard;
[[controller.lblCount.text should] equal:#"1 / ?"];
});
And my source code:
-(void)setCard:(Card *)aCard{
if ([card.points intValue] == 1) {
lblCount.text = #"1 / ?";
}
}
Running this causes a SIGKIL error in the writeObjectValueToInvocationReturnValue method.
Am I missing something?
Update
attempted to change the stub to:
[mockCard stub:#selector(points) andReturn:theValue(1)]
...
[FAILED], wrapped stub value type (i) could not be converted to the target type (v)
This is bug in Kiwi and is described here: https://github.com/allending/Kiwi/issues/63
Related
On trying to assign values to Nested Object Properties,Dart treats the Nested Object(class OperandRange) as null.
Default values have been assigned to the Nested Object Properties but the issue exists.
In the case below Nested Object Class OperandRange should be assigned minimum and maximum values but dart considers it to the Null.
How to resolve this?
Code
import 'dart:io';
//Nested Object Class
class OperandRange{
double _minValue = 0;
double _maxValue = 10;
OperandRange(this._minValue , this._maxValue);
double get minValue => _minValue;
double get maxValue => _maxValue;
set minValue(double _val){
_minValue = (_val) ;
}
set maxValue(double _val){
_maxValue = (_val) ;
}
}
class OperationData{
List<OperandRange> operandList = [];//Nested Object
List<String> operatorList = [] ;
OperationData({this.operandList, this.operatorList});
}
void main(){
int _operationCount = 2;
OperationData _operation = OperationData();
for(int _index = 0 ; _index < _operationCount ; _index++) {
stdout.write(" Operation $_index - Name(string): ");
_operation.operatorList[_index] = stdin.readLineSync();
//Null Object
stdout.write(" Operand $_index - Minimum Value (double) : ");
_operation.operandList[_index]._minValue =
double.parse(stdin.readLineSync());
stdout.write(" Operand $_index - Maximum Value (double): ");
_operation.operandList[_index]._maxValue =
double.parse(stdin.readLineSync());
}
}
Error
Operation 0 - Name(string): Add
Unhandled exception:
NoSuchMethodError: The method '[]=' was called on null.
Receiver: null
Tried calling: []=(0, "Add")
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 main (1.dart:41:28)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#3 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
Process finished with exit code 255
Here is what's happening.
You initialize operandList with a nested list. But this never has any effect because you also initialize it in OperationData constructor. Once you mention it in constructor arguments, it will either be set to a value you pass to constructor, or set to null if you do not pass this argument to constructor.
For your purpose you may remove constructor altogether as you never pass anything to it. Then your [] defaults will stand.
Otherwise, if in some cases you need to initialize it with a custom list, you may do it like this:
class OperationData{
List<OperandRange> operandList;
List<String> operatorList;
OperationData({
List<OperandRange> operandList,
List<String>operatorList,
}) :
this.operandList = operandList ?? <OperandList>[],
this.operatorList = operatorList ?? <String>[]
;
}
The same goes for your OperandRange class. 0 and 10 defaults will never be used as the constructor requires explicit values. By the way, I do not see OperandRange creation at all. The list stays empty. You will catch a next error when trying to access an index out of bounds when you fix the first error.
Also you should upgrade to Dart 2.12 if possible. It introduced null-safety that would show you this error at compile time.
So, I'm new to tweak development and obj c and I'm trying to change the style of dock with this code
%hook SBWallpaperEffect
-(void)setStyle: (NSInteger)arg1{
arg1 = 5;
}
%end
But it doesn't work. What am I doing wrong?
OK, I think this is the typical kind of pointer problem many programmers face. You are passing a NSInteger to the function, and arg1 is a copy of the value that is passed in. In other words, no matter how you change arg1 inside the function, the original variable does not change.
To make things more clear, look at the following code snippet:
NSInteger myInteger = 0;
NSInteger arg1;
arg1 = myInteger;
arg1 = 5;
// myInteger is still 0!
Changing arg1 does not change the value of myInteger, and that's what you're doing in your function. The arg1 copies the value of the integer passed in, be set to 5, and then gets released at the end of the function.
Instead, try this:
-(void)setStyle:(NSInteger *)arg1{
arg1 = 5;
}
and then call the function like this:
NSInteger myInteger = 0;
[self setStyle:&myInteger];
//myInteger is now 5!
Now you will get the result you want.
If you don't want to deal with these messy pointer stuff, use the returning value of the function to pass the number like this:
-(NSInteger)getStyle:(NSInteger)arg1{
// do some calculation
arg1 += 5;
return arg1;
}
or something like this (with no parameters):
-(NSInteger)getStyle{
return 5;
}
and call it like:
myInteger = [self getStyle:myInteger];
// or
myInteger = [self getStyle];
Now myInteger will also be 5. Hope this helps :)
Ok so i figured out that im using NSInteger instead of long long. Like this:
(void)setStyle:(long long)arg1;
Also, i was using
SBWallpaperEffect
Instead of
SBWallpaperEffectView
And i should've set the value inside %orig
So, this is the right way to write it:
%hook SBWallpaperEffectView
- (void)setStyle:(long long)arg1{
arg1 = 5;
%orig(arg1);
return;
}
%end
How can one get the count of invocations on a mocked object?
At a particular point in a test I'd like to get the current count of invocations for a certain method, then continue the test and finally validate that the method was invoked one more time.
This would be something like:
[given([mockA interestingMethod]) willReturnInt:5];
<do some work that may call 'interestingMethod' one or two times>
NSInteger count = currentCountOfInvocations([mockA interestingMethod]); //or something similar
<do some more work that [hopefully] calls interesting method one more time>
[verifyCount(mockA, times(count + 1)) interestingMethod];
You can mock anything with a block. So let's use a block to increment our own counter.
__block NSUInteger interestingMethodCount = 0;
[given([mockA interestingMethod]) willDo:^id(NSInvocation *invocation) {
interestingMethodCount += 1;
return #5;
}];
<do some work that may call 'interestingMethod' one or two times>
NSUInteger countAtCheckpoint = interestingMethodCount;
<do some more work that [hopefully] calls 'interestingMethod' one more time>
assertThat(#(interestingMethodCount), is(equalTo(#(countAtCheckpoint + 1))));
For example, if I want to know the return of
[NSKeyedArchiver archiveRootObject:self.privateItems toFile:[self.itemArchPath absoluteString]];
What could I do ?
If you want to see the result of [NSKeyedArchiver archiveRootObject:self.privateItems toFile:[self.itemArchPath absoluteString]] you could just wrap its result in a simple conditional statement and print a message: that method returns a boolean, so it's either true or false.
Example:
bool result = [NSKeyedArchiver archiveRootObject:self.privateItems toFile:[self.itemArchPath absoluteString]];
if (result) {
NSLog(#"It worked!");
} else {
NSLog(#"It failed!");
}
If you mean you want to check what was saved, then you should probably either print the path you saved to and look at it in on your Mac (if you're using the simulator) or try re-loading the object to make sure it matches what you expected.
In lldb and in Xcode, if you "step-out" of some function, when the step-out completes, we'll show the return value of the function you just left.
In Xcode, on stop after step out, the first element of the Locals view (called "Return Value") will be the return value of the function you just stepped out of.
If you are in command-line lldb the same thing will show up in the thread part of the stop printing:
(lldb) fin
Process 43838 stopped
* thread #1: tid = 0x849c80, 0x0000000100000f5b SimpleStepOut`main(argc=1, argv=0x00007fff5fbff5b8) + 27 at main.c:18, queue = 'com.apple.main-thread', stop reason = step out
Return value: (int) $0 = 5
frame #0: 0x0000000100000f5b SimpleStepOut`main(argc=1, argv=0x00007fff5fbff5b8) + 27 at main.c:18
15
16 int main(int argc, const char * argv[]) {
17 // insert code here...
-> 18 printf("Hello, World - %d!\n", return_five());
19 return 0;
20 }
Note, if you've customized your frame-format, you may not have this element, it's thread.return-value.
It's a little harder to do this when a "step in/out" happens to step out of the function, so for now it only works if you leave the function by stepping out.
TwoStraws answer is correct.
If, however, you are looking to find the return value (result in TwoStraws's answer) while debugging and only while debugging, you can step into the call to archiveRootObject:toFile: and then hit F8. That'll step out of the function and (usually) include a pseudo-local variable named "return" that will hold the return value from the call.
I've seen the answer about invoking a block that is stored in an array, but I can't get it to work with parameters.
I store the array an a part of an object, then when it's in a method, I want to invoke it, however, I need parameters.
Also, is there any limit to the parameters.
Lastly, I'd rather not use the extra storage to the variable, so invoking directly while in the array would be better.
__block int x = 123; // x lives in block storage
void (^printXAndY)(int) = ^(int y) {
x = x + y;
NSLog(#"X and Y: %d %d\n", x, y);
};
self.blocks = #[printXAndY];
printXAndY(10); // this works
void(^block)(void) = self.blocks[0];
block(); // this works
block(10); // this doesn't work
[self.blocks[0] invoke ];
The problem is this line:
void(^block)(void) = self.blocks[0];
You are declaring 'block' to take no parameters and return nothing. If you want the block to take a parameter, you need to declare it like this:
void(^block)(int) = self.blocks[0];
Note that block(); will no longer work. And when you declared the block incorrectly, that line was undefined behavior.