freshdesk_apiclient 0.1.3 → 0.1.4
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 +4 -4
- data/.codeclimate.yml +3 -1
- data/.rubocop.yml +1 -1
- data/.travis.yml +1 -1
- data/README.md +58 -5
- data/lib/core_extensions/object/class_name.rb +16 -0
- data/lib/freshdesk_apiclient/rest/client.rb +38 -17
- data/lib/freshdesk_apiclient/rest/resources.rb +27 -16
- data/lib/freshdesk_apiclient/rest/tickets.rb +2 -1
- data/lib/freshdesk_apiclient/utils/camelizable.rb +5 -1
- data/lib/freshdesk_apiclient/version.rb +1 -1
- data/lib/freshdesk_apiclient.rb +9 -0
- data/spec/core_extensions/object/class_name_spec.rb +32 -0
- data/spec/freshdesk_apiclient_spec.rb +3 -0
- data/spec/rest/client_spec.rb +1 -0
- data/spec/rest/resources_spec.rb +40 -26
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6429194a2b6efcbe4c6cad46d080fd2b16679a01
|
4
|
+
data.tar.gz: 948d6153138e7c8f1b2e887eae23e713de6c15a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aac732b4c3e702350e3afecbc2b1227212857750b967115a86cda6e72bf00155e4efe4daea82d21ff14407363e55225d7591b3f11643346a9c2226a6106497cc
|
7
|
+
data.tar.gz: 97e3e57d0922e6afe2c007eadd7040c4534be4f1c2dfdc386bd32f55fccb4dcd0ec858bde172a745b6ce0d8bb952a0b6982ca40734d8986e8e68f11502b233d7
|
data/.codeclimate.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -143,7 +143,7 @@ Style/StringLiteralsInInterpolation:
|
|
143
143
|
Metrics/AbcSize:
|
144
144
|
Description: A calculated magnitude based on number of assignments, branches, and
|
145
145
|
conditions.
|
146
|
-
Enabled:
|
146
|
+
Enabled: true
|
147
147
|
Max: 15
|
148
148
|
Metrics/BlockLength:
|
149
149
|
ExcludedMethods: ['describe', 'context', 'shared_examples']
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
[](https://gemnasium.com/github.com/qbantek/freshdesk_apiclient)
|
9
9
|
[](http://freshdesk_apiclient.mit-license.org)
|
10
10
|
|
11
|
-
A ruby client for [freshdesk
|
11
|
+
A ruby client for [freshdesk](https://developer.freshdesk.com/api/) API.
|
12
12
|
|
13
13
|
## Installation
|
14
14
|
|
@@ -25,20 +25,73 @@ And then execute:
|
|
25
25
|
Or install it yourself as:
|
26
26
|
|
27
27
|
$ gem install freshdesk_apiclient
|
28
|
+
|
29
|
+
#### Setup your authentication credentials
|
30
|
+
|
31
|
+
You'll need to create your account and get the credentials at [freshdesk](https://freshdesk.com/).
|
32
|
+
See [Authentication](https://developers.freshdesk.com/api/#authentication) for more information.
|
33
|
+
|
34
|
+
Username and password:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
# config/initializers/freshdesk_apiclient.rb
|
38
|
+
FreshdeskApiclient.username_or_api_key = ENV["FRESHDESK_USERNAME"]
|
39
|
+
FreshdeskApiclient.password = ENV["FRESHDESK_PASWWORD"]
|
40
|
+
```
|
41
|
+
|
42
|
+
Or API key:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
# config/initializers/freshdesk_apiclient.rb
|
46
|
+
FreshdeskApiclient.username_or_api_key = ENV["FRESHDESK_API_KEY"]
|
47
|
+
```
|
48
|
+
(If you use the API key, there is no need for a password.)
|
49
|
+
|
50
|
+
#### Other configuration
|
51
|
+
|
52
|
+
You might want to set the Logger to be used by the gem.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
# config/initializers/freshdesk_apiclient.rb
|
56
|
+
FreshdeskApiclient.logger = Rails.logger
|
57
|
+
```
|
28
58
|
|
29
59
|
## Usage
|
30
60
|
|
31
|
-
|
61
|
+
Currently, only the following requests are supported:
|
62
|
+
|
63
|
+
#### Tickets
|
64
|
+
|
65
|
+
- Create a ticket
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
client = FreshdeskApiclient::Client.new
|
69
|
+
client.tickets.create payload # payload is a hash,
|
70
|
+
```
|
71
|
+
See [Create a ticket](https://developers.freshdesk.com/api/#create_ticket) for allowed attributes on the payload.
|
72
|
+
|
73
|
+
- List all tickets
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
client = FreshdeskApiclient::Client.new
|
77
|
+
client.tickets.list
|
78
|
+
```
|
32
79
|
|
33
80
|
## Development
|
34
81
|
|
35
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
82
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec spec` to run the tests.
|
83
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
36
84
|
|
37
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
85
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
86
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
87
|
+
which will create a git tag for the version, push git commits and tags,
|
88
|
+
and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
38
89
|
|
39
90
|
## Contributing
|
40
91
|
|
41
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/qbantek/freshdesk_apiclient.
|
92
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/qbantek/freshdesk_apiclient.
|
93
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere
|
94
|
+
to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
42
95
|
|
43
96
|
|
44
97
|
## License
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module ObjectExtensions
|
3
|
+
refine Object do
|
4
|
+
def class_name
|
5
|
+
full_class_name_as_array.last
|
6
|
+
end
|
7
|
+
|
8
|
+
def full_class_name_as_array
|
9
|
+
full_class_name.split('::')
|
10
|
+
end
|
11
|
+
|
12
|
+
def full_class_name
|
13
|
+
self.class.name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require_relative '../../../lib/freshdesk_apiclient'
|
3
|
+
|
2
4
|
module FreshdeskApiclient
|
3
5
|
module REST
|
4
6
|
class Client
|
@@ -13,8 +15,7 @@ module FreshdeskApiclient
|
|
13
15
|
# @param [Logger] logger
|
14
16
|
def initialize(domain: FreshdeskApiclient.domain,
|
15
17
|
username_or_api_key: FreshdeskApiclient.username_or_api_key,
|
16
|
-
password: FreshdeskApiclient.password,
|
17
|
-
logger: nil)
|
18
|
+
password: FreshdeskApiclient.password, logger: FreshdeskApiclient.logger)
|
18
19
|
@base_url = "https://#{domain}.freshdesk.com/api/v2/"
|
19
20
|
@credentials = {username: username_or_api_key, password: password}
|
20
21
|
@logger = logger
|
@@ -22,21 +23,41 @@ module FreshdeskApiclient
|
|
22
23
|
|
23
24
|
# obj.method_missing(symbol [, *args] ) -> result
|
24
25
|
def method_missing(symbol, *arguments, &block)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
RESOURCES.include?(symbol) ? instance_variable(symbol) : super
|
27
|
+
end
|
28
|
+
|
29
|
+
def respond_to_missing?(method, *)
|
30
|
+
RESOURCES.include?(method) ? true : super
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def instance_variable(symbol)
|
36
|
+
class_name = camelize symbol
|
37
|
+
get_set_ivar class_name, as_ivar(class_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_set_ivar(class_name, ivar)
|
41
|
+
instance_variable_defined?(ivar) ? instance_variable_get(ivar) : set(ivar, class_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def set(ivar, class_name)
|
45
|
+
obj = instantiate class_name
|
46
|
+
instance_variable_set ivar, obj
|
47
|
+
end
|
48
|
+
|
49
|
+
def as_ivar(name)
|
50
|
+
"@#{name.downcase}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def instantiate(class_name)
|
54
|
+
klass(class_name, 'FreshdeskApiclient', 'REST').new(@base_url, credentials: @credentials, logger: logger)
|
55
|
+
end
|
56
|
+
|
57
|
+
def klass(class_name, *module_names)
|
58
|
+
c = Object
|
59
|
+
module_names.each {|m| c = c.const_get m }
|
60
|
+
c.const_get class_name
|
40
61
|
end
|
41
62
|
end
|
42
63
|
end
|
@@ -1,44 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'rest-client'
|
3
3
|
require 'forwardable'
|
4
|
-
|
4
|
+
require_relative '../../../lib/core_extensions/object/class_name'
|
5
5
|
|
6
6
|
module FreshdeskApiclient
|
7
7
|
module REST
|
8
8
|
class Resources
|
9
|
+
using ObjectExtensions
|
10
|
+
|
9
11
|
def initialize(base_url, options={})
|
10
|
-
@
|
11
|
-
@headers = headers options[:credentials]
|
12
|
+
@args = default_arguments options[:credentials], base_url, options[:path]
|
12
13
|
RestClient.log = options[:logger]
|
13
14
|
end
|
14
15
|
|
15
16
|
def list
|
16
|
-
execute(method: :get, headers:
|
17
|
+
execute(method: :get, headers: headers)
|
17
18
|
end
|
18
19
|
|
19
20
|
def create(json_payload)
|
20
|
-
execute(method: :post, headers:
|
21
|
+
execute(method: :post, headers: content_headers, payload: json_payload)
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
+
private
|
24
25
|
|
25
|
-
def
|
26
|
-
|
26
|
+
def resource
|
27
|
+
class_name.downcase
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
def execute(options)
|
32
|
-
RestClient::Request.execute @options.merge(options)
|
30
|
+
def execute(args)
|
31
|
+
RestClient::Request.execute @args.merge(args)
|
33
32
|
end
|
34
33
|
|
35
|
-
def
|
34
|
+
def default_arguments(credentials, base_url, path=nil)
|
36
35
|
{
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
user: credentials[:username],
|
37
|
+
password: credentials[:password],
|
38
|
+
url: full_url(base_url, path)
|
40
39
|
}
|
41
40
|
end
|
41
|
+
|
42
|
+
def full_url(base_url, path)
|
43
|
+
"#{base_url}/#{path || resource}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def content_headers
|
47
|
+
headers.merge('Content-Type': 'application/json')
|
48
|
+
end
|
49
|
+
|
50
|
+
def headers
|
51
|
+
{Accept: 'application/json'}
|
52
|
+
end
|
42
53
|
end
|
43
54
|
end
|
44
55
|
end
|
@@ -4,8 +4,12 @@ module FreshdeskApiclient
|
|
4
4
|
module Camelizable
|
5
5
|
def camelize(term)
|
6
6
|
string = term.to_s
|
7
|
+
format string
|
8
|
+
end
|
9
|
+
|
10
|
+
def format(string)
|
7
11
|
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
8
|
-
string.gsub!(%r{(?:_|(/))([a-z\d]*)}) { $2.capitalize
|
12
|
+
string.gsub!(%r{(?:_|(/))([a-z\d]*)}) { $2.capitalize }
|
9
13
|
string
|
10
14
|
end
|
11
15
|
end
|
data/lib/freshdesk_apiclient.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'core_extensions/object/class_name'
|
2
3
|
require 'freshdesk_apiclient/version'
|
3
4
|
|
4
5
|
require 'freshdesk_apiclient/utils/loggeable'
|
@@ -32,4 +33,12 @@ module FreshdeskApiclient
|
|
32
33
|
def self.password=(password)
|
33
34
|
@password = password
|
34
35
|
end
|
36
|
+
|
37
|
+
def self.logger
|
38
|
+
@logger ||= nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.logger=(logger)
|
42
|
+
@logger = logger
|
43
|
+
end
|
35
44
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative '../../../lib/core_extensions/object/class_name'
|
3
|
+
RSpec.describe ObjectExtensions do
|
4
|
+
module Foo
|
5
|
+
class Bar
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'when refining Object' do
|
10
|
+
using ObjectExtensions
|
11
|
+
|
12
|
+
context 'for any Foo:Bar instance' do
|
13
|
+
subject { Foo::Bar.new }
|
14
|
+
describe '#full_class_name' do
|
15
|
+
it { expect(subject.full_class_name).to eq('Foo::Bar') }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#full_class_name_as_array' do
|
19
|
+
it('should return an Array of 2 items') do
|
20
|
+
expect(subject.full_class_name_as_array).to be_a(Array)
|
21
|
+
expect(subject.full_class_name_as_array.size).to eq(2)
|
22
|
+
end
|
23
|
+
it('first array item should eq Foo') { expect(subject.full_class_name_as_array[0]).to eq('Foo') }
|
24
|
+
it('second array item should eq Bar') { expect(subject.full_class_name_as_array[0]).to eq('Foo') }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#class_name' do
|
28
|
+
it { expect(subject.class_name).to eq('Bar') }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -17,4 +17,7 @@ RSpec.describe FreshdeskApiclient do
|
|
17
17
|
before { FreshdeskApiclient.password = nil }
|
18
18
|
it('has a default password') { expect(FreshdeskApiclient.password).to eq('X') }
|
19
19
|
end
|
20
|
+
|
21
|
+
before { FreshdeskApiclient.logger = :l }
|
22
|
+
it('allows to set logger') { expect(FreshdeskApiclient.logger).to eq(:l) }
|
20
23
|
end
|
data/spec/rest/client_spec.rb
CHANGED
data/spec/rest/resources_spec.rb
CHANGED
@@ -5,45 +5,36 @@ RSpec.describe FreshdeskApiclient::REST::Resources do
|
|
5
5
|
subject { FreshdeskApiclient::REST::Resources.new(:url, credentials: {username: :u, password: :p}) }
|
6
6
|
|
7
7
|
RSpec.shared_examples 'a resource' do
|
8
|
-
let(:get_headers) { {
|
8
|
+
let(:get_headers) { {Accept: 'application/json'} }
|
9
9
|
let(:post_headers) { get_headers.merge('Content-Type': 'application/json') }
|
10
10
|
let(:resource) { subject.class.name.split('::').last.downcase }
|
11
11
|
|
12
12
|
describe '#new' do
|
13
|
+
it 'sets the user using given credentials' do
|
14
|
+
expect(subject.instance_variable_get(:@args)[:user]).to eql(:u)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets the password using given credentials' do
|
18
|
+
expect(subject.instance_variable_get(:@args)[:password]).to eql(:p)
|
19
|
+
end
|
20
|
+
|
13
21
|
context 'when path option is provided' do
|
14
22
|
subject { FreshdeskApiclient::REST::Resources.new(:url, credentials: {username: :u, password: :p}, path: :foo) }
|
15
23
|
it 'sets the url using given path' do
|
16
|
-
expect(subject.instance_variable_get(:@
|
24
|
+
expect(subject.instance_variable_get(:@args)[:url]).to eql("#{:url}/#{:foo}")
|
17
25
|
end
|
18
26
|
end
|
19
27
|
|
20
28
|
context 'when path option is not provided' do
|
21
29
|
it 'sets the url for the given resource' do
|
22
|
-
expect(subject.instance_variable_get(:@
|
30
|
+
expect(subject.instance_variable_get(:@args)[:url]).to eql("#{:url}/#{resource}")
|
23
31
|
end
|
24
32
|
end
|
25
33
|
|
26
|
-
it 'sets the Authorization header for the given credentials' do
|
27
|
-
expect(subject.instance_variable_get(:@headers)[:Authorization]).to eql(get_headers[:Authorization])
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'sets the Accept header to accept JSON' do
|
31
|
-
expect(subject.instance_variable_get(:@headers)[:Accept]).to eql(get_headers[:Accept])
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'sets the Content-Type header to indicate JSON content' do
|
35
|
-
expect(subject.instance_variable_get(:@headers)[:'Content-Type']).to eql(post_headers[:'Content-Type'])
|
36
|
-
end
|
37
|
-
|
38
34
|
it('sets the logger on RestClient') do
|
39
35
|
rest_client = object_double('RestClient', :log= => nil).as_stubbed_const
|
40
36
|
logger = Logger.new(STDOUT)
|
41
|
-
FreshdeskApiclient::REST::Resources.new(:url,
|
42
|
-
credentials: {
|
43
|
-
username: :u,
|
44
|
-
password: :p
|
45
|
-
},
|
46
|
-
logger: logger)
|
37
|
+
FreshdeskApiclient::REST::Resources.new(:url, credentials: {username: :u, password: :p}, logger: logger)
|
47
38
|
expect(rest_client).to have_received(:log=).with(logger)
|
48
39
|
end
|
49
40
|
end
|
@@ -52,7 +43,14 @@ RSpec.describe FreshdeskApiclient::REST::Resources do
|
|
52
43
|
it('executes the request as a GET') do
|
53
44
|
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
54
45
|
subject.list
|
55
|
-
expect(request).to have_received(:execute).with(method: :get
|
46
|
+
expect(request).to have_received(:execute).with(hash_including(method: :get))
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'sets the Accept header to accept JSON' do
|
50
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
51
|
+
subject.list
|
52
|
+
expect(get_headers[:Accept]).to eq('application/json')
|
53
|
+
expect(request).to have_received(:execute).with(hash_including(headers: get_headers))
|
56
54
|
end
|
57
55
|
end
|
58
56
|
|
@@ -60,10 +58,26 @@ RSpec.describe FreshdeskApiclient::REST::Resources do
|
|
60
58
|
it('executes the request as a POST') do
|
61
59
|
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
62
60
|
subject.create :payload
|
63
|
-
expect(request).to have_received(:execute).with(method: :post
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
expect(request).to have_received(:execute).with(hash_including(method: :post))
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'sets the Accept header to accept JSON' do
|
65
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
66
|
+
subject.create :payload
|
67
|
+
expect(request).to have_received(:execute).with(hash_including(headers: post_headers))
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'sets the Content-Type header to indicate JSON content' do
|
71
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
72
|
+
subject.create :payload
|
73
|
+
expect(post_headers[:'Content-Type']).to eq('application/json')
|
74
|
+
expect(request).to have_received(:execute).with(hash_including(headers: post_headers))
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'submits the payload' do
|
78
|
+
request = object_double('RestClient::Request', execute: nil).as_stubbed_const
|
79
|
+
subject.create :payload
|
80
|
+
expect(request).to have_received(:execute).with(hash_including(payload: :payload))
|
67
81
|
end
|
68
82
|
end
|
69
83
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: freshdesk_apiclient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erich Quintero
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -194,6 +194,7 @@ files:
|
|
194
194
|
- bin/console
|
195
195
|
- bin/setup
|
196
196
|
- freshdesk_apiclient.gemspec
|
197
|
+
- lib/core_extensions/object/class_name.rb
|
197
198
|
- lib/freshdesk_apiclient.rb
|
198
199
|
- lib/freshdesk_apiclient/rest/client.rb
|
199
200
|
- lib/freshdesk_apiclient/rest/resources.rb
|
@@ -202,6 +203,7 @@ files:
|
|
202
203
|
- lib/freshdesk_apiclient/utils/loggeable.rb
|
203
204
|
- lib/freshdesk_apiclient/version.rb
|
204
205
|
- lib/tasks/releaser.rake
|
206
|
+
- spec/core_extensions/object/class_name_spec.rb
|
205
207
|
- spec/freshdesk_apiclient_spec.rb
|
206
208
|
- spec/rest/client_spec.rb
|
207
209
|
- spec/rest/resources_spec.rb
|
@@ -237,3 +239,4 @@ test_files:
|
|
237
239
|
- spec/rest/resources_spec.rb
|
238
240
|
- spec/freshdesk_apiclient_spec.rb
|
239
241
|
- spec/spec_helper.rb
|
242
|
+
- spec/core_extensions/object/class_name_spec.rb
|