I have a class called Location
with the following automatically generated declaration,
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Location : NSManagedObject
@property (nonatomic, retain) NSNumber * cosRadLat;
@property (nonatomic, retain) NSNumber * latitude;
@property (nonatomic, retain) NSNumber * longitude;
@property (nonatomic, retain) NSNumber * radLat;
@property (nonatomic, retain) NSNumber * radLng;
@property (nonatomic, retain) NSNumber * sinRadLat;
@end
In an objective-c category, I have created two methods to calculate the other properties based on the latitude and longitude,
- (double)degreesToRadians:(NSNumber *)degrees
{
double radians = ([degrees doubleValue] * M_PI) / 180.0;
return radians;
}
- (void)setLatitude:(NSNumber *)newLat longitude:(NSNumber *)newLng
{
[self setLatitude:newLat];
[self setLongitude:newLng];
// Make calculations
double dblRadLat = [self degreesToRadians:newLat];
double dblRadLng = [self degreesToRadians:newLng];
double dblCosRadLat = cos(dblRadLat);
double dblSinRadLat = sin(dblRadLat);
// and set their values
[self setRadLat:[NSNumber numberWithDouble:dblRadLat]];
[self setRadLng:[NSNumber numberWithDouble:dblRadLng]];
[self setCosRadLat:[NSNumber numberWithDouble:dblCosRadLat]];
[self setSinRadLat:[NSNumber numberWithDouble:dblSinRadLat]];
}
When I run my unit tests, half the time I get this:
Lat 40.7302133
Lng -74.0003337
RadLat 0.7108763271245849
RadLng -1.291549470639518
CosRadLat 0.7577903652576623
SinRadLat 0.6524980937310535
The other half, I get this:
Lat 40.7302133
Lng -74.0003337
RadLat 0
RadLng 0
CosRadLat 0
SinRadLat 0
What am I doing wrong?
UNIT TEST
Here is my function I use to save the context in the unit test,
- (void)saveContext
{
NSLog(@"%@ saveContext", self.name);
NSError *saveError = nil;
STAssertTrue([self.managedObjectContext save:&saveError], @"Failed to save context to persistent store: %@", saveError);
}
And here is how I am calling it,
// Constants we will check to ensure our calcluations are correct
// 1st Location
double const LAT = 40.7292540;
double const LNG = -73.9988530;
double const RAD_LAT = 0.710859584;
double const RAD_LNG = -1.29152363;
double const SIN_RAD_LAT = 0.652485406;
double const COS_RAD_LAT = 0.75780129;
double const accuracy = 0.00000001;
/** Run before each test. Populates the database with objects to play with.
*/
- (void)setUp
{
NSLog(@"%@ setUp", self.name);
// Creates our persistent store in memory and initializes our managed object context for us.
[super setUp];
// Create a new Location
Location *location = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:self.managedObjectContext];
// Using the setLatitude:longitude: method, which cascades the calculation for all other values
[location setLatitude:[NSNumber numberWithDouble:LAT] longitude:[NSNumber numberWithDouble:LNG]];
// Check if it has properly calculated the values we asked for
double lat = [[location latitude] doubleValue];
double lng = [[location longitude] doubleValue];
double rad_lat = [[location radLat] doubleValue];
double rad_lng = [[location radLng] doubleValue];
double sin_rad_lat = [[location sinRadLat] doubleValue];
double cos_rad_lat = [[location cosRadLat] doubleValue];
STAssertEqualsWithAccuracy(LAT, lat, accuracy, @"Wanted: %f Got: %f", LAT, lat);
STAssertEqualsWithAccuracy(LNG, lng, accuracy, @"Wanted: %f Got: %f", LNG, lng);
STAssertEqualsWithAccuracy(RAD_LAT, rad_lat, accuracy, @"Wanted: %f Got: %f", RAD_LAT, rad_lat);
STAssertEqualsWithAccuracy(RAD_LNG, rad_lng, accuracy, @"Wanted: %f Got: %f", RAD_LNG, rad_lng);
STAssertEqualsWithAccuracy(SIN_RAD_LAT, sin_rad_lat, accuracy, @"Wanted: %f Got: %f", SIN_RAD_LAT, sin_rad_lat);
STAssertEqualsWithAccuracy(COS_RAD_LAT, cos_rad_lat, accuracy, @"Wanted: %f Got: %f", COS_RAD_LAT, cos_rad_lat);
// Saves the managed object context into the persistent store.
[self saveContext];
}
This part usually works. What happens is, setup
is called, it runs this test, and here is where it fails,
- (Location *)fetchLastLocation
{
NSLog(@"%@ getLastLocation", self.name);
NSMutableArray *mutableFetchResults = [self fetchEntity: @"Location"];
Location *location = (Location *)[mutableFetchResults lastObject];
return location;
}
/** Tests to see if the values stick after saving and fetching
*/
- (void)testCalculatedValuesStick
{
Location *location = [self fetchLastLocation];
NSLog(@"Stick: %@", location);
// Check if it has properly calculated the values we asked for
double lat = [[location latitude] doubleValue];
double lng = [[location longitude] doubleValue];
double rad_lat = [[location radLat] doubleValue];
double rad_lng = [[location radLng] doubleValue];
double sin_rad_lat = [[location sinRadLat] doubleValue];
double cos_rad_lat = [[location cosRadLat] doubleValue];
STAssertEqualsWithAccuracy(LAT, lat, accuracy, @"Wanted: %f Got: %f", LAT, lat);
STAssertEqualsWithAccuracy(LNG, lng, accuracy, @"Wanted: %f Got: %f", LNG, lng);
STAssertEqualsWithAccuracy(RAD_LAT, rad_lat, accuracy, @"Wanted: %f Got: %f", RAD_LAT, rad_lat);
STAssertEqualsWithAccuracy(RAD_LNG, rad_lng, accuracy, @"Wanted: %f Got: %f", RAD_LNG, rad_lng);
STAssertEqualsWithAccuracy(SIN_RAD_LAT, sin_rad_lat, accuracy, @"Wanted: %f Got: %f", SIN_RAD_LAT, sin_rad_lat);
STAssertEqualsWithAccuracy(COS_RAD_LAT, cos_rad_lat, accuracy, @"Wanted: %f Got: %f", COS_RAD_LAT, cos_rad_lat);
}
Do you think my unit test has anything to do with it?
I noticed your method is making variables named radLat, but that is also a property of your instance - I feel like you may have pointer troubles happening.
Try changing the name of your method variables (
double radLat
etc) to something different and see if that changes how your code is running. I think that code isn't behaving the way you're expecting it to - though knowing more about the code operating on yourLocation
class will help.