letsfreckle-client 0.1.0
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +39 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +75 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/letsfreckle-client.gemspec +87 -0
- data/lib/letsfreckle.rb +24 -0
- data/lib/letsfreckle/client_resource.rb +40 -0
- data/lib/letsfreckle/configuration.rb +10 -0
- data/lib/letsfreckle/entry.rb +40 -0
- data/lib/letsfreckle/error.rb +6 -0
- data/lib/letsfreckle/extensions/mash.rb +13 -0
- data/lib/letsfreckle/project.rb +13 -0
- data/lib/letsfreckle/tag.rb +13 -0
- data/lib/letsfreckle/user.rb +13 -0
- data/spec/letsfreckle/configuration_spec.rb +17 -0
- data/spec/letsfreckle/entry_spec.rb +20 -0
- data/spec/letsfreckle/project_spec.rb +20 -0
- data/spec/letsfreckle/tag_spec.rb +20 -0
- data/spec/letsfreckle/user_spec.rb +20 -0
- data/spec/responses/entries.xml.response +55 -0
- data/spec/responses/projects.xml.response +25 -0
- data/spec/responses/tags.xml.response +19 -0
- data/spec/responses/users.xml.response +23 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/webmock_helper.rb +5 -0
- metadata +192 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.2.6)
|
5
|
+
crack (0.1.8)
|
6
|
+
diff-lcs (1.1.2)
|
7
|
+
git (1.2.5)
|
8
|
+
hashie (1.0.0)
|
9
|
+
httparty (0.7.8)
|
10
|
+
crack (= 0.1.8)
|
11
|
+
jeweler (1.6.4)
|
12
|
+
bundler (~> 1.0)
|
13
|
+
git (>= 1.2.5)
|
14
|
+
rake
|
15
|
+
rake (0.9.2)
|
16
|
+
rcov (0.9.9)
|
17
|
+
rspec (2.5.0)
|
18
|
+
rspec-core (~> 2.5.0)
|
19
|
+
rspec-expectations (~> 2.5.0)
|
20
|
+
rspec-mocks (~> 2.5.0)
|
21
|
+
rspec-core (2.5.2)
|
22
|
+
rspec-expectations (2.5.0)
|
23
|
+
diff-lcs (~> 1.1.2)
|
24
|
+
rspec-mocks (2.5.0)
|
25
|
+
webmock (1.6.4)
|
26
|
+
addressable (~> 2.2, > 2.2.5)
|
27
|
+
crack (>= 0.1.7)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
bundler (~> 1.0.0)
|
34
|
+
hashie
|
35
|
+
httparty
|
36
|
+
jeweler (~> 1.6.4)
|
37
|
+
rcov
|
38
|
+
rspec (~> 2.5.0)
|
39
|
+
webmock (~> 1.6.2)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Ryan LeCompte
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
= letsfreckle-client
|
2
|
+
|
3
|
+
letsfreckle-client is a Ruby client for accessing the Let's Freckle API.
|
4
|
+
Let's Freckle is an intuitive time-tracking service.
|
5
|
+
See http://www.letsfreckle.com for more information.
|
6
|
+
|
7
|
+
API information can be found at http://madrobby.github.com/freckle-apidocs/
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
letsfreckle-client is available as a RubyGem:
|
12
|
+
|
13
|
+
gem install letsfreckle-client
|
14
|
+
|
15
|
+
== Examples
|
16
|
+
|
17
|
+
The following examples show how to access functions of the API. In order to use
|
18
|
+
the client, you must have an API token. You can access your token via your
|
19
|
+
letsfreckle.com settings/profile. Note that currently letsfreckle.com hosts
|
20
|
+
a sample API test account, which the following examples utilize.
|
21
|
+
|
22
|
+
=== Example:
|
23
|
+
|
24
|
+
# Configure the client before fetching data.
|
25
|
+
LetsFreckle.configure do
|
26
|
+
account_host "apitest"
|
27
|
+
username "apitest@letsfreckle.com"
|
28
|
+
token "lx3gi6pxdjtjn57afp8c2bv1me7g89j"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Submit a new entry.
|
32
|
+
LetsFreckle::Entry.create(:project_id => 3427, :minutes => '1h', :description => 'fixed a bug')
|
33
|
+
|
34
|
+
# Fetch all entries.
|
35
|
+
LetsFreckle::Entry.all.each do |entry|
|
36
|
+
puts "Entry #{entry.description} - #{entry.minutes} minutes"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Search for entries from a specific start date and tags
|
40
|
+
LetsFreckle::Entry.find(:from => '2010-07-10', :tags => ['development', 'design']).each do |entry|
|
41
|
+
puts entry.description
|
42
|
+
end
|
43
|
+
|
44
|
+
# Fetch all projects and associated entries
|
45
|
+
LetsFreckle::Project.all.each do |project|
|
46
|
+
puts "Project #{project.name} has #{project.entries.size} entries"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Fetch all tags and associated entries
|
50
|
+
LetsFreckle::Tag.all.each do |tag|
|
51
|
+
puts "Tag #{tag.name} has #{tag.entries.size} entries"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Fetch all users and associated permissions
|
55
|
+
LetsFreckle::User.all.each do |user|
|
56
|
+
puts "User #{user.email} has following permissions: #{user.permissions}"
|
57
|
+
end
|
58
|
+
|
59
|
+
== Note on Patches/Pull Requests
|
60
|
+
|
61
|
+
* Fork the project.
|
62
|
+
* Make your feature addition or bug fix.
|
63
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
64
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
65
|
+
* Send me a pull request. Bonus points for topic branches.
|
66
|
+
|
67
|
+
== Authors
|
68
|
+
|
69
|
+
* Ryan LeCompte
|
70
|
+
|
71
|
+
== Copyright
|
72
|
+
|
73
|
+
Copyright (c) 2011 Ryan LeCompte. See LICENSE.txt for
|
74
|
+
further details.
|
75
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "letsfreckle-client"
|
18
|
+
gem.homepage = "http://github.com/ryanlecompte/letsfreckle-client"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Ruby client for letsfreckle.com API}
|
21
|
+
gem.description = %Q{Ruby client for letsfreckle.com API that supports entries, projects, tags, and users}
|
22
|
+
gem.email = "lecompte@gmail.com"
|
23
|
+
gem.authors = ["Ryan LeCompte"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
task :default => :spec
|
40
|
+
|
41
|
+
require 'rake/rdoctask'
|
42
|
+
Rake::RDocTask.new do |rdoc|
|
43
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
44
|
+
|
45
|
+
rdoc.rdoc_dir = 'rdoc'
|
46
|
+
rdoc.title = "letsfreckle-client #{version}"
|
47
|
+
rdoc.rdoc_files.include('README*')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{letsfreckle-client}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ryan LeCompte"]
|
12
|
+
s.date = %q{2011-07-25}
|
13
|
+
s.description = %q{Ruby client for letsfreckle.com API that supports entries, projects, tags, and users}
|
14
|
+
s.email = %q{lecompte@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"letsfreckle-client.gemspec",
|
29
|
+
"lib/letsfreckle.rb",
|
30
|
+
"lib/letsfreckle/client_resource.rb",
|
31
|
+
"lib/letsfreckle/configuration.rb",
|
32
|
+
"lib/letsfreckle/entry.rb",
|
33
|
+
"lib/letsfreckle/error.rb",
|
34
|
+
"lib/letsfreckle/extensions/mash.rb",
|
35
|
+
"lib/letsfreckle/project.rb",
|
36
|
+
"lib/letsfreckle/tag.rb",
|
37
|
+
"lib/letsfreckle/user.rb",
|
38
|
+
"spec/letsfreckle/configuration_spec.rb",
|
39
|
+
"spec/letsfreckle/entry_spec.rb",
|
40
|
+
"spec/letsfreckle/project_spec.rb",
|
41
|
+
"spec/letsfreckle/tag_spec.rb",
|
42
|
+
"spec/letsfreckle/user_spec.rb",
|
43
|
+
"spec/responses/entries.xml.response",
|
44
|
+
"spec/responses/projects.xml.response",
|
45
|
+
"spec/responses/tags.xml.response",
|
46
|
+
"spec/responses/users.xml.response",
|
47
|
+
"spec/spec_helper.rb",
|
48
|
+
"spec/support/webmock_helper.rb"
|
49
|
+
]
|
50
|
+
s.homepage = %q{http://github.com/ryanlecompte/letsfreckle-client}
|
51
|
+
s.licenses = ["MIT"]
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.3.7}
|
54
|
+
s.summary = %q{Ruby client for letsfreckle.com API}
|
55
|
+
|
56
|
+
if s.respond_to? :specification_version then
|
57
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
58
|
+
s.specification_version = 3
|
59
|
+
|
60
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
61
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
62
|
+
s.add_runtime_dependency(%q<hashie>, [">= 0"])
|
63
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.5.0"])
|
64
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
65
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
66
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<webmock>, ["~> 1.6.2"])
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
70
|
+
s.add_dependency(%q<hashie>, [">= 0"])
|
71
|
+
s.add_dependency(%q<rspec>, ["~> 2.5.0"])
|
72
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
73
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
74
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
75
|
+
s.add_dependency(%q<webmock>, ["~> 1.6.2"])
|
76
|
+
end
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<httparty>, [">= 0"])
|
79
|
+
s.add_dependency(%q<hashie>, [">= 0"])
|
80
|
+
s.add_dependency(%q<rspec>, ["~> 2.5.0"])
|
81
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
82
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
83
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
84
|
+
s.add_dependency(%q<webmock>, ["~> 1.6.2"])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
data/lib/letsfreckle.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'httparty'
|
3
|
+
require 'delegate'
|
4
|
+
|
5
|
+
require 'letsfreckle/extensions/mash'
|
6
|
+
require 'letsfreckle/configuration'
|
7
|
+
require 'letsfreckle/client_resource'
|
8
|
+
require 'letsfreckle/project'
|
9
|
+
require 'letsfreckle/error'
|
10
|
+
require 'letsfreckle/entry'
|
11
|
+
require 'letsfreckle/user'
|
12
|
+
require 'letsfreckle/tag'
|
13
|
+
|
14
|
+
module LetsFreckle
|
15
|
+
extend self
|
16
|
+
|
17
|
+
attr_reader :config
|
18
|
+
|
19
|
+
def configure(&block)
|
20
|
+
raise ArgumentError, 'configuration block required' unless block
|
21
|
+
@config = Configuration.new
|
22
|
+
@config.instance_eval(&block)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module LetsFreckle
|
2
|
+
# ClientResource should be extended by resource classes in order to gain
|
3
|
+
# access to HTTP methods.
|
4
|
+
module ClientResource
|
5
|
+
API_URL = "https://%s.letsfreckle.com/api/%s.xml?token=%s"
|
6
|
+
|
7
|
+
def fetch(resource, options = {})
|
8
|
+
response = HTTParty.get(url(resource), :query => options, :format => :xml)
|
9
|
+
verify!(response, 200) { raise FetchError, "Fetch failed, HTTP error: #{response.code}" }
|
10
|
+
mashes = mashes_from_response(response)
|
11
|
+
mashes.map { |m| new(m) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(resource, options = {})
|
15
|
+
response = HTTParty.post(url(resource), :body => options, :format => :xml)
|
16
|
+
verify!(response, 201) { raise CreateError, "Create failed, HTTP error: #{response.code}" }
|
17
|
+
end
|
18
|
+
|
19
|
+
def url(resource)
|
20
|
+
API_URL % [LetsFreckle.config.account_host, resource, LetsFreckle.config.token]
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def verify!(response, code, &block)
|
26
|
+
block.call unless response.code == code
|
27
|
+
end
|
28
|
+
|
29
|
+
def mashes_from_response(response)
|
30
|
+
return [] unless response.respond_to?(:to_a)
|
31
|
+
flattened_response = response.to_a.flatten
|
32
|
+
flattened_response.keep_if { |r| r.is_a?(Hash) }
|
33
|
+
flattened_response.map do |h|
|
34
|
+
m = Hashie::Mash.new(h)
|
35
|
+
# extend so that #respond_to? works nicely with DelegateClass
|
36
|
+
m.extend(Extensions::Mash)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module LetsFreckle
|
2
|
+
class Configuration
|
3
|
+
[:username, :account_host, :token].each do |method_name|
|
4
|
+
define_method(method_name) do |value=nil|
|
5
|
+
instance_variable_set("@#{method_name}", value) if value
|
6
|
+
instance_variable_get("@#{method_name}")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module LetsFreckle
|
2
|
+
class Entry < DelegateClass(Hashie::Mash)
|
3
|
+
extend ClientResource
|
4
|
+
|
5
|
+
def self.all
|
6
|
+
fetch('entries')
|
7
|
+
end
|
8
|
+
|
9
|
+
# Fetches all entries. Supported options are:
|
10
|
+
# :people => ['ryan', 'frank']
|
11
|
+
# :projects => ['project1', 'project2']
|
12
|
+
# :tags => ['tag1', 'tag2']
|
13
|
+
# :from => '2011-01-01'
|
14
|
+
# :to => '2012-01-01'
|
15
|
+
# :billable => true/false
|
16
|
+
def self.find(options = {})
|
17
|
+
fetch('entries', searchable_options_from(options))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Creates a new entry. Supported options are:
|
21
|
+
# :minutes => '4h' (required)
|
22
|
+
# :project_id => 3221
|
23
|
+
# :description => 'new task'
|
24
|
+
# :date => '2011-08-01'
|
25
|
+
def self.create(options = {})
|
26
|
+
raise ArgumentError, ':username config missing' unless LetsFreckle.config.username
|
27
|
+
raise ArgumentError, ':minutes missing' unless options.has_key?(:minutes)
|
28
|
+
post('entries', :entry => options.merge(:user => LetsFreckle.config.username))
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.searchable_options_from(options = {})
|
32
|
+
options.each_with_object({}) do |(key, value), result|
|
33
|
+
case value
|
34
|
+
when Array then result["search[#{key}]"] = value.join(',')
|
35
|
+
else result["search[#{key}]"] = value.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Ruby's DelegateClass expects the delegate to support the second
|
2
|
+
# optional argument to Object#respond_to?. Hashie::Mash doesn't
|
3
|
+
# currently define the method in this way, so we provide a module
|
4
|
+
# that is #extend'ed into each Hashie::Mash instance that we create.
|
5
|
+
module LetsFreckle
|
6
|
+
module Extensions
|
7
|
+
module Mash
|
8
|
+
def respond_to?(sym, include_private=false)
|
9
|
+
super(sym)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LetsFreckle::Configuration do
|
4
|
+
context "as DSL" do
|
5
|
+
it "should properly set and read config values" do
|
6
|
+
LetsFreckle.configure do
|
7
|
+
username "user"
|
8
|
+
account_host "userhost"
|
9
|
+
token "secret"
|
10
|
+
end
|
11
|
+
|
12
|
+
LetsFreckle.config.username.should == "user"
|
13
|
+
LetsFreckle.config.account_host.should == "userhost"
|
14
|
+
LetsFreckle.config.token.should == "secret"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LetsFreckle::Entry do
|
4
|
+
context "#all" do
|
5
|
+
it "should return all entries" do
|
6
|
+
LetsFreckle.configure do
|
7
|
+
username "username"
|
8
|
+
account_host "host"
|
9
|
+
token "secret"
|
10
|
+
end
|
11
|
+
|
12
|
+
stub_http_request(:get, LetsFreckle::Entry.url('entries')).to_return(:body => load_response('entries'))
|
13
|
+
entries = LetsFreckle::Entry.all
|
14
|
+
entries.size.should == 2
|
15
|
+
|
16
|
+
first_entry = entries.first
|
17
|
+
first_entry.description.should == 'api test description'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LetsFreckle::Project do
|
4
|
+
context "#all" do
|
5
|
+
it "should return all projects" do
|
6
|
+
LetsFreckle.configure do
|
7
|
+
username "username"
|
8
|
+
account_host "host"
|
9
|
+
token "secret"
|
10
|
+
end
|
11
|
+
|
12
|
+
stub_http_request(:get, LetsFreckle::Project.url('projects')).to_return(:body => load_response('projects'))
|
13
|
+
projects = LetsFreckle::Project.all
|
14
|
+
projects.size.should == 2
|
15
|
+
|
16
|
+
first_project = projects.first
|
17
|
+
first_project.name.should == 'TestProject1'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LetsFreckle::Tag do
|
4
|
+
context "#all" do
|
5
|
+
it "should return all tags" do
|
6
|
+
LetsFreckle.configure do
|
7
|
+
username "username"
|
8
|
+
account_host "host"
|
9
|
+
token "secret"
|
10
|
+
end
|
11
|
+
|
12
|
+
stub_http_request(:get, LetsFreckle::Tag.url('tags')).to_return(:body => load_response('tags'))
|
13
|
+
tags = LetsFreckle::Tag.all
|
14
|
+
tags.size.should == 2
|
15
|
+
|
16
|
+
first_tag = tags.first
|
17
|
+
first_tag.name.should == 'test tag 1'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LetsFreckle::User do
|
4
|
+
context "#all" do
|
5
|
+
it "should return all users" do
|
6
|
+
LetsFreckle.configure do
|
7
|
+
username "username"
|
8
|
+
account_host "host"
|
9
|
+
token "secret"
|
10
|
+
end
|
11
|
+
|
12
|
+
stub_http_request(:get, LetsFreckle::User.url('users')).to_return(:body => load_response('users'))
|
13
|
+
users = LetsFreckle::User.all
|
14
|
+
users.size.should == 2
|
15
|
+
|
16
|
+
first_user = users.first
|
17
|
+
first_user.email.should == 'apitest@letsfreckle.com'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<entries type="array">
|
3
|
+
<entry>
|
4
|
+
<billable type="boolean">true</billable>
|
5
|
+
<created-at type="datetime">2011-05-25T13:15:35Z</created-at>
|
6
|
+
<date type="date">2011-11-25</date>
|
7
|
+
<description>api test description</description>
|
8
|
+
<description-text>freckle restful api test</description-text>
|
9
|
+
<id type="integer">986234</id>
|
10
|
+
<import-id type="integer" nil="true"></import-id>
|
11
|
+
<invoiced-at type="datetime" nil="true"></invoiced-at>
|
12
|
+
<minutes type="integer">30</minutes>
|
13
|
+
<project-id type="integer" nil="true"></project-id>
|
14
|
+
<project-invoice-id type="integer" nil="true"></project-invoice-id>
|
15
|
+
<recently-updated-at type="datetime">2011-05-25T13:15:35Z</recently-updated-at>
|
16
|
+
<time-from type="integer" nil="true"></time-from>
|
17
|
+
<time-to type="integer" nil="true"></time-to>
|
18
|
+
<updated-at type="datetime">2011-05-25T13:15:35Z</updated-at>
|
19
|
+
<url nil="true"></url>
|
20
|
+
<user-id type="integer">5543</user-id>
|
21
|
+
<tags type="array">
|
22
|
+
<tag>
|
23
|
+
<billable type="boolean">true</billable>
|
24
|
+
<id type="integer">23035</id>
|
25
|
+
<name>bulk import</name>
|
26
|
+
</tag>
|
27
|
+
</tags>
|
28
|
+
</entry>
|
29
|
+
<entry>
|
30
|
+
<billable type="boolean">true</billable>
|
31
|
+
<created-at type="datetime">2011-02-18T15:27:57Z</created-at>
|
32
|
+
<date type="date">2011-01-28</date>
|
33
|
+
<description>api test description</description>
|
34
|
+
<description-text></description-text>
|
35
|
+
<id type="integer">708805</id>
|
36
|
+
<import-id type="integer" nil="true"></import-id>
|
37
|
+
<invoiced-at type="datetime" nil="true"></invoiced-at>
|
38
|
+
<minutes type="integer">420</minutes>
|
39
|
+
<project-id type="integer">8475</project-id>
|
40
|
+
<project-invoice-id type="integer" nil="true"></project-invoice-id>
|
41
|
+
<recently-updated-at type="datetime">2011-02-18T15:27:57Z</recently-updated-at>
|
42
|
+
<time-from type="integer" nil="true"></time-from>
|
43
|
+
<time-to type="integer" nil="true"></time-to>
|
44
|
+
<updated-at type="datetime">2011-02-18T15:27:57Z</updated-at>
|
45
|
+
<url nil="true"></url>
|
46
|
+
<user-id type="integer">5543</user-id>
|
47
|
+
<tags type="array">
|
48
|
+
<tag>
|
49
|
+
<billable type="boolean">true</billable>
|
50
|
+
<id type="integer">123124</id>
|
51
|
+
<name>- instru</name>
|
52
|
+
</tag>
|
53
|
+
</tags>
|
54
|
+
</entry>
|
55
|
+
</entries>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<projects type="array">
|
3
|
+
<project>
|
4
|
+
<account-id type="integer">100</account-id>
|
5
|
+
<budget type="integer" nil="true"></budget>
|
6
|
+
<created-at type="datetime">2008-12-19T16:21:34Z</created-at>
|
7
|
+
<enabled type="boolean">true</enabled>
|
8
|
+
<id type="integer">1343</id>
|
9
|
+
<name>TestProject1</name>
|
10
|
+
<stepping type="integer">15</stepping>
|
11
|
+
<updated-at type="datetime">2008-12-19T16:21:34Z</updated-at>
|
12
|
+
<user-id type="integer" nil="true"></user-id>
|
13
|
+
</project>
|
14
|
+
<project>
|
15
|
+
<account-id type="integer">100</account-id>
|
16
|
+
<budget type="integer" nil="true"></budget>
|
17
|
+
<created-at type="datetime">2008-12-19T16:23:06Z</created-at>
|
18
|
+
<enabled type="boolean">true</enabled>
|
19
|
+
<id type="integer">1344</id>
|
20
|
+
<name>TestProject2</name>
|
21
|
+
<stepping type="integer">15</stepping>
|
22
|
+
<updated-at type="datetime">2008-12-19T16:23:06Z</updated-at>
|
23
|
+
<user-id type="integer" nil="true"></user-id>
|
24
|
+
</project>
|
25
|
+
</projects>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<tags type="array">
|
3
|
+
<tag>
|
4
|
+
<account-id type="integer">5039</account-id>
|
5
|
+
<billable type="boolean">true</billable>
|
6
|
+
<created-at type="datetime">2009-10-16T09:57:22Z</created-at>
|
7
|
+
<id type="integer">23035</id>
|
8
|
+
<name>test tag 1</name>
|
9
|
+
<updated-at type="datetime">2009-10-16T09:57:22Z</updated-at>
|
10
|
+
</tag>
|
11
|
+
<tag>
|
12
|
+
<account-id type="integer">5039</account-id>
|
13
|
+
<billable type="boolean">true</billable>
|
14
|
+
<created-at type="datetime">2009-10-16T09:04:50Z</created-at>
|
15
|
+
<id type="integer">23029</id>
|
16
|
+
<name>conf call</name>
|
17
|
+
<updated-at type="datetime">2009-10-16T09:04:50Z</updated-at>
|
18
|
+
</tag>
|
19
|
+
</tags>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<users type="array">
|
3
|
+
<user>
|
4
|
+
<email>apitest@letsfreckle.com</email>
|
5
|
+
<first-name>Test</first-name>
|
6
|
+
<id type="integer">5538</id>
|
7
|
+
<last-name>User</last-name>
|
8
|
+
<login>test</login>
|
9
|
+
<time-format>fraction</time-format>
|
10
|
+
<week-start>Sunday</week-start>
|
11
|
+
<permissions>integration, time, invoicing, reports, tags, expenses, projects, team, people, account, billing, import</permissions>
|
12
|
+
</user>
|
13
|
+
<user>
|
14
|
+
<email>apitest2@letsfreckle.com</email>
|
15
|
+
<first-name>Test2</first-name>
|
16
|
+
<id type="integer">5539</id>
|
17
|
+
<last-name>User</last-name>
|
18
|
+
<login>test2</login>
|
19
|
+
<time-format>fraction</time-format>
|
20
|
+
<week-start>Monday</week-start>
|
21
|
+
<permissions>integration, time, invoicing, reports, tags, expenses, projects, team</permissions>
|
22
|
+
</user>
|
23
|
+
</users>
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'webmock/rspec'
|
5
|
+
require 'letsfreckle'
|
6
|
+
|
7
|
+
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.include(WebMockHelper)
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: letsfreckle-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Ryan LeCompte
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-07-25 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: httparty
|
22
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
prerelease: false
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: hashie
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
version: "0"
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 2
|
55
|
+
- 5
|
56
|
+
- 0
|
57
|
+
version: 2.5.0
|
58
|
+
type: :development
|
59
|
+
prerelease: false
|
60
|
+
version_requirements: *id003
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: bundler
|
63
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
segments:
|
69
|
+
- 1
|
70
|
+
- 0
|
71
|
+
- 0
|
72
|
+
version: 1.0.0
|
73
|
+
type: :development
|
74
|
+
prerelease: false
|
75
|
+
version_requirements: *id004
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: jeweler
|
78
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 1
|
85
|
+
- 6
|
86
|
+
- 4
|
87
|
+
version: 1.6.4
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rcov
|
93
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
type: :development
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: *id006
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: webmock
|
106
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
segments:
|
112
|
+
- 1
|
113
|
+
- 6
|
114
|
+
- 2
|
115
|
+
version: 1.6.2
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: *id007
|
119
|
+
description: Ruby client for letsfreckle.com API that supports entries, projects, tags, and users
|
120
|
+
email: lecompte@gmail.com
|
121
|
+
executables: []
|
122
|
+
|
123
|
+
extensions: []
|
124
|
+
|
125
|
+
extra_rdoc_files:
|
126
|
+
- LICENSE.txt
|
127
|
+
- README.rdoc
|
128
|
+
files:
|
129
|
+
- .document
|
130
|
+
- .rspec
|
131
|
+
- Gemfile
|
132
|
+
- Gemfile.lock
|
133
|
+
- LICENSE.txt
|
134
|
+
- README.rdoc
|
135
|
+
- Rakefile
|
136
|
+
- VERSION
|
137
|
+
- letsfreckle-client.gemspec
|
138
|
+
- lib/letsfreckle.rb
|
139
|
+
- lib/letsfreckle/client_resource.rb
|
140
|
+
- lib/letsfreckle/configuration.rb
|
141
|
+
- lib/letsfreckle/entry.rb
|
142
|
+
- lib/letsfreckle/error.rb
|
143
|
+
- lib/letsfreckle/extensions/mash.rb
|
144
|
+
- lib/letsfreckle/project.rb
|
145
|
+
- lib/letsfreckle/tag.rb
|
146
|
+
- lib/letsfreckle/user.rb
|
147
|
+
- spec/letsfreckle/configuration_spec.rb
|
148
|
+
- spec/letsfreckle/entry_spec.rb
|
149
|
+
- spec/letsfreckle/project_spec.rb
|
150
|
+
- spec/letsfreckle/tag_spec.rb
|
151
|
+
- spec/letsfreckle/user_spec.rb
|
152
|
+
- spec/responses/entries.xml.response
|
153
|
+
- spec/responses/projects.xml.response
|
154
|
+
- spec/responses/tags.xml.response
|
155
|
+
- spec/responses/users.xml.response
|
156
|
+
- spec/spec_helper.rb
|
157
|
+
- spec/support/webmock_helper.rb
|
158
|
+
has_rdoc: true
|
159
|
+
homepage: http://github.com/ryanlecompte/letsfreckle-client
|
160
|
+
licenses:
|
161
|
+
- MIT
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options: []
|
164
|
+
|
165
|
+
require_paths:
|
166
|
+
- lib
|
167
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
168
|
+
none: false
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
hash: 24628150016863968
|
173
|
+
segments:
|
174
|
+
- 0
|
175
|
+
version: "0"
|
176
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
segments:
|
182
|
+
- 0
|
183
|
+
version: "0"
|
184
|
+
requirements: []
|
185
|
+
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 1.3.7
|
188
|
+
signing_key:
|
189
|
+
specification_version: 3
|
190
|
+
summary: Ruby client for letsfreckle.com API
|
191
|
+
test_files: []
|
192
|
+
|