milk_cap 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YTA1NGE1OTViOTc2NDBkMDdlNjY0ZDkxNjJlYjIxYzM4YzU3NGJiNQ==
4
+ MzIzYTI4ZjQ3M2IxOTBhNzUwNmQxZjc4ZTZiNjRkM2M1Y2UzNDU1ZA==
5
5
  data.tar.gz: !binary |-
6
- OTA0NmMxYjUxZjViY2FhZTUxMTViMDg0NDQ5YTlkZWVhNDQ2MjEwNQ==
6
+ YzE1NGNhZjk2NjQ5ZjFjMWViYTJlMzM3NGJhNDIxNGNkNjJiOGRhNA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmYwMWQ4MGQ5Y2QwMjE1NmE0MTFiOTM2OTY5OGQzMmYyMzE0OThjNzcxZjBl
10
- Njg4ODgxZTE0NGMxZWUzYWNiZGQ2YzZjMTk3NDhlZjVjYjEwNGU3YTczOWEz
11
- ZDIxZTk4MGQ1YTRlNzM2YzIyZGE5ZDQzODZhYTA3ZWFhNmQ0NjU=
9
+ NWE4OThhYmUzMWViMTA3MzNmNDRhNTYyZTA5ZWQwMjEwOTc3YTU4MzI1N2I1
10
+ NWVhYmRiNTAwNWQ2OWU1MThjMTQxZmRmYjE0MjA5OTJlMTJjNWMyMWI5ODMw
11
+ YWY4YjQ0YmZiMzcyOTE1N2I2MmM4ODJlMTYyZDI4MDU4MTMyZWI=
12
12
  data.tar.gz: !binary |-
13
- OGQzYzQ0ODMzMGIwODhhNjkwYWJmYmQ1ZTM4MGZmN2E0YzcyMDAyYThkZDM2
14
- NjY5OWQxYzg4MDFkNzE2MzFkMDBjNDdlN2M2ZmI5YjY1ZDUyMGNiMDRhNDll
15
- YTIwNGFhM2M3NGYzNjkyMWE2OTk5MjhlNWMyN2NmMmQ5ODYwNzU=
13
+ ZTM3NDM3ZTRlYWExMWVjYzI2ZDZjMDFlM2JmYzY1MzVhNmI2MzllOTlmODI3
14
+ ZjRmNjc3MTMxYTNmMjQ1YjIwOGNhMzE3NjViMTVkNmJlMTBjMGJiMGU5NzMw
15
+ YTcwMDBiMGE1MGRhYjczODJjNjk4OTE5MTJkNWQ1NDQzMGE5OWM=
data/CHANGELOG.txt CHANGED
@@ -1,6 +1,15 @@
1
1
 
2
2
  = milk_cap CHANGELOG.txt
3
3
 
4
+ == milk_cap - 0.5.2 released 2014/03/06
5
+
6
+ - converted from test/unit to rspec, removed test files from gem distribution
7
+ - removed forced 1 second sleep in RTM API calls
8
+ - removed new timeline creation for each #add! call, now reuses single timeline
9
+ - supports setting task tags
10
+ - BUGFIX: correctly parse taskseries with tasks array
11
+
12
+
4
13
  == milk_cap - 0.5.1 released 2014/01/03
5
14
 
6
15
  - removed rufus-verbs dependency (and rufus-lru)
data/README.rdoc CHANGED
@@ -96,6 +96,13 @@ make then sure that all the 4 variables are set in the environment you use for r
96
96
 
97
97
  task.complete!
98
98
 
99
+ #
100
+ # set tags for a task
101
+
102
+ task.tags = 'tag1,tag2'
103
+ task.tags = ['tag1', 'tag2'] # alternative
104
+ task.save!
105
+
99
106
  #
100
107
  # deleting a task
101
108
 
@@ -104,14 +111,10 @@ make then sure that all the 4 variables are set in the environment you use for r
104
111
 
105
112
  Note that the methods that change the state of the Remember The Milk dataset have names ending with an exclamation mark.
106
113
 
107
- Note as well that, there is a 1 second delay before any request to the RTM server, in order to respect their conditions. This may change in future releases.
108
-
109
114
 
110
- == features yet to implement
115
+ == development
111
116
 
112
- * tags modifications
113
- * smart lists
114
- * ...
117
+ * Testing with rspec -- run suite with 'rspec', 'rake' or 'rake spec'.
115
118
 
116
119
 
117
120
  == issue tracker
data/Rakefile CHANGED
@@ -7,12 +7,19 @@ require 'rubygems'
7
7
  require 'rake'
8
8
 
9
9
 
10
+ #
11
+ # TEST
12
+
13
+ require 'rspec/core/rake_task'
14
+ RSpec::Core::RakeTask.new(:spec)
15
+ task :default => :spec
16
+
17
+
10
18
  #
11
19
  # CLEAN
12
20
 
13
21
  require 'rake/clean'
14
22
  CLEAN.include('pkg', 'tmp', 'html')
15
- task :default => [ :clean ]
16
23
 
17
24
 
18
25
  #
@@ -34,9 +41,11 @@ Jeweler::Tasks.new do |gem|
34
41
  gem.authors = [ 'John Mettraux', 'Jeff Leverenz' ]
35
42
  gem.licenses = 'MIT'
36
43
 
37
- gem.test_file = 'test/test.rb'
44
+ gem.files.exclude 'spec/**'
38
45
 
39
46
  gem.add_development_dependency 'yard', '>= 0'
47
+ gem.add_development_dependency 'rspec', '~> 2.14'
48
+ gem.add_development_dependency 'jeweler', '~> 2.0.1'
40
49
  end
41
50
  Jeweler::GemcutterTasks.new
42
51
 
@@ -45,7 +45,7 @@ end
45
45
  module MilkCap
46
46
  module RTM
47
47
 
48
- VERSION = '0.5.1'
48
+ VERSION = '0.5.2'
49
49
 
50
50
  AUTH_ENDPOINT = "http://www.rememberthemilk.com/services/auth/"
51
51
  REST_ENDPOINT = "http://api.rememberthemilk.com/services/rest/"
@@ -63,8 +63,6 @@ module RTM
63
63
  #
64
64
  def self.milk (params={}) #:nodoc:
65
65
 
66
- sleep 1
67
-
68
66
  endpoint = params.delete(:endpoint)
69
67
  endpoint = AUTH_ENDPOINT if endpoint == :auth
70
68
  endpoint = endpoint || REST_ENDPOINT
@@ -0,0 +1,44 @@
1
+ module MilkCap::RTM
2
+
3
+ # Helper methods to normalize incoming data
4
+ module DataNormalization
5
+
6
+ # Converts various forms of tag lists into an Array of strings.
7
+ #
8
+ # +tags+ can be nil, a string of one or more comma separated tags, or an
9
+ # array. Returns an array of stripped strings.
10
+ def normalize_tags_array(tags)
11
+ return [] if tags.nil?
12
+
13
+ if tags.kind_of? String
14
+ tags = tags.split(",")
15
+ end
16
+ return tags.map { |i| i.strip }
17
+ end
18
+
19
+ # Normalize data values returned in RTM's json 'tags' keys to an Array of strings.
20
+ #
21
+ # RTM returns the value for it's 'tags' key in a few formats:
22
+ #
23
+ # When there are no tags, an empty JSON array: []
24
+ #
25
+ # When there is one tag, a hash with "tag" key, set to a string for the tagname:
26
+ # { "tag": "tagname" }
27
+ #
28
+ # When there are multiple tags, a hash with "tag" key, set to a JSON array of strings:
29
+ # { "tag": ["tagname1", "tagname2"] }
30
+ #
31
+ def normalize_rtm_tags_hash(tags_hash)
32
+ if tags_hash.is_a?(Array)
33
+ tags_hash
34
+ else
35
+ if tags_hash['tag'].is_a?(Array)
36
+ tags_hash['tag']
37
+ else
38
+ [tags_hash['tag']]
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ end
@@ -33,20 +33,6 @@ module MilkCap::RTM
33
33
  def initialize (hsh)
34
34
 
35
35
  @hsh = hsh
36
- @operations = []
37
- end
38
-
39
- # Saves the instance back to RTM.
40
- #
41
- def save!
42
-
43
- # TODO : compact !
44
-
45
- @operations.reverse.each do |method_name, args|
46
-
47
- self.class.execute method_name, args
48
- end
49
- @operations = []
50
36
  end
51
37
 
52
38
  protected
@@ -94,12 +80,7 @@ module MilkCap::RTM
94
80
  #
95
81
  def self.timeline
96
82
 
97
- @timeline ||= MilkCap::RTM.get_timeline
98
- end
99
-
100
- def queue_operation (method_name, args)
101
-
102
- @operations << [ method_name, args ]
83
+ @@timeline ||= MilkCap::RTM.get_timeline
103
84
  end
104
85
  end
105
86
 
@@ -107,13 +88,14 @@ module MilkCap::RTM
107
88
  # The RTM Task class.
108
89
  #
109
90
  class Task < MilkResource
91
+ include DataNormalization
110
92
 
111
93
  def self.task_attr (*att_names) #:nodoc:
112
94
 
113
95
  att_names.each do |att_name|
114
96
  class_eval %{
115
97
  def #{att_name}
116
- @hsh['task']['#{att_name}']
98
+ @task_hash['#{att_name}']
117
99
  end
118
100
  }
119
101
  end
@@ -145,17 +127,27 @@ module MilkCap::RTM
145
127
  :estimate,
146
128
  :due
147
129
 
148
- def initialize (list_id, h)
149
-
150
- super(h)
130
+ # Task series may have multiple tasks. task_hash used to specify which task
131
+ # in series.
132
+ def initialize (list_id, task_series_hash, task_hash)
151
133
 
152
- t = h['task']
134
+ super(task_series_hash)
135
+ @task_hash = task_hash
153
136
 
154
137
  @list_id = list_id
155
- @taskseries_id = h['id']
156
- @task_id = t['id']
138
+ @taskseries_id = task_series_hash['id']
139
+ @task_id = @task_hash['id']
157
140
 
158
- @tags = TagArray.new(self, h['tags'])
141
+ # Normalize the RTM structure and put it in TagArray
142
+ tags = normalize_rtm_tags_hash( task_series_hash['tags'] )
143
+ @tags = TagArray.new(self, tags)
144
+ end
145
+
146
+ def save!
147
+ if self.tags.dirty?
148
+ args = prepare_api_args.merge( tags: self.tags.join(",") )
149
+ self.class.execute('setTags', args)
150
+ end
159
151
  end
160
152
 
161
153
  # Deletes the task.
@@ -175,12 +167,8 @@ module MilkCap::RTM
175
167
  # Sets the tags for the task.
176
168
  #
177
169
  def tags= (tags)
178
-
179
- tags = tags.split(',') if tags.is_a?(String)
180
-
181
- @tags = TagArray.new(list_id, tags)
182
-
183
- queue_operation('setTasks', tags.join(','))
170
+ @tags = TagArray.new(self, normalize_tags_array(tags))
171
+ @tags.dirty!
184
172
  end
185
173
 
186
174
  def self.find (params={})
@@ -196,7 +184,7 @@ module MilkCap::RTM
196
184
  args = {}
197
185
  args[:name] = name
198
186
  args[:list_id] = opts[:list_id] if opts[:list_id]
199
- args[:timeline] = MilkCap::RTM.get_timeline
187
+ args[:timeline] = timeline
200
188
  args[:parse] = 1 unless !opts[:parse]
201
189
 
202
190
  h = execute('add', args)
@@ -237,9 +225,15 @@ module MilkCap::RTM
237
225
  end
238
226
 
239
227
  def self.parse_taskseries (list_id, o)
240
-
241
228
  o = [ o ] unless o.is_a?(Array)
242
- o.collect { |s| self.new(list_id, s) }
229
+
230
+ # o is an array of taskseries. Collect flattened array of tasks out of
231
+ # all taskseries
232
+ o.inject([]) do |m,s|
233
+ tasks = s['task']
234
+ tasks = [ tasks ] unless tasks.is_a?(Array)
235
+ m + tasks.collect { |t| self.new(list_id, s, t) }
236
+ end
243
237
  end
244
238
  end
245
239
 
@@ -271,54 +265,42 @@ module MilkCap::RTM
271
265
  class TagArray #:nodoc:
272
266
  include Enumerable
273
267
 
274
- def initialize (task, tags)
268
+ # TODO introduce method to return state change between clean & dirty tags
269
+ # in order to use addTags or removeTags instead of just setTags.
275
270
 
276
- @task = task
271
+ def initialize (task, tags)
272
+ @dirty = false
273
+ @prev = @tags = tags
274
+ end
277
275
 
278
- @tags = if tags.is_a?(Array)
279
- tags
280
- else
281
- tags['tag']
282
- end
276
+ def dirty=(dirty_state)
277
+ @dirty = dirty_state
278
+ @prev = @tags if !dirty_state
283
279
  end
280
+ def dirty!; self.dirty=true; end
281
+ def dirty?; @dirty; end
284
282
 
285
283
  def << (tag)
286
-
287
284
  @tags << tag
288
-
289
- args = prepare_api_args
290
- args[:tags] = tag
291
-
292
- @task.queue_operation('addTags', args)
285
+ self.dirty!
293
286
  end
294
287
 
295
288
  def delete (tag)
296
-
297
289
  @tags.delete tag
298
-
299
- args = prepare_api_args
300
- args[:tags] = tag
301
-
302
- @task.queue_operation('removeTags', args)
290
+ self.dirty!
303
291
  end
304
292
 
305
293
  def clear
306
294
 
307
295
  @tags.clear
308
-
309
- args = prepare_api_args
310
- args[:tags] = ''
311
-
312
- @task.queue_operation('setTags', args)
296
+ self.dirty!
313
297
  end
314
298
 
315
299
  def join (s)
316
-
317
300
  @tags.join(s)
318
301
  end
319
302
 
320
303
  def each
321
-
322
304
  @tags.each { |e| yield e }
323
305
  end
324
306
  end
data/lib/milk_cap/rtm.rb CHANGED
@@ -22,4 +22,5 @@
22
22
 
23
23
  require 'milk_cap/rtm/base'
24
24
  require 'milk_cap/rtm/credentials'
25
+ require 'milk_cap/rtm/data_normalization'
25
26
  require 'milk_cap/rtm/resources'
data/milk_cap.gemspec CHANGED
@@ -2,15 +2,15 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: milk_cap 0.5.1 ruby lib
5
+ # stub: milk_cap 0.5.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "milk_cap"
9
- s.version = "0.5.1"
9
+ s.version = "0.5.2"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["John Mettraux", "Jeff Leverenz"]
13
- s.date = "2014-01-03"
13
+ s.date = "2014-03-06"
14
14
  s.description = "\n Yet another RememberTheMilk wrapper, successor to rufus-rtm.\n "
15
15
  s.email = "jeff.leverenz@gmail.com"
16
16
  s.extra_rdoc_files = [
@@ -26,28 +26,32 @@ Gem::Specification.new do |s|
26
26
  "lib/milk_cap/rtm.rb",
27
27
  "lib/milk_cap/rtm/base.rb",
28
28
  "lib/milk_cap/rtm/credentials.rb",
29
+ "lib/milk_cap/rtm/data_normalization.rb",
29
30
  "lib/milk_cap/rtm/resources.rb",
30
- "milk_cap.gemspec",
31
- "test/tasks_test.rb",
32
- "test/test.rb"
31
+ "milk_cap.gemspec"
33
32
  ]
34
33
  s.homepage = "http://github.com/jleverenz/milk_cap/"
35
34
  s.licenses = ["MIT"]
36
35
  s.require_paths = ["lib"]
37
36
  s.rubygems_version = "2.1.11"
38
37
  s.summary = "Yet another RememberTheMilk wrapper, successor to rufus-rtm."
39
- s.test_files = ["test/test.rb"]
40
38
 
41
39
  if s.respond_to? :specification_version then
42
40
  s.specification_version = 4
43
41
 
44
42
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
43
  s.add_development_dependency(%q<yard>, [">= 0"])
44
+ s.add_development_dependency(%q<rspec>, ["~> 2.14"])
45
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
46
46
  else
47
47
  s.add_dependency(%q<yard>, [">= 0"])
48
+ s.add_dependency(%q<rspec>, ["~> 2.14"])
49
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
48
50
  end
49
51
  else
50
52
  s.add_dependency(%q<yard>, [">= 0"])
53
+ s.add_dependency(%q<rspec>, ["~> 2.14"])
54
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
51
55
  end
52
56
  end
53
57
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: milk_cap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-03 00:00:00.000000000 Z
12
+ date: 2014-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yard
@@ -25,6 +25,34 @@ dependencies:
25
25
  - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '2.14'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '2.14'
42
+ - !ruby/object:Gem::Dependency
43
+ name: jeweler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: 2.0.1
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 2.0.1
28
56
  description: ! "\n Yet another RememberTheMilk wrapper, successor to rufus-rtm.\n
29
57
  \ "
30
58
  email: jeff.leverenz@gmail.com
@@ -42,10 +70,9 @@ files:
42
70
  - lib/milk_cap/rtm.rb
43
71
  - lib/milk_cap/rtm/base.rb
44
72
  - lib/milk_cap/rtm/credentials.rb
73
+ - lib/milk_cap/rtm/data_normalization.rb
45
74
  - lib/milk_cap/rtm/resources.rb
46
75
  - milk_cap.gemspec
47
- - test/tasks_test.rb
48
- - test/test.rb
49
76
  homepage: http://github.com/jleverenz/milk_cap/
50
77
  licenses:
51
78
  - MIT
@@ -70,5 +97,4 @@ rubygems_version: 2.1.11
70
97
  signing_key:
71
98
  specification_version: 4
72
99
  summary: Yet another RememberTheMilk wrapper, successor to rufus-rtm.
73
- test_files:
74
- - test/test.rb
100
+ test_files: []
data/test/tasks_test.rb DELETED
@@ -1,113 +0,0 @@
1
- require 'rubygems'
2
-
3
- require 'test/unit'
4
-
5
- $: << File.dirname(__FILE__) + '/../lib'
6
-
7
- require 'milk_cap/rtm'
8
-
9
- include MilkCap::RTM
10
-
11
-
12
- class TasksTest < Test::Unit::TestCase
13
-
14
- #def setup
15
- #end
16
-
17
- #def teardown
18
- #end
19
-
20
- def test_0
21
-
22
- taskname = "milk the cow #{Time.now.to_i}"
23
-
24
- t0 = Task.add!(taskname)
25
-
26
- assert_kind_of Task, t0
27
- assert_equal taskname, t0.name
28
-
29
- ts = Task.find
30
-
31
- #puts "tasks : #{ts.size}"
32
-
33
- t1 = ts.find { |t| t.task_id == t0.task_id }
34
- assert_equal taskname, t1.name
35
- assert_equal '', t1.tags.join(',')
36
-
37
- ts = Task.find :filter => "status:incomplete"
38
-
39
- #puts "incomplete tasks : #{ts.size}"
40
-
41
- t1 = ts.find { |t| t.task_id == t0.task_id }
42
- assert_equal taskname, t1.name
43
-
44
- t1.delete!
45
-
46
- ts = Task.find :filter => "status:incomplete"
47
-
48
- t1 = ts.find { |t| t.task_id == t0.task_id }
49
- assert_nil t1
50
- end
51
-
52
- def test_1
53
-
54
- lists = List.find
55
- assert_not_nil(lists.find { |e| e.name == 'Inbox' })
56
-
57
- work = lists.find { |e| e.name == 'Work' }
58
-
59
- taskname = "more work #{Time.now.to_i}"
60
-
61
- t0 = Task.add! taskname, :list_id => work.list_id
62
-
63
- tasks = Task.find :list_id => work.list_id, :filer => 'status:incomplete'
64
-
65
- assert_not_nil(tasks.find { |t| t.task_id == t0.task_id })
66
-
67
- t0.complete!
68
-
69
- tasks = Task.find :list_id => work.list_id, :filer => 'status:completed'
70
- assert_not_nil(tasks.find { |t| t.task_id == t0.task_id })
71
-
72
- t0.delete!
73
- end
74
-
75
- def test_2
76
-
77
- key = ENV.delete('RTM_API_KEY')
78
- secret = ENV.delete('RTM_SHARED_SECRET')
79
-
80
- assert_raise RuntimeError do
81
- lists = List.find
82
- end
83
-
84
- assert_not_nil List.find(:api_key => key, :shared_secret => secret)
85
-
86
- ENV['RTM_API_KEY'] = key
87
- ENV['RTM_SHARED_SECRET'] = secret
88
- end
89
-
90
- def test_smart_add
91
- taskname = "more work #{Time.now.to_i}"
92
- smart_add_string = "#{taskname} tomorrow"
93
- task = Task.add! smart_add_string
94
-
95
- tasks = Task.find
96
-
97
- task_created = tasks.find { |t| t.task_id == task.task_id }
98
- assert !task_created.due.empty?
99
- assert_equal taskname, task_created.name # 'tomorrow' is stripped as due date
100
- end
101
-
102
- def test_turn_smart_add_off
103
- taskname = "more work #{Time.now.to_i} tomorrow"
104
- task = Task.add! taskname, :parse => false
105
-
106
- tasks = Task.find
107
-
108
- task_created = tasks.find { |t| t.task_id == task.task_id }
109
- assert task_created.due.empty?
110
- assert_equal taskname, task_created.name
111
- end
112
-
113
- end
data/test/test.rb DELETED
@@ -1,3 +0,0 @@
1
-
2
- Dir["#{File.dirname(__FILE__)}/*_test.rb"].each { |path| load(path) }
3
-