Skip to content

Commit

Permalink
make util methods private
Browse files Browse the repository at this point in the history
Updated specs to test the private methods directly, which is typically
considered a smell. In this case we're leaving the specs to test the
implementation of these methods directly as there is still value in
having their logic be covered explicitly. Might come back to rework
the util methods if time permits (e.g extract to a dedicated module
perhaps).
  • Loading branch information
zokioki committed Dec 29, 2023
1 parent 8f65c59 commit d5d2080
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ UNRELEASED
-----
- BREAKING: Upgrade `oauth2` dependency to v2.0
- BREAKING: Minimum required Ruby version 2.7.0
- BREAKING: Make utility methods private (e.g. `format_date`)
- Fix response parsing error for `revoke_token!`

0.17.1
Expand Down
2 changes: 2 additions & 0 deletions lib/fitbit_api/helpers/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module FitbitAPI
class Client
PERIODS = %w[1d 7d 30d 1w 1m 3m 6m 1y max].freeze

private

def format_date(date)
if [Date, Time, DateTime].include?(date.class)
date.strftime('%Y-%m-%d')
Expand Down
61 changes: 33 additions & 28 deletions spec/helpers/utils_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
date_time = DateTime.parse('21-09-1991')

[date, time, date_time].each do |obj|
expect(client.format_date(obj)).to eq('1991-09-21')
expect(client.send(:format_date, obj)).to eq('1991-09-21')
end
end

it 'verifies string input to be of yyyy-MM-dd format' do
string = '91-9-21'
expect { client.format_date string }.to raise_error(FitbitAPI::InvalidArgumentError)
expect { client.send(:format_date, string) }.to raise_error(FitbitAPI::InvalidArgumentError)
end

it 'returns unaltered argument if argument is properly formatted' do
string = '1991-09-21'
expect(client.format_date(string)).to eq(string)
expect(client.send(:format_date, string)).to eq(string)
end
end

Expand All @@ -35,130 +35,135 @@
date_time = DateTime.parse('12:45')

[time, date_time].each do |obj|
expect(client.format_time(obj)).to eq('12:45')
expect(client.send(:format_time, obj)).to eq('12:45')
end
end

it 'verifies string input to be of HH:mm format' do
string = '2:45'
expect { client.format_time string }.to raise_error(FitbitAPI::InvalidArgumentError)
expect { client.send(:format_time, string) }.to raise_error(FitbitAPI::InvalidArgumentError)
end

it 'returns unaltered argument if argument is properly formatted' do
string = '12:45'
expect(client.format_time(string)).to eq(string)
expect(client.send(:format_time, string)).to eq(string)
end
end

describe '#format_scope' do
it 'returns elements of an Array as single space delimited string' do
scope = %w[one two three]
expect(client.format_scope(scope)).to eq('one two three')
expect(client.send(:format_scope, scope)).to eq('one two three')
end

it 'returns unaltered argument if argument is not an Array' do
scope = 'one two three'
expect(client.format_scope(scope)).to eq(scope)
expect(client.send(:format_scope, scope)).to eq(scope)
end
end

describe '#strip_root_key' do
it 'returns the original argument if not a Hash' do
object = %w[foo bar baz]
expect(client.strip_root_key(object)).to eq(object)
expect(client.send(:strip_root_key, object)).to eq(object)
end

it 'returns the original argument if it is a Hash with multiple root-level keys' do
object = { foo: 1, bar: [2, 3, 4], baz: { biz: 5 } }
expect(client.strip_root_key(object)).to eq(object)
expect(client.send(:strip_root_key, object)).to eq(object)
end

it 'returns the object without the root key' do
object = { data: { foo: 1, bar: 2, baz: 3 } }
expect(client.strip_root_key(object)).to eq(object[:data])
expect(client.send(:strip_root_key, object)).to eq(object[:data])
end
end

describe '#deep_keys_to_snake_case!' do
it 'converts keys of hash to snake case format' do
object = { 'keyOne' => 1, 'keyTwo' => 2, 'keyThree' => 3 }
expect(client.deep_keys_to_snake_case!(object)).to eq({ 'key_one' => 1, 'key_two' => 2, 'key_three' => 3 })
expect(client.send(:deep_keys_to_snake_case!, object)).to eq(
{ 'key_one' => 1, 'key_two' => 2, 'key_three' => 3 }
)
end

it 'converts nested keys of hash to snake case format' do
object = { 'keyOne' => 1, 'keyTwo' => { 'keyThree' => 3, 'keyFour' => 4 } }
expect(client.deep_keys_to_snake_case!(object)).to eq({ 'key_one' => 1,
'key_two' => { 'key_three' => 3, 'key_four' => 4 } })
expect(client.send(:deep_keys_to_snake_case!, object)).to eq(
{ 'key_one' => 1, 'key_two' => { 'key_three' => 3, 'key_four' => 4 } }
)
end
end

describe '#deep_keys_to_camel_case!' do
it 'converts keys of hash to camel case format' do
object = { 'key_one' => 1, 'key_two' => 2, 'key_three' => 3 }
expect(client.deep_keys_to_camel_case!(object)).to eq({ 'keyOne' => 1, 'keyTwo' => 2, 'keyThree' => 3 })
expect(client.send(:deep_keys_to_camel_case!, object)).to eq({ 'keyOne' => 1, 'keyTwo' => 2, 'keyThree' => 3 })
end

it 'converts nested keys of hash to camel case format' do
object = { 'key_one' => 1, 'key_two' => { 'key_three' => 3, 'key_four' => 4 } }
expect(client.deep_keys_to_camel_case!(object)).to eq({ 'keyOne' => 1,
'keyTwo' => { 'keyThree' => 3, 'keyFour' => 4 } })
expect(client.send(:deep_keys_to_camel_case!, object)).to eq(
{ 'keyOne' => 1, 'keyTwo' => { 'keyThree' => 3, 'keyFour' => 4 } }
)
end

it 'handles mixed input of camel cased and snake cased keys' do
object = { 'key_one' => 1, 'keyTwo' => { 'key_three' => 3, keyFour: 4 } }
expect(client.deep_keys_to_camel_case!(object)).to eq({ 'keyOne' => 1,
'keyTwo' => { 'keyThree' => 3, 'keyFour' => 4 } })
expect(client.send(:deep_keys_to_camel_case!, object)).to eq(
{ 'keyOne' => 1, 'keyTwo' => { 'keyThree' => 3, 'keyFour' => 4 } }
)
end
end

describe '#deep_symbolize_keys!' do
it 'converts keys of hash to symbol' do
object = { 'keyOne' => 1, 'keyTwo' => 2, 'keyThree' => 3 }
expect(client.deep_symbolize_keys!(object)).to eq({ keyOne: 1, keyTwo: 2, keyThree: 3 })
expect(client.send(:deep_symbolize_keys!, object)).to eq({ keyOne: 1, keyTwo: 2, keyThree: 3 })
end

it 'converts nested keys of hash to symbol' do
object = { 'keyOne' => 1, 'keyTwo' => { 'keyThree' => 3, 'keyFour' => 4 } }
expect(client.deep_symbolize_keys!(object)).to eq({ keyOne: 1, keyTwo: { keyThree: 3, keyFour: 4 } })
expect(client.send(:deep_symbolize_keys!, object)).to eq({ keyOne: 1, keyTwo: { keyThree: 3, keyFour: 4 } })
end
end

describe '#to_snake_case' do
it 'converts camelCased words to snake_case format' do
word = 'imMrMeeseeksLookAtMe'
expect(client.to_snake_case(word)).to eq 'im_mr_meeseeks_look_at_me'
expect(client.send(:to_snake_case, word)).to eq 'im_mr_meeseeks_look_at_me'
end

it 'properly recognizes series of capital letters as single word' do
word = 'iThinkNASAIsCool'
expect(client.to_snake_case(word)).to eq 'i_think_nasa_is_cool'
expect(client.send(:to_snake_case, word)).to eq 'i_think_nasa_is_cool'
end

it 'processes dashes to underscore if :replace_dashes option is provided' do
word = 'some-dashesAndSnakes'
expect(client.to_snake_case(word, replace_dashes: true)).to eq 'some_dashes_and_snakes'
expect(client.send(:to_snake_case, word, replace_dashes: true)).to eq 'some_dashes_and_snakes'
end
end

describe '#to_camel_case' do
it 'returns original string if already camelCased' do
word = 'AlreadyCamel'
expect(client.to_camel_case(word)).to eq 'AlreadyCamel'
expect(client.send(:to_camel_case, word)).to eq 'AlreadyCamel'
end

it 'returns original string if already lowerCamelCased' do
word = 'alreadyLowerCamel'
expect(client.to_camel_case(word, lower: true)).to eq 'alreadyLowerCamel'
expect(client.send(:to_camel_case, word, lower: true)).to eq 'alreadyLowerCamel'
end

it 'converts snake_cased words to CamelCase format' do
word = 'im_mr_meeseeks_look_at_me'
expect(client.to_camel_case(word)).to eq 'ImMrMeeseeksLookAtMe'
expect(client.send(:to_camel_case, word)).to eq 'ImMrMeeseeksLookAtMe'
end

it 'converts snake_cased words to lowerCamelCase format' do
word = 'lower_camel'
expect(client.to_camel_case(word, lower: true)).to eq 'lowerCamel'
expect(client.send(:to_camel_case, word, lower: true)).to eq 'lowerCamel'
end
end
end

0 comments on commit d5d2080

Please sign in to comment.