medic 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/lib/medic/{anchored_object_query.rb → anchored_object_query_builder.rb} +5 -2
  4. data/lib/medic/{correlation_query.rb → correlation_query_builder.rb} +5 -2
  5. data/lib/medic/finders.rb +22 -17
  6. data/lib/medic/interval.rb +1 -0
  7. data/lib/medic/{observer_query.rb → observer_query_builder.rb} +5 -2
  8. data/lib/medic/predicate.rb +1 -1
  9. data/lib/medic/query_options.rb +1 -1
  10. data/lib/medic/{sample_query.rb → sample_query_builder.rb} +6 -2
  11. data/lib/medic/{source_query.rb → source_query_builder.rb} +5 -2
  12. data/lib/medic/statistics_collection_query_builder.rb +45 -0
  13. data/lib/medic/{statistics_query.rb → statistics_query_builder.rb} +5 -2
  14. data/lib/medic/store.rb +52 -18
  15. data/lib/medic/units.rb +15 -0
  16. data/lib/medic/version.rb +1 -1
  17. data/spec/medic/anchor.rb +1 -1
  18. data/spec/medic/anchored_object_query_builder_spec.rb +12 -0
  19. data/spec/medic/{correlation_query_spec.rb → correlation_query_builder_spec.rb} +4 -4
  20. data/spec/medic/hk_constants_spec.rb +1 -1
  21. data/spec/medic/interval_spec.rb +1 -1
  22. data/spec/medic/medic_spec.rb +1 -1
  23. data/spec/medic/observer_query_builder_spec.rb +12 -0
  24. data/spec/medic/predicate_spec.rb +1 -1
  25. data/spec/medic/query_options_spec.rb +1 -1
  26. data/spec/medic/sample_query_builder_spec.rb +12 -0
  27. data/spec/medic/sort_spec.rb +1 -1
  28. data/spec/medic/source_query_builder_spec.rb +12 -0
  29. data/spec/medic/statistics_collection_query_builder_spec.rb +56 -0
  30. data/spec/medic/statistics_options_spec.rb +1 -1
  31. data/spec/medic/statistics_query_builder_spec.rb +12 -0
  32. data/spec/medic/store_spec.rb +16 -15
  33. data/spec/medic/types_spec.rb +1 -1
  34. metadata +25 -24
  35. data/lib/medic/statistics_collection_query.rb +0 -39
  36. data/spec/medic/anchored_object_query_spec.rb +0 -12
  37. data/spec/medic/observer_query_spec.rb +0 -12
  38. data/spec/medic/sample_query_spec.rb +0 -12
  39. data/spec/medic/source_query_spec.rb +0 -12
  40. data/spec/medic/statistics_collection_query_spec.rb +0 -27
  41. data/spec/medic/statistics_query_spec.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bf3a75beba5a3f3be3df75476d6d18d188752bac
4
- data.tar.gz: 01bb258ba550c735090e7d04df792972562f4f91
3
+ metadata.gz: 885ef7d6a312a5644cf27850d9bb01fc24e5bcaa
4
+ data.tar.gz: 41f408b021b7b03bcab32b2eca082274439b7c9e
5
5
  SHA512:
6
- metadata.gz: 02ff5adbb1f076e1e95fee777d4d5289e0bd1eb73808f32d3ee90a6b2a45aafc27b13e323ea96885e55294e4356d2eb783cbd02e7b271287a7dc1afa07df7fa1
7
- data.tar.gz: 780718864993970ea3889ac42df1627066152d3862aab9be21f7f5eded7b146195874fff3c1a68497dc46b14482aa5348f089c70eac31e9572250511ee34ca8e
6
+ metadata.gz: 1a6b3e8f52c4338cbb9de50165fde57c559f41136e141776a9794544bbbd37bf005d156ef84482150f4d253b7f22dc06b3e883917bae28df256296fc43d9568b
7
+ data.tar.gz: f3372641785e97bf22028ec8a90c22a9bb6f2f1fffe076fed282e96beda379d55a3a3929be7e8c77647cecfda8383b399d00e8f15d1a52bae2801dc53b270c6f
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Medic [![Gem Version](https://badge.fury.io/rb/medic.svg)](http://badge.fury.io/rb/medic) [![Build Status](https://travis-ci.org/ryanlntn/medic.svg)](https://travis-ci.org/ryanlntn/medic) [![Code Climate](https://codeclimate.com/github/ryanlntn/medic/badges/gpa.svg)](https://codeclimate.com/github/ryanlntn/medic) [![Dependency Status](https://gemnasium.com/ryanlntn/medic.svg)](https://gemnasium.com/ryanlntn/medic)
2
2
 
3
- Is HealthKit's verbose and convoluted API driving you to autolobotomization? Quick! You need a medic!
3
+ Is HealthKit's verbose and convoluted API driving you mad? Quick! You need a medic!
4
4
 
5
5
  ## Installation
6
6
 
@@ -202,12 +202,12 @@ Medic.blood_type # => :o_negative
202
202
 
203
203
  #### Queries
204
204
 
205
- If for some reason you need to access the `HKSample` objects directly you can use Medic's Query objects:
205
+ If for some reason you need to access the `HKSample` objects directly you can use Medic's QueryBuilder objects:
206
206
 
207
207
  ```ruby
208
208
  query_params = { type: :dietary_protein, sort_desc: :start_date, limit: 7 }
209
209
 
210
- query = Medic::SampleQuery.new query_params do |query, results, error|
210
+ query = Medic::SampleQueryBuilder.new query_params do |query, results, error|
211
211
  if results
212
212
  results.each do |sample|
213
213
  NSLog "#{sample.startDate} - #{sample.quantity.doubleValueForUnit(HKUnit.gramUnit)}"
@@ -215,7 +215,7 @@ query = Medic::SampleQuery.new query_params do |query, results, error|
215
215
  else
216
216
  NSLog "no results"
217
217
  end
218
- end
218
+ end.query
219
219
 
220
220
  Medic.execute(query)
221
221
  ```
@@ -1,12 +1,15 @@
1
1
  module Medic
2
- class AnchoredObjectQuery < HKAnchoredObjectQuery
2
+ class AnchoredObjectQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
3
5
 
4
6
  include Medic::Types
5
7
  include Medic::Predicate
6
8
  include Medic::Anchor
7
9
 
8
10
  def initialize(args={}, block=Proc.new)
9
- self.initWithType(object_type(args[:type]),
11
+ @params = args
12
+ @query = HKAnchoredObjectQuery.alloc.initWithType(object_type(args[:type]),
10
13
  predicate: predicate(args),
11
14
  anchor: anchor_for_symbol(args[:anchor_date] || args[:anchor] || args[:date] || HKAnchoredObjectQueryNoAnchor),
12
15
  limit: args[:limit] || HKObjectQueryNoLimit,
@@ -1,11 +1,14 @@
1
1
  module Medic
2
- class CorrelationQuery < HKCorrelationQuery
2
+ class CorrelationQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
3
5
 
4
6
  include Medic::Types
5
7
  include Medic::Predicate
6
8
 
7
9
  def initialize(args={}, block=Proc.new)
8
- self.initWithType(object_type(args[:type]),
10
+ @params = args
11
+ @query = HKCorrelationQuery.alloc.initWithType(object_type(args[:type]),
9
12
  predicate: predicate(args),
10
13
  samplePredicates: sample_predicates(args[:sample_predicates]),
11
14
  completion: block
data/lib/medic/finders.rb CHANGED
@@ -3,62 +3,67 @@ module Medic
3
3
 
4
4
  def observe(type, options={}, block=Proc.new)
5
5
  query_params = options.merge(type: type)
6
- query = Medic::ObserverQuery.new query_params do |query, completion, error|
6
+ query = Medic::ObserverQueryBuilder.new query_params do |query, completion, error|
7
7
  block.call(completion, error)
8
- end
8
+ end.query
9
9
  Medic.execute(query)
10
10
  end
11
11
 
12
12
  def find_sources(type, options={}, block=Proc.new)
13
13
  query_params = options.merge(type: type)
14
- query = Medic::SourceQuery.new query_params do |query, results, error|
14
+ query = Medic::SourceQueryBuilder.new query_params do |query, results, error|
15
15
  sources = results ? results.allObjects.map{ |source| source.name.to_s } : []
16
16
  block.call(sources)
17
- end
17
+ end.query
18
18
  Medic.execute(query)
19
19
  end
20
20
 
21
21
  def find_samples(type, options={}, block=Proc.new)
22
22
  query_params = options.merge(type: type)
23
- query = Medic::SampleQuery.new query_params do |query, results, error|
23
+ query = Medic::SampleQueryBuilder.new query_params do |query, results, error|
24
24
  block.call(samples_to_hashes(Array(results)))
25
- end
25
+ end.query
26
26
  Medic.execute(query)
27
27
  end
28
28
 
29
29
  def find_correlations(type, options={}, block=Proc.new)
30
30
  query_params = options.merge(type: type)
31
- query = Medic::CorrelationQuery.new query_params do |query, correlations, error|
31
+ query = Medic::CorrelationQueryBuilder.new query_params do |query, correlations, error|
32
32
  block.call(samples_to_hashes(Array(correlations)))
33
- end
33
+ end.query
34
34
  Medic.execute(query)
35
35
  end
36
36
 
37
37
  def find_anchored(type, options={}, block=Proc.new)
38
38
  query_params = options.merge(type: type)
39
- query = Medic::AnchoredObjectQuery.new query_params do |query, results, new_anchor, error|
39
+ query = Medic::AnchoredObjectQueryBuilder.new query_params do |query, results, new_anchor, error|
40
40
  block.call(samples_to_hashes(Array(results)), new_anchor)
41
- end
41
+ end.query
42
42
  Medic.execute(query)
43
43
  end
44
44
 
45
45
  def find_statistics(type, options={}, block=Proc.new)
46
46
  query_params = options.merge(type: type)
47
- query = Medic::StatisticsQuery.new query_params do |query, statistics, error|
47
+ query = Medic::StatisticsQueryBuilder.new query_params do |query, statistics, error|
48
48
  block.call(statistics_to_hash(statistics)) if statistics
49
- end
49
+ end.query
50
50
  Medic.execute(query)
51
51
  end
52
52
 
53
53
  def find_statistics_collection(type, options={}, block=Proc.new)
54
54
  query_params = options.merge(type: type)
55
- query = Medic::StatisticsCollectionQuery.new query_params do |query, collection, error|
55
+ query = Medic::StatisticsCollectionQueryBuilder.new query_params do |query, collection, error|
56
+ from_date = options[:from_date] || options[:from] || options[:start_date] || collection.anchorDate
57
+ to_date = options[:to_date] || options[:to] || options[:end_date] || NSDate.date
56
58
  formatted_stats = []
57
- collection.enumerateStatisticsFromDate(collection.anchorDate, toDate: NSDate.date, withBlock: ->(result, stop){
58
- formatted_stats << statistics_to_hash(result)
59
- })
59
+ if collection
60
+ collection.enumerateStatisticsFromDate(from_date, toDate: to_date, withBlock: ->(result, stop){
61
+ formatted_stats << statistics_to_hash(result)
62
+ })
63
+ end
60
64
  block.call(formatted_stats)
61
- end
65
+ end.query
66
+
62
67
  Medic.execute(query)
63
68
  end
64
69
 
@@ -22,6 +22,7 @@ module Medic
22
22
  end
23
23
  end
24
24
  n ||= 1
25
+
25
26
  NSDateComponents.new.send("#{component}=", n)
26
27
  end
27
28
 
@@ -1,11 +1,14 @@
1
1
  module Medic
2
- class ObserverQuery < HKObserverQuery
2
+ class ObserverQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
3
5
 
4
6
  include Medic::Types
5
7
  include Medic::Predicate
6
8
 
7
9
  def initialize(args={}, block=Proc.new)
8
- self.initWithSampleType(object_type(args[:type]),
10
+ @params = args
11
+ @query = HKObserverQuery.alloc.initWithSampleType(object_type(args[:type]),
9
12
  predicate: predicate(args),
10
13
  updateHandler: block
11
14
  )
@@ -23,7 +23,7 @@ module Medic
23
23
  elsif args[:no_correlation]
24
24
  HKQuery.predicateForObjectsWithNoCorrelation
25
25
  elsif args[:start_date] && args[:end_date]
26
- options = query_options(args[:options]) || HKQueryOptionNone
26
+ options = query_options(args[:query_options]) || HKQueryOptionNone
27
27
  HKQuery.predicateForSamplesWithStartDate(args[:start_date], endDate: args[:end_date], options: options)
28
28
  elsif args[:workout]
29
29
  HKQuery.predicateForObjectsFromWorkout(args[:workout])
@@ -10,7 +10,7 @@ module Medic
10
10
  def query_options(symbols)
11
11
  options = 0
12
12
  Array(symbols).each do |option|
13
- options = options | query_option(option)
13
+ options |= query_option(option)
14
14
  end
15
15
  options
16
16
  end
@@ -1,16 +1,20 @@
1
1
  module Medic
2
- class SampleQuery < HKSampleQuery
2
+ class SampleQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
3
5
 
4
6
  include Medic::Types
5
7
  include Medic::Predicate
6
8
  include Medic::Sort
7
9
 
8
10
  def initialize(args={}, block=Proc.new)
11
+ @params = args
12
+
9
13
  sort = args[:sort_descriptors] || args[:sort_by] || args[:sort_asc] || args[:sort]
10
14
  sort = sort_descriptors(sort) if sort
11
15
  sort ||= sort_descriptors(args[:sort_desc], false) if args[:sort_desc]
12
16
 
13
- self.initWithSampleType(object_type(args[:type]),
17
+ @query = HKSampleQuery.alloc.initWithSampleType(object_type(args[:type]),
14
18
  predicate: predicate(args),
15
19
  limit: args[:limit] || HKObjectQueryNoLimit,
16
20
  sortDescriptors: sort,
@@ -1,11 +1,14 @@
1
1
  module Medic
2
- class SourceQuery < HKSourceQuery
2
+ class SourceQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
3
5
 
4
6
  include Medic::Types
5
7
  include Medic::Predicate
6
8
 
7
9
  def initialize(args={}, block=Proc.new)
8
- self.initWithSampleType(object_type(args[:type]),
10
+ @params = args
11
+ @query = HKSourceQuery.alloc.initWithSampleType(object_type(args[:type]),
9
12
  samplePredicate: predicate(args),
10
13
  completionHandler: block
11
14
  )
@@ -0,0 +1,45 @@
1
+ module Medic
2
+ class StatisticsCollectionQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
5
+
6
+ include Medic::Types
7
+ include Medic::Predicate
8
+ include Medic::StatisticsOptions
9
+ include Medic::Anchor
10
+ include Medic::Interval
11
+
12
+ def initialize(args={})
13
+ @params = args
14
+ @query = HKStatisticsCollectionQuery.alloc.initWithQuantityType(object_type(args[:type]),
15
+ quantitySamplePredicate: predicate(args),
16
+ options: options_for_stat_query(args[:options]),
17
+ anchorDate: anchor_for_symbol(args[:anchor_date] || args[:anchor] || args[:date] || NSDate.date),
18
+ intervalComponents: interval(args[:interval_components] || args[:interval])
19
+ )
20
+ if block_given?
21
+ handler = Proc.new
22
+ @query.initialResultsHandler = handler
23
+ @query.statisticsUpdateHandler = Proc.new{|q,_,r,e| handler.call(q,r,e)} if args[:update] == true
24
+ end
25
+ @query.statisticsUpdateHandler = args[:update] if args[:update].is_a?(Proc)
26
+ end
27
+
28
+ def initial_results_handler
29
+ @query.initialResultsHandler
30
+ end
31
+
32
+ def initial_results_handler=(callback=Proc.new)
33
+ @query.initialResultsHandler = callback
34
+ end
35
+
36
+ def statistics_update_handler
37
+ @query.statisticsUpdateHandler
38
+ end
39
+
40
+ def statistics_update_handler=(callback=Proc.new)
41
+ @query.statisticsUpdateHandler = callback
42
+ end
43
+
44
+ end
45
+ end
@@ -1,12 +1,15 @@
1
1
  module Medic
2
- class StatisticsQuery < HKStatisticsQuery
2
+ class StatisticsQueryBuilder
3
+ attr_reader :params
4
+ attr_reader :query
3
5
 
4
6
  include Medic::Types
5
7
  include Medic::Predicate
6
8
  include Medic::StatisticsOptions
7
9
 
8
10
  def initialize(args={}, block=Proc.new)
9
- self.initWithQuantityType(object_type(args[:type]),
11
+ @params = args
12
+ @query = HKStatisticsQuery.alloc.initWithQuantityType(object_type(args[:type]),
10
13
  quantitySamplePredicate: predicate(args),
11
14
  options: options_for_stat_query(args[:options]),
12
15
  completionHandler: block
data/lib/medic/store.rb CHANGED
@@ -1,20 +1,26 @@
1
1
  module Medic
2
- class Store < HKHealthStore
3
-
2
+ class Store
4
3
  include Medic::Types
4
+ include Medic::Units
5
5
  include Medic::HKConstants
6
6
 
7
7
  def self.shared
8
- Dispatch.once { @store ||= new }
9
- @store
8
+ Dispatch.once { @@hk_store ||= HKHealthStore.new }
9
+ Dispatch.once { @medic_store ||= new }
10
+ @medic_store
11
+ end
12
+
13
+ def self.hk_store
14
+ @@hk_store
10
15
  end
11
16
 
12
17
  def self.unload
13
- @store = nil
18
+ @@hk_store = nil
19
+ @medic_store = nil
14
20
  end
15
21
 
16
22
  def self.available?
17
- isHealthDataAvailable
23
+ HKHealthStore.isHealthDataAvailable
18
24
  end
19
25
  singleton_class.send(:alias_method, :is_available?, :available?)
20
26
 
@@ -22,13 +28,13 @@ module Medic
22
28
  share = Array(types[:share] || types[:write]).map{ |sym| object_type(sym) }
23
29
  read = Array(types[:read]).map{ |sym| object_type(sym) }
24
30
 
25
- requestAuthorizationToShareTypes(NSSet.setWithArray(share), readTypes: NSSet.setWithArray(read), completion: ->(success, error){
31
+ @@hk_store.requestAuthorizationToShareTypes(NSSet.setWithArray(share), readTypes: NSSet.setWithArray(read), completion: ->(success, error){
26
32
  block.call(success, error)
27
33
  })
28
34
  end
29
35
 
30
36
  def authorized?(sym)
31
- authorizationStatusForType(object_type(sym)) == HKAuthorizationStatusSharingAuthorized
37
+ @@hk_store.authorizationStatusForType(object_type(sym)) == HKAuthorizationStatusSharingAuthorized
32
38
  end
33
39
  alias_method :authorized_for?, :authorized?
34
40
  alias_method :is_authorized?, :authorized?
@@ -36,7 +42,7 @@ module Medic
36
42
 
37
43
  def biological_sex
38
44
  error = Pointer.new(:object)
39
- sex = biologicalSexWithError error
45
+ sex = @@hk_store.biologicalSexWithError error
40
46
  if block_given?
41
47
  yield BIOLOGICAL_SEXES.invert[sex.biologicalSex], error[0]
42
48
  else
@@ -46,7 +52,7 @@ module Medic
46
52
 
47
53
  def blood_type
48
54
  error = Pointer.new(:object)
49
- blood = bloodTypeWithError error
55
+ blood = @@hk_store.bloodTypeWithError error
50
56
  if block_given?
51
57
  yield BLOOD_TYPES.invert[blood.bloodType], error[0]
52
58
  else
@@ -56,7 +62,7 @@ module Medic
56
62
 
57
63
  def date_of_birth
58
64
  error = Pointer.new(:object)
59
- birthday = dateOfBirthWithError error
65
+ birthday = @@hk_store.dateOfBirthWithError error
60
66
  if block_given?
61
67
  yield birthday, error[0]
62
68
  else
@@ -65,14 +71,15 @@ module Medic
65
71
  end
66
72
 
67
73
  def delete(hk_object, block=Proc.new)
68
- deleteObject(hk_object, withCompletion: ->(success, error){
74
+ @@hk_store.deleteObject(hk_object, withCompletion: ->(success, error){
69
75
  block.call(success, error)
70
76
  })
71
77
  end
72
78
  alias_method :delete_object, :delete
73
79
 
74
80
  def save(hk_objects, block=Proc.new)
75
- saveObjects(Array(hk_objects), withCompletion: ->(success, error){
81
+ objs_array = hk_objects.is_a?(Array) ? hk_objects : [hk_objects]
82
+ @@hk_store.saveObjects(objs_array.map{|obj| prepare_for_save(obj)}, withCompletion: ->(success, error){
76
83
  block.call(success, error)
77
84
  })
78
85
  end
@@ -83,17 +90,17 @@ module Medic
83
90
  # addSamples:toWorkout:completion:
84
91
 
85
92
  def execute(query)
86
- executeQuery(query)
93
+ @@hk_store.executeQuery(query)
87
94
  end
88
95
  alias_method :execute_query, :execute
89
96
 
90
97
  def stop(query)
91
- stopQuery(query)
98
+ @@hk_store.stopQuery(query)
92
99
  end
93
100
  alias_method :stop_query, :stop
94
101
 
95
102
  def enable_background_delivery(type, frequency, block=Proc.new)
96
- enableBackgroundDeliveryForType(object_type(type), frequency: update_frequency(frequency), withCompletion: ->(success, error){
103
+ @@hk_store.enableBackgroundDeliveryForType(object_type(type), frequency: update_frequency(frequency), withCompletion: ->(success, error){
97
104
  block.call(success, error)
98
105
  })
99
106
  end
@@ -101,17 +108,44 @@ module Medic
101
108
 
102
109
  def disable_background_delivery(type, block=Proc.new)
103
110
  return disable_all_background_delivery(block) if type == :all
104
- disableBackgroundDeliveryForType(object_type(type), withCompletion: ->(success, error){
111
+ @@hk_store.disableBackgroundDeliveryForType(object_type(type), withCompletion: ->(success, error){
105
112
  block.call(success, error)
106
113
  })
107
114
  end
108
115
  alias_method :disable_background_delivery_for, :disable_background_delivery
109
116
 
110
117
  def disable_all_background_delivery(block=Proc.new)
111
- disableAllBackgroundDeliveryWithCompletion(->(success, error){
118
+ @@hk_store.disableAllBackgroundDeliveryWithCompletion(->(success, error){
112
119
  block.call(success, error)
113
120
  })
114
121
  end
115
122
 
123
+ private
124
+
125
+ def prepare_for_save(sample)
126
+ return sample if sample.kind_of? HKSample
127
+
128
+ date = sample[:date] || NSDate.date
129
+ start_date = sample[:start] || sample[:start_date] || date
130
+ end_date = sample[:end] || sample[:end_date] || date
131
+ metadata = sample[:metadata] || {}
132
+
133
+ type = object_type(sample[:type] || sample[:sample_type] || sample[:quantity_type] || sample[:correlation_type] || sample[:category_type])
134
+
135
+ case type
136
+ when HKQuantityType
137
+ quantity = HKQuantity.quantityWithUnit((sample_unit(sample[:unit]) || type.canonicalUnit), doubleValue: sample[:quantity])
138
+ HKQuantitySample.quantitySampleWithType(type, quantity: quantity, startDate: start_date, endDate: end_date, metadata: metadata)
139
+ when HKCorrelationType
140
+ objects = (sample[:objects].is_a?(Array) ? sample[:objects] : [sample[:objects]]).map{|obj| prepare_for_save(obj)}
141
+ HKCorrelation.correlationWithType(type, startDate: start_date, endDate: end_date, objects: objects, metadata: metadata)
142
+ when HKCategoryType
143
+ value = sleep_analysis(sample[:value]) # SleepAnalysis is the only category type at the moment
144
+ HKCategorySample.categorySampleWithType(type, value: value, startDate: start_date, endDate: end_date, metadata: metadata)
145
+ else
146
+ # handle workouts
147
+ end
148
+ end
149
+
116
150
  end
117
151
  end
@@ -0,0 +1,15 @@
1
+ module Medic
2
+ module Units
3
+
4
+ def sample_unit(u)
5
+ return unless u
6
+ camelized = u.to_s.gsub(/_([a-z]*)/){ "#{$1.capitalize}" }
7
+ if HKUnit.respond_to?(:"#{camelized}Unit")
8
+ HKUnit.send(:"#{camelized}Unit")
9
+ else
10
+ HKUnit.unitFromString(u.to_s)
11
+ end
12
+ end
13
+
14
+ end
15
+ end
data/lib/medic/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Medic
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/spec/medic/anchor.rb CHANGED
@@ -1,4 +1,4 @@
1
- describe "Medic::Anchor" do
1
+ describe Medic::Anchor do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -0,0 +1,12 @@
1
+ describe Medic::AnchoredObjectQueryBuilder do
2
+
3
+ before do
4
+ @subject = Medic::AnchoredObjectQueryBuilder.new type: :step_count do |query, results, new_anchor, error|
5
+ end
6
+ end
7
+
8
+ it "has a query getter that returns an HKAnchoredObjectQuery" do
9
+ @subject.query.should.be.kind_of? HKAnchoredObjectQuery
10
+ end
11
+
12
+ end
@@ -1,16 +1,16 @@
1
- describe "Medic::CorrelationQuery" do
1
+ describe Medic::CorrelationQueryBuilder do
2
2
 
3
3
  before do
4
4
  high_cal = HKQuantity.quantityWithUnit(HKUnit.kilocalorieUnit, doubleValue: 800.0)
5
5
  greater_than_high_cal = HKQuery.predicateForQuantitySamplesWithOperatorType(NSGreaterThanOrEqualToPredicateOperatorType, quantity: high_cal)
6
6
  energy_consumed = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDietaryEnergyConsumed)
7
7
  sample_predicates = { energy_consumed => greater_than_high_cal }
8
- @subject = Medic::CorrelationQuery.new type: :food, sample_predicates: sample_predicates do |query, correlations, error|
8
+ @subject = Medic::CorrelationQueryBuilder.new type: :food, sample_predicates: sample_predicates do |query, correlations, error|
9
9
  end
10
10
  end
11
11
 
12
- it "is a subclass of HKCorrelationQuery" do
13
- @subject.should.be.kind_of? HKCorrelationQuery
12
+ it "has a query getter that returns an HKCorrelationQuery" do
13
+ @subject.query.should.be.kind_of? HKCorrelationQuery
14
14
  end
15
15
 
16
16
  end
@@ -1,4 +1,4 @@
1
- describe "Medic::HKConstants" do
1
+ describe Medic::HKConstants do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -1,4 +1,4 @@
1
- describe "Medic::Interval" do
1
+ describe Medic::Interval do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -1,4 +1,4 @@
1
- describe "Medic" do
1
+ describe Medic do
2
2
 
3
3
  before do
4
4
  @store = Medic::Store.shared
@@ -0,0 +1,12 @@
1
+ describe Medic::ObserverQueryBuilder do
2
+
3
+ before do
4
+ @subject = Medic::ObserverQueryBuilder.new type: :step_count do |query, completion, error|
5
+ end
6
+ end
7
+
8
+ it "has a query getter that returns an HKObserverQuery" do
9
+ @subject.query.should.be.kind_of? HKObserverQuery
10
+ end
11
+
12
+ end
@@ -1,4 +1,4 @@
1
- describe "Medic::Predicate" do
1
+ describe Medic::Predicate do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -1,4 +1,4 @@
1
- describe "Medic::QueryOptions" do
1
+ describe Medic::QueryOptions do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -0,0 +1,12 @@
1
+ describe Medic::SampleQueryBuilder do
2
+
3
+ before do
4
+ @subject = Medic::SampleQueryBuilder.new type: :dietary_protein, limit: 7 do |query, results, error|
5
+ end
6
+ end
7
+
8
+ it "has a query getter that returns an HKSampleQuery" do
9
+ @subject.query.should.be.kind_of? HKSampleQuery
10
+ end
11
+
12
+ end
@@ -1,4 +1,4 @@
1
- describe "Medic::Sort" do
1
+ describe Medic::Sort do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -0,0 +1,12 @@
1
+ describe Medic::SourceQueryBuilder do
2
+
3
+ before do
4
+ @subject = Medic::SourceQueryBuilder.new type: :dietary_protein do |query, sources, error|
5
+ end
6
+ end
7
+
8
+ it "has a query getter that returns an HKSourceQuery" do
9
+ @subject.query.should.be.kind_of? HKSourceQuery
10
+ end
11
+
12
+ end
@@ -0,0 +1,56 @@
1
+ describe Medic::StatisticsCollectionQueryBuilder do
2
+
3
+ before do
4
+ query_params = { type: :step_count, options: :sum, interval: :day }
5
+ @subject = Medic::StatisticsCollectionQueryBuilder.new query_params do |query, collection, error|
6
+ @block_contents = [query, collection, error]
7
+ end
8
+
9
+ query_params2 = { type: :step_count, options: :sum, interval: :day, update: true }
10
+ @subject_with_update = Medic::StatisticsCollectionQueryBuilder.new query_params2 do |query, collection, error|
11
+ @block_contents = [query, collection, error]
12
+ end
13
+ end
14
+
15
+ after do
16
+ @block_contents = nil
17
+ end
18
+
19
+ it "has a query getter that returns an HKStatisticsCollectionQuery" do
20
+ @subject.query.should.be.kind_of? HKStatisticsCollectionQuery
21
+ end
22
+
23
+ describe "initialize" do
24
+ it "sets initialResultsHandler when given block" do
25
+ @subject.query.initialResultsHandler.call(:query, :collection, :error)
26
+ @block_contents.should == [:query, :collection, :error]
27
+ end
28
+
29
+ context "when :update is given" do
30
+ it "sets statisticsUpdateHandler when given block" do
31
+ @subject_with_update.query.statisticsUpdateHandler.call(:query, :statistics, :collection, :error)
32
+ @block_contents.should == [:query, :collection, :error]
33
+ end
34
+ end
35
+
36
+ context "when :update isn't given" do
37
+ it "doesn't set statisticsUpdateHandler when given block" do
38
+ @subject.query.statisticsUpdateHandler.should == nil
39
+ @block_contents.should == nil
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#initial_results_handler=" do
45
+ it "sets initialResultsHandler with callback" do
46
+ @subject.query.initialResultsHandler.should.respond_to? :call
47
+ end
48
+ end
49
+
50
+ describe "#statistics_update_handler=" do
51
+ it "sets statisticsUpdateHandler with callback" do
52
+ @subject_with_update.query.statisticsUpdateHandler.should.respond_to? :call
53
+ end
54
+ end
55
+
56
+ end
@@ -1,4 +1,4 @@
1
- describe "Medic::StatisticsOptions" do
1
+ describe Medic::StatisticsOptions do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
@@ -0,0 +1,12 @@
1
+ describe Medic::StatisticsQueryBuilder do
2
+
3
+ before do
4
+ @subject = Medic::StatisticsQueryBuilder.new type: :step_count, options: :sum do |query, results, error|
5
+ end
6
+ end
7
+
8
+ it "has a query getter that returns an HKStatisticsQuery" do
9
+ @subject.query.should.be.kind_of? HKStatisticsQuery
10
+ end
11
+
12
+ end
@@ -1,12 +1,13 @@
1
- describe "Medic::Store" do
1
+ describe Medic::Store do
2
2
 
3
3
  before do
4
4
  @subject = Medic::Store.new
5
+ @hk_store = Medic::Store.hk_store
5
6
  end
6
7
 
7
8
  describe "#authorize" do
8
9
  it "calls #requestAuthorizationToShareTypes:readTypes:completion with correct args" do
9
- @subject.mock! 'requestAuthorizationToShareTypes:readTypes:completion' do |share, read, comp|
10
+ @hk_store.mock! 'requestAuthorizationToShareTypes:readTypes:completion' do |share, read, comp|
10
11
  share.should.be.kind_of? NSSet
11
12
  read.should.be.kind_of? NSSet
12
13
  comp.should.respond_to? :call
@@ -18,7 +19,7 @@ describe "Medic::Store" do
18
19
 
19
20
  describe "#authorized?" do
20
21
  it "calls #authorizationStatusForType with correct args" do
21
- @subject.mock! 'authorizationStatusForType' do |type|
22
+ @hk_store.mock! 'authorizationStatusForType' do |type|
22
23
  type.should.be.kind_of? HKObjectType
23
24
  false
24
25
  end
@@ -40,7 +41,7 @@ describe "Medic::Store" do
40
41
 
41
42
  describe "#biological_sex" do
42
43
  it "calls #biologicalSexWithError with correct args" do
43
- @subject.mock! 'biologicalSexWithError' do |error|
44
+ @hk_store.mock! 'biologicalSexWithError' do |error|
44
45
  error.should.be.kind_of? Pointer
45
46
  mock(:biologicalSex, return: HKBiologicalSexFemale)
46
47
  end
@@ -50,7 +51,7 @@ describe "Medic::Store" do
50
51
 
51
52
  describe "#blood_type" do
52
53
  it "calls #bloodTypeWithError with correct args" do
53
- @subject.mock! 'bloodTypeWithError' do |error|
54
+ @hk_store.mock! 'bloodTypeWithError' do |error|
54
55
  error.should.be.kind_of? Pointer
55
56
  mock(:bloodType, return: HKBloodTypeONegative)
56
57
  end
@@ -60,7 +61,7 @@ describe "Medic::Store" do
60
61
 
61
62
  describe "#date_of_birth" do
62
63
  it "calls #dateOfBirthWithError with correct args" do
63
- @subject.mock! 'dateOfBirthWithError' do |error|
64
+ @hk_store.mock! 'dateOfBirthWithError' do |error|
64
65
  error.should.be.kind_of? Pointer
65
66
  true
66
67
  end
@@ -70,18 +71,18 @@ describe "Medic::Store" do
70
71
 
71
72
  describe "#save" do
72
73
  it "calls #saveObject:withCompletion with correct args" do
73
- @subject.mock! 'saveObjects:withCompletion' do |object, comp|
74
- object.first.should.be.kind_of? HKObjectType
74
+ @hk_store.mock! 'saveObjects:withCompletion' do |object, comp|
75
+ object.first.should.be.kind_of? HKSample
75
76
  comp.should.respond_to? :call
76
77
  end
77
- steps = @subject.object_type(:step_count)
78
+ steps = { quantity_type: :step_count, quantity: 50 }
78
79
  @subject.save(steps){|success, error|}
79
80
  end
80
81
  end
81
82
 
82
83
  describe "#delete" do
83
84
  it "calls #deleteObject:withCompletion with correct args" do
84
- @subject.mock! 'deleteObject:withCompletion' do |object, comp|
85
+ @hk_store.mock! 'deleteObject:withCompletion' do |object, comp|
85
86
  object.should.be.kind_of? HKObjectType
86
87
  comp.should.respond_to? :call
87
88
  end
@@ -92,7 +93,7 @@ describe "Medic::Store" do
92
93
 
93
94
  describe "#execute" do
94
95
  it "calls #executeQuery with correct args" do
95
- @subject.mock! 'executeQuery' do |query|
96
+ @hk_store.mock! 'executeQuery' do |query|
96
97
  query.should.be.kind_of? HKQuery
97
98
  end
98
99
  query = HKSampleQuery.alloc.initWithSampleType(@subject.object_type(:step_count), predicate:nil, limit:HKObjectQueryNoLimit, sortDescriptors:nil, resultsHandler:->(q,r,e){})
@@ -106,7 +107,7 @@ describe "Medic::Store" do
106
107
 
107
108
  describe "#stop" do
108
109
  it "calls #stopQuery with correct args" do
109
- @subject.mock! 'stopQuery' do |query|
110
+ @hk_store.mock! 'stopQuery' do |query|
110
111
  query.should.be.kind_of? HKQuery
111
112
  end
112
113
  query = HKSampleQuery.alloc.initWithSampleType(@subject.object_type(:step_count), predicate:nil, limit:HKObjectQueryNoLimit, sortDescriptors:nil, resultsHandler:->(q,r,e){})
@@ -120,7 +121,7 @@ describe "Medic::Store" do
120
121
 
121
122
  describe "#enable_background_delivery" do
122
123
  it "calls #enableBackgroundDeliveryForType with correct args" do
123
- @subject.mock! 'enableBackgroundDeliveryForType:frequency:withCompletion' do |type, freq, comp|
124
+ @hk_store.mock! 'enableBackgroundDeliveryForType:frequency:withCompletion' do |type, freq, comp|
124
125
  type.should.be.kind_of? HKObjectType
125
126
  freq.should == HKUpdateFrequencyWeekly
126
127
  comp.should.respond_to? :call
@@ -135,7 +136,7 @@ describe "Medic::Store" do
135
136
 
136
137
  describe "#disable_background_delivery" do
137
138
  it "calls #disableBackgroundDeliveryForType:withCompletion with correct args" do
138
- @subject.mock! 'disableBackgroundDeliveryForType:withCompletion' do |type, comp|
139
+ @hk_store.mock! 'disableBackgroundDeliveryForType:withCompletion' do |type, comp|
139
140
  type.should.be.kind_of? HKObjectType
140
141
  comp.should.respond_to? :call
141
142
  end
@@ -149,7 +150,7 @@ describe "Medic::Store" do
149
150
 
150
151
  describe "#disable_all_background_delivery" do
151
152
  it "calls #disableAllBackgroundDeliveryWithCompletion with correct args" do
152
- @subject.mock! 'disableAllBackgroundDeliveryWithCompletion' do |comp|
153
+ @hk_store.mock! 'disableAllBackgroundDeliveryWithCompletion' do |comp|
153
154
  comp.should.respond_to? :call
154
155
  end
155
156
  @subject.disable_all_background_delivery{|success, error|}
@@ -1,4 +1,4 @@
1
- describe "Medic::Types" do
1
+ describe Medic::Types do
2
2
 
3
3
  before do
4
4
  @subject = Object.new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: medic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Linton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-20 00:00:00.000000000 Z
11
+ date: 2015-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -48,39 +48,40 @@ files:
48
48
  - README.md
49
49
  - lib/medic.rb
50
50
  - lib/medic/anchor.rb
51
- - lib/medic/anchored_object_query.rb
52
- - lib/medic/correlation_query.rb
51
+ - lib/medic/anchored_object_query_builder.rb
52
+ - lib/medic/correlation_query_builder.rb
53
53
  - lib/medic/finders.rb
54
54
  - lib/medic/hk_constants.rb
55
55
  - lib/medic/interval.rb
56
56
  - lib/medic/medic.rb
57
- - lib/medic/observer_query.rb
57
+ - lib/medic/observer_query_builder.rb
58
58
  - lib/medic/predicate.rb
59
59
  - lib/medic/query_options.rb
60
- - lib/medic/sample_query.rb
60
+ - lib/medic/sample_query_builder.rb
61
61
  - lib/medic/sort.rb
62
- - lib/medic/source_query.rb
63
- - lib/medic/statistics_collection_query.rb
62
+ - lib/medic/source_query_builder.rb
63
+ - lib/medic/statistics_collection_query_builder.rb
64
64
  - lib/medic/statistics_options.rb
65
- - lib/medic/statistics_query.rb
65
+ - lib/medic/statistics_query_builder.rb
66
66
  - lib/medic/store.rb
67
67
  - lib/medic/types.rb
68
+ - lib/medic/units.rb
68
69
  - lib/medic/version.rb
69
70
  - spec/medic/anchor.rb
70
- - spec/medic/anchored_object_query_spec.rb
71
- - spec/medic/correlation_query_spec.rb
71
+ - spec/medic/anchored_object_query_builder_spec.rb
72
+ - spec/medic/correlation_query_builder_spec.rb
72
73
  - spec/medic/hk_constants_spec.rb
73
74
  - spec/medic/interval_spec.rb
74
75
  - spec/medic/medic_spec.rb
75
- - spec/medic/observer_query_spec.rb
76
+ - spec/medic/observer_query_builder_spec.rb
76
77
  - spec/medic/predicate_spec.rb
77
78
  - spec/medic/query_options_spec.rb
78
- - spec/medic/sample_query_spec.rb
79
+ - spec/medic/sample_query_builder_spec.rb
79
80
  - spec/medic/sort_spec.rb
80
- - spec/medic/source_query_spec.rb
81
- - spec/medic/statistics_collection_query_spec.rb
81
+ - spec/medic/source_query_builder_spec.rb
82
+ - spec/medic/statistics_collection_query_builder_spec.rb
82
83
  - spec/medic/statistics_options_spec.rb
83
- - spec/medic/statistics_query_spec.rb
84
+ - spec/medic/statistics_query_builder_spec.rb
84
85
  - spec/medic/store_spec.rb
85
86
  - spec/medic/types_spec.rb
86
87
  homepage: https://github.com/ryanlntn/medic
@@ -103,25 +104,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
104
  version: '0'
104
105
  requirements: []
105
106
  rubyforge_project:
106
- rubygems_version: 2.4.2
107
+ rubygems_version: 2.4.6
107
108
  signing_key:
108
109
  specification_version: 4
109
110
  summary: A RubyMotion Wrapper for HealthKit
110
111
  test_files:
111
112
  - spec/medic/anchor.rb
112
- - spec/medic/anchored_object_query_spec.rb
113
- - spec/medic/correlation_query_spec.rb
113
+ - spec/medic/anchored_object_query_builder_spec.rb
114
+ - spec/medic/correlation_query_builder_spec.rb
114
115
  - spec/medic/hk_constants_spec.rb
115
116
  - spec/medic/interval_spec.rb
116
117
  - spec/medic/medic_spec.rb
117
- - spec/medic/observer_query_spec.rb
118
+ - spec/medic/observer_query_builder_spec.rb
118
119
  - spec/medic/predicate_spec.rb
119
120
  - spec/medic/query_options_spec.rb
120
- - spec/medic/sample_query_spec.rb
121
+ - spec/medic/sample_query_builder_spec.rb
121
122
  - spec/medic/sort_spec.rb
122
- - spec/medic/source_query_spec.rb
123
- - spec/medic/statistics_collection_query_spec.rb
123
+ - spec/medic/source_query_builder_spec.rb
124
+ - spec/medic/statistics_collection_query_builder_spec.rb
124
125
  - spec/medic/statistics_options_spec.rb
125
- - spec/medic/statistics_query_spec.rb
126
+ - spec/medic/statistics_query_builder_spec.rb
126
127
  - spec/medic/store_spec.rb
127
128
  - spec/medic/types_spec.rb
@@ -1,39 +0,0 @@
1
- module Medic
2
- class StatisticsCollectionQuery < HKStatisticsCollectionQuery
3
-
4
- include Medic::Types
5
- include Medic::Predicate
6
- include Medic::StatisticsOptions
7
- include Medic::Anchor
8
- include Medic::Interval
9
-
10
- def initialize(args={})
11
- self.initWithQuantityType(object_type(args[:type]),
12
- quantitySamplePredicate: predicate(args),
13
- options: options_for_stat_query(args[:options]),
14
- anchorDate: anchor_for_symbol(args[:anchor_date] || args[:anchor] || args[:date] || NSDate.date),
15
- intervalComponents: interval(args[:interval_components] || args[:interval])
16
- )
17
- self.initialResultsHandler = Proc.new if block_given?
18
- self
19
- end
20
-
21
- alias_method :initial_results_handler, :initialResultsHandler
22
-
23
- def initial_results_handler=(callback=Proc.new)
24
- self.initialResultsHandler = callback
25
- end
26
-
27
- alias_method :statistics_update_handler, :statisticsUpdateHandler
28
-
29
- def statistics_update_handler=(callback=Proc.new)
30
- self.statisticsUpdateHandler = callback
31
- end
32
-
33
- alias_method :anchor, :anchorDate
34
- alias_method :anchor_date, :anchorDate
35
- alias_method :interval, :intervalComponents
36
- alias_method :interval_components, :intervalComponents
37
-
38
- end
39
- end
@@ -1,12 +0,0 @@
1
- describe "Medic::AnchoredObjectQuery" do
2
-
3
- before do
4
- @subject = Medic::AnchoredObjectQuery.new type: :step_count do |query, results, new_anchor, error|
5
- end
6
- end
7
-
8
- it "is a subclass of HKAnchoredObjectQuery" do
9
- @subject.should.be.kind_of? HKAnchoredObjectQuery
10
- end
11
-
12
- end
@@ -1,12 +0,0 @@
1
- describe "Medic::ObserverQuery" do
2
-
3
- before do
4
- @subject = Medic::ObserverQuery.new type: :step_count do |query, completion, error|
5
- end
6
- end
7
-
8
- it "is a subclass of HKObserverQuery" do
9
- @subject.should.be.kind_of? HKObserverQuery
10
- end
11
-
12
- end
@@ -1,12 +0,0 @@
1
- describe "Medic::SampleQuery" do
2
-
3
- before do
4
- @subject = Medic::SampleQuery.new type: :dietary_protein, limit: 7 do |query, results, error|
5
- end
6
- end
7
-
8
- it "is a subclass of HKSampleQuery" do
9
- @subject.should.be.kind_of? HKSampleQuery
10
- end
11
-
12
- end
@@ -1,12 +0,0 @@
1
- describe "Medic::SourceQuery" do
2
-
3
- before do
4
- @subject = Medic::SourceQuery.new type: :dietary_protein do |query, sources, error|
5
- end
6
- end
7
-
8
- it "is a subclass of HKSourceQuery" do
9
- @subject.should.be.kind_of? HKSourceQuery
10
- end
11
-
12
- end
@@ -1,27 +0,0 @@
1
- describe "Medic::StatisticsCollectionQuery" do
2
-
3
- before do
4
- @interval = NSDateComponents.new
5
- @interval.day = 1
6
- @subject = Medic::StatisticsCollectionQuery.new(type: :step_count, options: :sum, interval: @interval)
7
- end
8
-
9
- it "is a subclass of HKStatisticsCollectionQuery" do
10
- @subject.should.be.kind_of? HKStatisticsCollectionQuery
11
- end
12
-
13
- describe "#initial_results_handler=" do
14
- it "sets initialResultsHandler with callback" do
15
- @subject.initial_results_handler = ->(){}
16
- @subject.initialResultsHandler.should.respond_to? :call
17
- end
18
- end
19
-
20
- describe "#statistics_update_handler=" do
21
- it "sets statisticsUpdateHandler with callback" do
22
- @subject.statistics_update_handler = ->(){}
23
- @subject.statisticsUpdateHandler.should.respond_to? :call
24
- end
25
- end
26
-
27
- end
@@ -1,12 +0,0 @@
1
- describe "Medic::StatisticsQuery" do
2
-
3
- before do
4
- @subject = Medic::StatisticsQuery.new type: :step_count, options: :sum do |query, results, error|
5
- end
6
- end
7
-
8
- it "is a subclass of HKStatisticsQuery" do
9
- @subject.should.be.kind_of? HKStatisticsQuery
10
- end
11
-
12
- end