harvested2 5.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.gitignore +35 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +34 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +12 -0
  8. data/Gemfile +20 -0
  9. data/HISTORY.md +118 -0
  10. data/MIT-LICENSE +21 -0
  11. data/README.md +66 -0
  12. data/Rakefile +24 -0
  13. data/harvested2.gemspec +30 -0
  14. data/lib/ext/array.rb +52 -0
  15. data/lib/ext/date.rb +9 -0
  16. data/lib/ext/hash.rb +17 -0
  17. data/lib/ext/time.rb +5 -0
  18. data/lib/harvest/account.rb +13 -0
  19. data/lib/harvest/api/account.rb +25 -0
  20. data/lib/harvest/api/base.rb +72 -0
  21. data/lib/harvest/api/clients.rb +10 -0
  22. data/lib/harvest/api/company.rb +12 -0
  23. data/lib/harvest/api/contacts.rb +9 -0
  24. data/lib/harvest/api/expense_categories.rb +9 -0
  25. data/lib/harvest/api/expenses.rb +26 -0
  26. data/lib/harvest/api/invoice_categories.rb +9 -0
  27. data/lib/harvest/api/invoice_messages.rb +86 -0
  28. data/lib/harvest/api/invoice_payments.rb +41 -0
  29. data/lib/harvest/api/invoices.rb +9 -0
  30. data/lib/harvest/api/projects.rb +9 -0
  31. data/lib/harvest/api/task_assignments.rb +75 -0
  32. data/lib/harvest/api/tasks.rb +9 -0
  33. data/lib/harvest/api/time_entry.rb +19 -0
  34. data/lib/harvest/api/user_assignments.rb +75 -0
  35. data/lib/harvest/api/users.rb +10 -0
  36. data/lib/harvest/base.rb +333 -0
  37. data/lib/harvest/behavior/activatable.rb +31 -0
  38. data/lib/harvest/behavior/crud.rb +80 -0
  39. data/lib/harvest/client.rb +23 -0
  40. data/lib/harvest/company.rb +8 -0
  41. data/lib/harvest/contact.rb +20 -0
  42. data/lib/harvest/credentials.rb +34 -0
  43. data/lib/harvest/errors.rb +27 -0
  44. data/lib/harvest/expense.rb +54 -0
  45. data/lib/harvest/expense_category.rb +10 -0
  46. data/lib/harvest/hardy_client.rb +80 -0
  47. data/lib/harvest/invoice.rb +75 -0
  48. data/lib/harvest/invoice_category.rb +8 -0
  49. data/lib/harvest/invoice_message.rb +8 -0
  50. data/lib/harvest/invoice_payment.rb +8 -0
  51. data/lib/harvest/line_item.rb +21 -0
  52. data/lib/harvest/model.rb +133 -0
  53. data/lib/harvest/project.rb +41 -0
  54. data/lib/harvest/receipt.rb +12 -0
  55. data/lib/harvest/task.rb +21 -0
  56. data/lib/harvest/task_assignment.rb +27 -0
  57. data/lib/harvest/time_entry.rb +57 -0
  58. data/lib/harvest/timezones.rb +130 -0
  59. data/lib/harvest/user.rb +58 -0
  60. data/lib/harvest/user_assignment.rb +27 -0
  61. data/lib/harvest/version.rb +3 -0
  62. data/lib/harvested2.rb +96 -0
  63. data/spec/factories/client.rb +14 -0
  64. data/spec/factories/contact.rb +8 -0
  65. data/spec/factories/expense.rb +10 -0
  66. data/spec/factories/expenses_category.rb +7 -0
  67. data/spec/factories/invoice.rb +25 -0
  68. data/spec/factories/invoice_category.rb +5 -0
  69. data/spec/factories/invoice_message.rb +9 -0
  70. data/spec/factories/invoice_payment.rb +7 -0
  71. data/spec/factories/line_item.rb +9 -0
  72. data/spec/factories/project.rb +15 -0
  73. data/spec/factories/task.rb +8 -0
  74. data/spec/factories/task_assignment.rb +8 -0
  75. data/spec/factories/time_entry.rb +13 -0
  76. data/spec/factories/user.rb +19 -0
  77. data/spec/factories/user_assigment.rb +7 -0
  78. data/spec/functional/clients_spec.rb +105 -0
  79. data/spec/functional/errors_spec.rb +42 -0
  80. data/spec/functional/expenses_spec.rb +97 -0
  81. data/spec/functional/invoice_messages_spec.rb +48 -0
  82. data/spec/functional/invoice_payments_spec.rb +51 -0
  83. data/spec/functional/invoice_spec.rb +138 -0
  84. data/spec/functional/project_spec.rb +76 -0
  85. data/spec/functional/tasks_spec.rb +119 -0
  86. data/spec/functional/time_entries_spec.rb +87 -0
  87. data/spec/functional/users_spec.rb +72 -0
  88. data/spec/harvest/base_spec.rb +10 -0
  89. data/spec/harvest/basic_auth_credentials_spec.rb +12 -0
  90. data/spec/harvest/expense_category_spec.rb +5 -0
  91. data/spec/harvest/expense_spec.rb +18 -0
  92. data/spec/harvest/invoice_message_spec.rb +5 -0
  93. data/spec/harvest/invoice_payment_spec.rb +5 -0
  94. data/spec/harvest/invoice_spec.rb +5 -0
  95. data/spec/harvest/oauth_credentials_spec.rb +11 -0
  96. data/spec/harvest/project_spec.rb +5 -0
  97. data/spec/harvest/task_assignment_spec.rb +5 -0
  98. data/spec/harvest/task_spec.rb +5 -0
  99. data/spec/harvest/time_entry_spec.rb +23 -0
  100. data/spec/harvest/user_assignment_spec.rb +5 -0
  101. data/spec/harvest/user_spec.rb +34 -0
  102. data/spec/spec_helper.rb +22 -0
  103. data/spec/support/factory_bot.rb +5 -0
  104. data/spec/support/harvested_helpers.rb +28 -0
  105. data/spec/support/json_examples.rb +9 -0
  106. metadata +238 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ee945ac9e562e426b40c904e32025c47dcde6186
4
+ data.tar.gz: 9383142f811b6040b1554498ad7e5fb2215663a9
5
+ SHA512:
6
+ metadata.gz: b0e235f4e3dc3fc1bcaef473d289ccfd7b41373a3c5abce161721f1e3faf03be94d82bc98253e5110ddee1894f13e41df1e0dedf58cae4c9c9e5f799a7a2bca5
7
+ data.tar.gz: f0d85bb0e06ed404ffe2dcd4265ad0a00f26da7267bd21da1817bab503c604fb0d9864adc33aa431680a165dbb730888770f040318846f3dd675a0369e35fe16
@@ -0,0 +1,3 @@
1
+ README.md
2
+ lib/**/*.rb
3
+ MIT-LICENSE
@@ -0,0 +1,35 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ doc
21
+ .yardoc
22
+
23
+ ## PROJECT::SPECIFIC
24
+ features/support/harvest_credentials.yml
25
+ spec/support/harvest_credentials.yml
26
+ .cassettes
27
+ .rbx
28
+
29
+ ## RUBYGEMS
30
+ *.gem
31
+ Gemfile.lock
32
+ .bundle
33
+ vendor/bundle
34
+
35
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,34 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.1
3
+ DisplayCopNames: true
4
+ Exclude:
5
+ - .git/**/*
6
+ - spec/core/middleware/response/sanitize_response_spec.rb
7
+ - vendor/**/*
8
+
9
+ # Align the elements of a hash literal if they span more than one line.
10
+ Layout/AlignHash:
11
+ EnforcedLastArgumentHashStyle: ignore_implicit
12
+
13
+ # Align the parameters of a method call if they span more than one line.
14
+ Layout/AlignParameters:
15
+ EnforcedStyle: with_fixed_indentation
16
+
17
+ # Checks the indentation of hanging closing parentheses.
18
+ Layout/ClosingParenthesisIndentation:
19
+ Enabled: false
20
+
21
+ # Checks the indentation of the first parameter in a method call.
22
+ Layout/FirstParameterIndentation:
23
+ EnforcedStyle: consistent
24
+
25
+ # Checks indentation of method calls with the dot operator that span more than one line.
26
+ Layout/MultilineMethodCallIndentation:
27
+ EnforcedStyle: indented
28
+
29
+ # Checks indentation of binary operations that span more than one line.
30
+ Layout/MultilineOperationIndentation:
31
+ EnforcedStyle: indented
32
+
33
+ Metrics:
34
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.5.1
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ cache: bundler
3
+ dist: trusty
4
+ sudo: false
5
+
6
+ rvm:
7
+ - 2.2.10
8
+ - 2.3.0
9
+ - 2.4.3
10
+
11
+ script:
12
+ - bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ gem 'rubocop'
8
+ gem 'jruby-openssl', platform: [:jruby]
9
+ gem 'byebug'
10
+ gem 'pry'
11
+ gem 'pry-rails'
12
+ gem 'yard'
13
+ gem 'redcarpet'
14
+ end
15
+
16
+ group :test do
17
+ gem 'rspec'
18
+ gem 'webmock'
19
+ gem 'factory_bot'
20
+ end
@@ -0,0 +1,118 @@
1
+ ## 5.0.3 - Jun 10, 2018
2
+ * Add support for API V2
3
+ * Task/UserAssignment endpoints now are called Task/UserProjectAssignmens
4
+ * Update invoice, categories, messages and payment related actions
5
+ * Update expense actions
6
+ * Update client actions
7
+ * Update time entry actions
8
+ * Update user actions
9
+ * Update task actions
10
+ * Update line item actions
11
+ * Update account actions
12
+ * Add company actions
13
+ * Add receipt actions
14
+ * Update project, task and user assignments actions
15
+ * Remove deprecated reports endpoint
16
+
17
+ ## 4.0.0 - Apr 21, 2017
18
+ * Invoices need to be told explicitly to send line items to the server with a new attribute: `update_line_items`.
19
+ * Task/UserAssignment endpoints can now be passed query params. (Thanks Brendan Loudermilk - @bloudermilk and Nick Giancola @patbenatar)
20
+ * Expense Attachments work again. (Thanks Peter - @toothfairy)
21
+ * Company information is now included when retreiving info from `who_am_i`. (Thanks André Arko - @indirect)
22
+
23
+ ## 3.1.0 - Aug 29, 2014
24
+ * Allows Invoice Messages to be created (Thanks Thomas Balthazar - @tbalthazar)
25
+
26
+ ## 3.0.0 - Aug 29, 2014
27
+ * No longer requires Hashie v1 as a dependency
28
+ * Fixes bug where project hints were not handled properly
29
+
30
+ ## 3.0.0.rc1 - May 30, 2014
31
+ * Require Ruby 2.0+
32
+ * Allow OAuth authentication (Thanks Brendan Loudermilk - @bloudermilk)
33
+ * Allow expenses_by_project to be retrieved (Thanks Jordan Yeo - @jordanyeo)
34
+ * Reports now pass through any remaining options (Thanks Philip Arndt - @parndt)
35
+
36
+ ## 2.0.0 - April 23, 2014
37
+ * Every connection must be SSL
38
+
39
+ ## 1.2.0 - February 21, 2014
40
+ * Adds time.trackable_projects: projects that the current user can create entries for
41
+ * Show hint on error for projects.all as unprivileged user
42
+
43
+ ## 1.1.0 - December 13, 2013
44
+ * Adds ability to toggle timers (thanks Eli Fatsi - @efatsi)
45
+
46
+ ## 1.0.1 - June 21, 2013
47
+ * Adds ability to pass updated_since paramter to report methods (thanks Pete McWilliams)
48
+ * Adds ability to create time entries for a given user
49
+
50
+ ## 1.0.0 - April 26, 2013
51
+ * Same as 0.6.4 - This should have been v1.0 long ago.
52
+
53
+ ## 0.6.4 - October 24, 2012
54
+ * Removes yard and redcarpet dependencies (added on accident)
55
+
56
+ ## 0.6.3 - October 24, 2012
57
+ * Adds task activation (Thanks Mark Rickert - @markrickert)
58
+ * Adds basic invoice support (Thanks Jeffrey Lee - @jlee42)
59
+ * Adds basic invoice payment support (Thanks Adam Doeler - @releod)
60
+
61
+ ## 0.6.2 - August 25, 2012
62
+ * Fixes Mash constructor errors
63
+
64
+ ## 0.6.1 - August 22, 2012
65
+ * Adds options to "all" finder (thanks Mikel Lindsaar)
66
+ * Adds Unauthorized error type (thanks @bcobb)
67
+
68
+ ## 0.6.0 - August 22, 2012
69
+ * Replaces Dash with Mash
70
+
71
+ ## 0.5.3 - August 21, 2012
72
+ * Adds new fields has_timesheet_2012_beta and timesheet_2012_beta_control_group to Users (thanks Aldric Giacomoni)
73
+
74
+ ## 0.5.2 - August 17, 2012
75
+ * Adds new field password_change_required to Users
76
+
77
+ ## 0.5.1 - June 27, 2012
78
+ * Updates README and harvested_credentials.example.yml with warnings about normal accounts
79
+
80
+ ## 0.5.0 - June 18, 2012
81
+ * Bugfixes on User: https://github.com/zmoazeni/harvested/pull/26
82
+ * Bugfixes on TimeEntry: https://github.com/zmoazeni/harvested/pull/25
83
+
84
+ ## 0.4.0 - August 4, 2011
85
+ * Large rewrite of codebase
86
+ * Rewrite of library to use JSON instead of XML
87
+ * Rewrite of tests to use rspec instead of cucumber
88
+ * Brings in VCR to help cache test responses
89
+ * Implements more reporting functionality
90
+ * Implements most of the invoice functionality. Creating/Editing/Updating is disabled due to Harvest API issue
91
+ * Consolidates various forks (thanks Chris Ritterdorf, bricooke, Michelle Moon Lee, tkwong, Steve McKinney, and others that helped but aren't in the git log!)
92
+ * Tests passing against MRI 1.8, 1.9, JRuby, and Rubinius
93
+
94
+ ## 0.3.3 - January 27, 2010
95
+ * Adds fields to TaskAssignment (Quilted)
96
+
97
+ ## 0.3.2 - January 27, 2010
98
+ * Adds of_user support to Time Entry (Benjamin Wong - tkwong)
99
+
100
+ ## 0.3.1 - October 14, 2010
101
+ * Updates docs removing :ssl => false since Harvest released SSL to everyone
102
+ * Adds department to the User model (Steve McKinney - )
103
+
104
+ ## 0.3.0 - April 11, 2010
105
+ * Adds users
106
+ * Adds clients
107
+ * Adds contacts
108
+ * Adds expense categories
109
+ * Adds expenses
110
+ * Adds projects
111
+ * Adds tasks
112
+ * Adds task assignments
113
+ * Adds user assignments
114
+ * Adds time tracking
115
+ * Adds reporting
116
+ * Adds account information
117
+ * Adds common errors
118
+ * Adds Harvest#hardy_client
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 MagmaLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,66 @@
1
+ # Harvested: A Ruby Harvest API V2
2
+ [![Build Status](https://travis-ci.org/magma-labs/harvested2.svg?branch=master)](https://travis-ci.org/magma-labs/harvested2)
3
+
4
+ This is a Ruby wrapper for the [Harvest API V2](https://help.getharvest.com/api-v2)
5
+
6
+ ## Installation
7
+
8
+ gem install harvested2
9
+
10
+ ## Requirements
11
+ - Personal Access Token or OAuth2 application credentials
12
+
13
+ You can get them at https://id.getharvest.com/developers
14
+
15
+ ## Examples
16
+
17
+ ```ruby
18
+ harvest = Harvest.client(access_token: 'token', account_id: '123')
19
+ harvest.projects.all # list out projects
20
+
21
+ client = Harvest::Client.new(name: "Billable Company LTD.")
22
+ client = harvest.clients.create(client)
23
+ harvest.clients.find(client.id) # returns a Harvest::Client
24
+ ```
25
+
26
+ You can also pass query options in as the last parameter on any object's `all` finder
27
+ method, for example to find all the projects for client ID 12345:
28
+
29
+ ```ruby
30
+ harvest = Harvest.client(access_token: 'token', account_id: '123')
31
+ harvest.projects.all(nil, client: 12345)
32
+ ```
33
+
34
+ Note: the first parameter is a User ID field that is optional, but needs to be specified
35
+ as nil if not included.
36
+
37
+ You can pass in any hash of query attributes you wish as per the
38
+ [Harvest API V2](https://help.getharvest.com/api-v2) page.
39
+
40
+ You can find more examples at [Harvested Examples](https://github.com/harvesthq/harvest_api_samples/tree/master/v2)
41
+
42
+ ## Permissions
43
+
44
+ For most operations you need to be an Admin on the Harvest account. You can do a few select things as a normal user or a project manager, but you will likely get errors.
45
+
46
+ ## Hardy Client
47
+
48
+ The team at Harvest built a great API, but there are always dangers in writing code that depends on an API. For example: HTTP Timeouts, Occasional Bad Gateways, and Rate Limiting issues need to be accounted for.
49
+
50
+ Using `Harvested#client` your code needs to handle all these situations. However you can also use `Harvested#hardy_client` which will retry errors and wait for Rate Limit resets.
51
+
52
+ ```ruby
53
+ harvest = Harvest.hardy_client(access_token: 'token', account_id: '123')
54
+ harvest.projects.all # This will wait for the Rate Limit reset if you have gone over your limit
55
+ ```
56
+
57
+ ## Ruby support
58
+
59
+ Harvested's tests currently support Ruby version 2.1+
60
+
61
+ ## Links
62
+
63
+ * [Harvested Documentation](http://rdoc.info/projects/zmoazeni/harvested)
64
+ * [Harvest API Documentation](https://help.getharvest.com/api-v2/)
65
+ * [Source Code for Harvested](http://github.com/zmoazeni/harvested)
66
+
@@ -0,0 +1,24 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => %w(spec)
9
+
10
+ begin
11
+ require 'yard'
12
+ YARD::Rake::YardocTask.new
13
+ rescue LoadError
14
+ task :yardoc do
15
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
16
+ end
17
+ end
18
+
19
+ desc 'Removes all data on harvest'
20
+ task 'clean_remote' do
21
+ require 'harvested2'
22
+ require File.expand_path('../spec/support/harvested_helpers', __FILE__)
23
+ HarvestedHelpers.clean_remote
24
+ end
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'harvest/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.platform = Gem::Platform::RUBY
8
+ s.name = 'harvested2'
9
+ s.version = Harvest::VERSION
10
+ s.summary = 'A Ruby Wrapper for the Harvest API http://www.getharvest.com/ V2'
11
+ s.description = 'Harvested wraps the Harvest API concisely without the use of Rails dependencies. More information about the Harvest API can be found on their website (http://www.getharvest.com/api). For support hit up the Mailing List (http://groups.google.com/group/harvested)'
12
+
13
+ s.authors = ['Zach Moazeni', 'Jonathan Tapia']
14
+ s.email = ['zach.moazeni@gmail.com', 'jonathan.tapia@magmalabs.io']
15
+ s.homepage = 'http://github.com/jtapia/harvested2'
16
+ s.license = 'MIT'
17
+
18
+ s.require_path = 'lib'
19
+ s.requirements << 'none'
20
+ s.files = `git ls-files -z`.split("\x0")
21
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
23
+
24
+ s.required_ruby_version = '>= 2.2'
25
+ s.required_rubygems_version = '>= 1.3.6'
26
+
27
+ s.add_runtime_dependency('httparty')
28
+ s.add_runtime_dependency('hashie')
29
+ s.add_runtime_dependency('json')
30
+ end
@@ -0,0 +1,52 @@
1
+ # Shamelessly ripped from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/array/wrap.rb
2
+
3
+ unless Array.respond_to?(:wrap)
4
+ class Array
5
+ # Wraps its argument in an array unless it is already an array (or array-like).
6
+ #
7
+ # Specifically:
8
+ #
9
+ # * If the argument is +nil+ an empty list is returned.
10
+ # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
11
+ # * Otherwise, returns an array with the argument as its single element.
12
+ #
13
+ # Array.wrap(nil) # => []
14
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
15
+ # Array.wrap(0) # => [0]
16
+ #
17
+ # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
18
+ #
19
+ # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
20
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Arraw.wrap</tt> returns
21
+ # such a +nil+ right away.
22
+ # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
23
+ # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
24
+ # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
25
+ #
26
+ # The last point is particularly worth comparing for some enumerables:
27
+ #
28
+ # Array(:foo => :bar) # => [[:foo, :bar]]
29
+ # Array.wrap(:foo => :bar) # => [{:foo => :bar}]
30
+ #
31
+ # Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
32
+ # Array.wrap("foo\nbar") # => ["foo\nbar"]
33
+ #
34
+ # There's also a related idiom that uses the splat operator:
35
+ #
36
+ # [*object]
37
+ #
38
+ # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise.
39
+ #
40
+ # Thus, in this case the behavior is different for +nil+, and the differences with
41
+ # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
42
+ def self.wrap(object)
43
+ if object.nil?
44
+ []
45
+ elsif object.respond_to?(:to_ary)
46
+ object.to_ary
47
+ else
48
+ [object]
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ # Shamelessly ripped from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/date/conversions.rb
2
+
3
+ unless ::Date.respond_to?(:to_time)
4
+ class ::Date
5
+ def to_time(*)
6
+ ::Time.utc(year, month, day)
7
+ end
8
+ end
9
+ end