diff --git a/.rspec b/.rspec index 8c18f1a..7a2cc1a 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,3 @@ +--require spec_helper --format documentation --color diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..5ef7521 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,242 @@ +Naming/HeredocDelimiterNaming: + Enabled: false + +Style/MultipleComparison: + Enabled: false + +Style/PercentLiteralDelimiters: + Enabled: false + +# kind_of? is a good way to check a type +Style/ClassCheck: + EnforcedStyle: kind_of? + +Style/FrozenStringLiteralComment: + Enabled: false + +# This doesn't work with older versions of Ruby (pre 2.4.0) +Style/SafeNavigation: + Enabled: false + +# This doesn't work with older versions of Ruby (pre 2.4.0) +Performance/RegexpMatch: + Enabled: false + +# This suggests use of `tr` instead of `gsub`. While this might be more performant, +# these methods are not at all interchangable, and behave very differently. This can +# lead to people making the substitution without considering the differences. +Performance/StringReplacement: + Enabled: false + +# .length == 0 is also good, we don't always want .zero? +Style/NumericPredicate: + Enabled: false + +# this would cause errors with long lanes +Metrics/BlockLength: + Enabled: false + +# this is a bit buggy +Metrics/ModuleLength: + Enabled: false + +# certificate_1 is an okay variable name +Naming/VariableNumber: + Enabled: false + +# This is used a lot across the fastlane code base for config files +Style/MethodMissing: + Enabled: false + +# +# File.chmod(0777, f) +# +# is easier to read than +# +# File.chmod(0o777, f) +# +Style/NumericLiteralPrefix: + Enabled: false + +# +# command = (!clean_expired.nil? || !clean_pattern.nil?) ? CLEANUP : LIST +# +# is easier to read than +# +# command = !clean_expired.nil? || !clean_pattern.nil? ? CLEANUP : LIST +# +Style/TernaryParentheses: + Enabled: false + +# sometimes it is useful to have those empty methods +Style/EmptyMethod: + Enabled: false + +# It's better to be more explicit about the type +Style/BracesAroundHashParameters: + Enabled: false + +# specs sometimes have useless assignments, which is fine +Lint/UselessAssignment: + Exclude: + - '**/spec/**/*' + +# We could potentially enable the 2 below: +Layout/IndentHash: + Enabled: false + +Layout/AlignHash: + Enabled: false + +# HoundCI doesn't like this rule +Layout/DotPosition: + Enabled: false + +# We allow !! as it's an easy way to convert ot boolean +Style/DoubleNegation: + Enabled: false + +# Prevent to replace [] into %i +Style/SymbolArray: + Enabled: false + +# We still support Ruby 2.0.0 +Layout/IndentHeredoc: + Enabled: false + +# This cop would not work fine with rspec +Style/MixinGrouping: + Exclude: + - '**/spec/**/*' + +# Sometimes we allow a rescue block that doesn't contain code +Lint/HandleExceptions: + Enabled: false + +# Cop supports --auto-correct. +Lint/UnusedBlockArgument: + Enabled: false + +Lint/AmbiguousBlockAssociation: + Enabled: false + +# Needed for $verbose +Style/GlobalVars: + Enabled: false + +# We want to allow class Fastlane::Class +Style/ClassAndModuleChildren: + Enabled: false + +# $? Exit +Style/SpecialGlobalVars: + Enabled: false + +Metrics/AbcSize: + Enabled: false + +Metrics/MethodLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +# The %w might be confusing for new users +Style/WordArray: + MinSize: 19 + +# raise and fail are both okay +Style/SignalException: + Enabled: false + +# Better too much 'return' than one missing +Style/RedundantReturn: + Enabled: false + +# Having if in the same line might not always be good +Style/IfUnlessModifier: + Enabled: false + +# and and or is okay +Style/AndOr: + Enabled: false + +# Configuration parameters: CountComments. +Metrics/ClassLength: + Max: 320 + + +# Configuration parameters: AllowURI, URISchemes. +Metrics/LineLength: + Max: 370 + +# Configuration parameters: CountKeywordArgs. +Metrics/ParameterLists: + Max: 17 + +Metrics/PerceivedComplexity: + Max: 18 + +# Sometimes it's easier to read without guards +Style/GuardClause: + Enabled: false + +# We allow both " and ' +Style/StringLiterals: + Enabled: false + +# something = if something_else +# that's confusing +Style/ConditionalAssignment: + Enabled: false + +# Better to have too much self than missing a self +Style/RedundantSelf: + Enabled: false + +# e.g. +# def self.is_supported?(platform) +# we may never use `platform` +Lint/UnusedMethodArgument: + Enabled: false + +# the let(:key) { ... } +Lint/ParenthesesAsGroupedExpression: + Exclude: + - '**/spec/**/*' + +# This would reject is_ in front of methods +# We use `is_supported?` everywhere already +Naming/PredicateName: + Enabled: false + +# We allow the $ +Style/PerlBackrefs: + Enabled: false + +# They have not to be snake_case +Naming/FileName: + Exclude: + - '**/Gemfile' + - '**/Rakefile' + - '**/*.gemspec' + +# We're not there yet +Style/Documentation: + Enabled: false + +# Added after upgrade to 0.38.0 +Style/MutableConstant: + Enabled: false + +# length > 0 is good +Style/ZeroLengthPredicate: + Enabled: false + +# Adds complexity +Style/IfInsideElse: + Enabled: false + +# Sometimes we just want to 'collect' +Style/CollectionMethods: + Enabled: false diff --git a/.ruby-version b/.ruby-version index 2bf1c1c..8e8299d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.3.1 +2.4.2 diff --git a/.travis.yml b/.travis.yml index 078a0ce..a75751d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ language: ruby rvm: - - 2.0.0 -before_install: gem install bundler -v 1.11.2 + - 2.4.2 diff --git a/Rakefile b/Rakefile index b7e9ed5..05f4f23 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,9 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" +require 'bundler/gem_tasks' -RSpec::Core::RakeTask.new(:spec) +require 'rspec/core/rake_task' +RSpec::Core::RakeTask.new -task :default => :spec +require 'rubocop/rake_task' +RuboCop::RakeTask.new(:rubocop) + +task default: [:spec, :rubocop] diff --git a/branch_io.gemspec b/branch_io.gemspec index 952425b..3851493 100644 --- a/branch_io.gemspec +++ b/branch_io.gemspec @@ -1,4 +1,4 @@ -# coding: utf-8 + lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'branch_io/version' @@ -9,8 +9,8 @@ Gem::Specification.new do |spec| spec.authors = ["Aurélien Noce"] spec.email = ["aurelien.noce@imagine-app.fr"] - spec.summary = %q{A Client for the Branch.io deep linking public API} - spec.description = %q{This wrapper allows you to create and update deep links on branch.io, using the public REST API.} + spec.summary = 'A Client for the Branch.io deep linking public API' + spec.description = 'This wrapper allows you to create and update deep links on branch.io, using the public REST API.' spec.homepage = "https://github.com/ushu/branch_io" spec.license = "MIT" @@ -22,7 +22,11 @@ Gem::Specification.new do |spec| spec.add_dependency "httparty", "~> 0.13" spec.add_development_dependency "vcr", "~> 3.0" spec.add_development_dependency "webmock", "~> 2.1" - spec.add_development_dependency "bundler", "~> 1.11" - spec.add_development_dependency "rake", "~> 10.0" + spec.add_development_dependency "bundler" + spec.add_development_dependency "rake" spec.add_development_dependency "rspec", "~> 3.0" + spec.add_development_dependency "rspec_junit_formatter" + spec.add_development_dependency "rspec-simplecov" + spec.add_development_dependency "rubocop", "~> 0.50.0" + spec.add_development_dependency "simplecov" end diff --git a/lib/branch_io.rb b/lib/branch_io.rb index 69af183..3be766b 100644 --- a/lib/branch_io.rb +++ b/lib/branch_io.rb @@ -21,5 +21,4 @@ def self.respond_to?(name) end super end - end diff --git a/lib/branch_io/client.rb b/lib/branch_io/client.rb index 26243b3..3cd9070 100644 --- a/lib/branch_io/client.rb +++ b/lib/branch_io/client.rb @@ -5,7 +5,6 @@ require_relative "client/links" module BranchIO - class Client class ErrorMissingBranchKey < StandardError; end @@ -18,12 +17,12 @@ class ErrorMissingBranchKey < StandardError; end # Basic Api client attr_reader :branch_key, :branch_secret - def initialize(branch_key=ENV["BRANCH_KEY"], branch_secret=ENV["BRANCH_SECRET"]) + def initialize(branch_key = ENV["BRANCH_KEY"], branch_secret = ENV["BRANCH_SECRET"]) @branch_key = branch_key @branch_secret = branch_secret unless branch_key - raise ErrorMissingBranchKey.new("No Branch Key found: please provided one such key to BranchIO::Client#initialize or by setting the BRANCH_KEY environment variable") + raise ErrorMissingBranchKey, "No Branch Key found: please provided one such key to BranchIO::Client#initialize or by setting the BRANCH_KEY environment variable" end end @@ -31,12 +30,12 @@ def get(url) self.class.get(url, headers: default_headers) end - def post(url, data={}) + def post(url, data = {}) body = data.to_json self.class.post(url, body: body, headers: default_headers) end - def put(url, data={}) + def put(url, data = {}) body = data.to_json self.class.put(url, body: body, headers: default_headers) end @@ -45,7 +44,7 @@ def put(url, data={}) def ensure_branch_secret_defined! unless branch_secret - raise ErrorMissingBranchKey.new("No Branch Secret found: please provided one such key to BranchIO::Client#initialize or by setting the BRANCH_SECRET environment variable") + raise ErrorMissingBranchKey, "No Branch Secret found: please provided one such key to BranchIO::Client#initialize or by setting the BRANCH_SECRET environment variable" end end @@ -55,7 +54,5 @@ def default_headers "Accept" => "application/json" } end - end - end diff --git a/lib/branch_io/client/links.rb b/lib/branch_io/client/links.rb index c34486d..e27f828 100644 --- a/lib/branch_io/client/links.rb +++ b/lib/branch_io/client/links.rb @@ -2,17 +2,16 @@ module BranchIO class Client - module Links LINK_PATH = "/v1/url" - def link!(options={}) + def link!(options = {}) res = link(options) res.validate! res end - def link(options={}) + def link(options = {}) # Load and check the link properties link_properties = BranchIO::LinkProperties.wrap(options) @@ -34,15 +33,15 @@ def link(options={}) end end - def links!(options={}) + def links!(options = {}) res = links(options) res.validate! res end - def links(options=[]) + def links(options = []) # Load and check the links properties - link_properties_array = options.map{ |o| BranchIO::LinkProperties.wrap(o) } + link_properties_array = options.map { |o| BranchIO::LinkProperties.wrap(o) } # Build the request links_url = "#{LINK_PATH}/bulk/#{self.branch_key}" @@ -59,13 +58,13 @@ def links(options=[]) end end - def update_link!(options={}) + def update_link!(options = {}) res = update_link(options) res.validate! res end - def update_link(url, options={}) + def update_link(url, options = {}) ensure_branch_secret_defined! # Load and check the links configuration properties @@ -94,7 +93,7 @@ def update_link(url, options={}) end end - def link_info!(options={}) + def link_info!(options = {}) res = link_info(options) res.validate! res @@ -116,8 +115,6 @@ def link_info(url) ErrorResponse.new(raw_response) end end - end - end end diff --git a/lib/branch_io/client/response.rb b/lib/branch_io/client/response.rb index 38d2c42..04371eb 100644 --- a/lib/branch_io/client/response.rb +++ b/lib/branch_io/client/response.rb @@ -28,7 +28,7 @@ def failure? end def validate! - raise ErrorApiCallFailed.new(self) unless success? + raise ErrorApiCallFailed, self unless success? end def json @@ -84,7 +84,7 @@ def erroneous_responses def responses @responses ||= json.map do |url_info| # below the EmbeddedResponseWrapper(s) act as a dummp HTTParty response - if url_info.has_key?("error") + if url_info.key?("error") ErrorResponse.new(EmbeddedResponseWrapper.new(url_info)) else UrlResponse.new(EmbeddedResponseWrapper.new(url_info)) @@ -92,9 +92,14 @@ def responses end end + # rubocop: disable Lint/UselessAccessModifier + # Not sure why RuboCop thinks this is useless. + private - class EmbeddedResponseWrapper < Struct.new(:parsed_response); end + # rubocop: enable Lint/UselessAccessModifier + + EmbeddedResponseWrapper = Struct.new(:parsed_response) end class LinkPropertiesResponse < Response @@ -102,6 +107,5 @@ def link_properties @link_properties ||= BranchIO::LinkProperties.new(json) end end - end end diff --git a/lib/branch_io/link_properties.rb b/lib/branch_io/link_properties.rb index 5689a59..dbe5886 100644 --- a/lib/branch_io/link_properties.rb +++ b/lib/branch_io/link_properties.rb @@ -1,5 +1,4 @@ module BranchIO - class LinkProperties attr_reader :tags attr_reader :channel @@ -18,8 +17,8 @@ def self.wrap(options) end end - def initialize(options={}) - @tags = options.delete(:tags) ||options.delete("tags") + def initialize(options = {}) + @tags = options.delete(:tags) || options.delete("tags") @channel = options.delete(:channel) || options.delete("channel") @feature = options.delete(:feature) || options.delete("feature") @campaign = options.delete(:campaign) || options.delete("campaign") @@ -29,7 +28,7 @@ def initialize(options={}) @data = options.delete(:data) || options.delete("data") unless options.empty? - raise ErrorInvalidParameters.new(options.keys) + raise ErrorInvalidParameters, options.keys end end @@ -50,9 +49,8 @@ class ErrorInvalidParameters < StandardError attr_reader :parameters def initialize(parameters) @parameters = parameters - super("Invalid parameters for BranchIO::LinkProperties: \"#{@parameters.join(", ")}\"") + super("Invalid parameters for BranchIO::LinkProperties: \"#{@parameters.join(', ')}\"") end end end - end diff --git a/lib/branch_io/version.rb b/lib/branch_io/version.rb index 0ae2784..c9a41f9 100644 --- a/lib/branch_io/version.rb +++ b/lib/branch_io/version.rb @@ -1,3 +1,3 @@ module BranchIO - VERSION = "0.1.0" + VERSION = "0.2.0" end diff --git a/spec/branch_io_spec.rb b/spec/branch_io_spec.rb index b78f0f6..91d2a03 100644 --- a/spec/branch_io_spec.rb +++ b/spec/branch_io_spec.rb @@ -1,12 +1,9 @@ -require 'spec_helper' - describe BranchIO do it 'has a version number' do expect(BranchIO::VERSION).not_to be nil end describe "delegate methods to the (default) client" do - %i(link link! links links! update_link update_link! link_info link_info!).each do |m| describe ".#{m}" do it "delegates the call to a new (default) client" do @@ -14,10 +11,9 @@ expect(BranchIO::Client).to receive(:new).and_return(client) expect(client).to receive(m).with(test: 42) - BranchIO.send(m, {test: 42}) + BranchIO.send(m, { test: 42 }) end end end - end end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 3cb575d..f3d20c3 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1,16 +1,12 @@ -require 'spec_helper' - ENV["BRANCH_KEY"] = "key_test_ngn27ouyf8yBVhq5kffg7ncfErc7cISG" ENV["BRANCH_SECRET"] = "secret_test_6L2X9Pt3k07Tn6HW3sKcR3VZFkklISYY" describe BranchIO::Client do - describe "#initialize" do - it "should raise an exception if no branch key is provided" do - expect { + expect do BranchIO::Client.new(nil) - }.to raise_error(BranchIO::Client::ErrorMissingBranchKey) + end.to raise_error(BranchIO::Client::ErrorMissingBranchKey) end it "should try to load the branch key from the BRANCH_KEY envorionemnt variable" do @@ -22,7 +18,6 @@ expect(client.branch_key).to eq("12345") expect(client.branch_secret).to eq("666") end - end describe BranchIO::Client::Links do @@ -43,9 +38,9 @@ res = BranchIO::Client::ErrorResponse.new(double(success?: false)) expect(client).to receive(:link).and_return(res) - expect { + expect do client.link! - }.to raise_error(BranchIO::Client::ErrorApiCallFailed) + end.to raise_error(BranchIO::Client::ErrorApiCallFailed) end end @@ -80,13 +75,14 @@ # Create a new link res = client.link( - tags: [ "test" ], - channel: "test", - feature: "spec", - stage: "test", - data: { - value: 42 - }) + tags: ["test"], + channel: "test", + feature: "spec", + stage: "test", + data: { + value: 42 + } + ) # It should be successbul expect(res).not_to be_nil @@ -100,13 +96,14 @@ # Create a new link properties object props = BranchIO::LinkProperties.new( - tags: [ "test" ], - channel: "test", - feature: "spec", - stage: "test", - data: { - value: 42 - }) + tags: ["test"], + channel: "test", + feature: "spec", + stage: "test", + data: { + value: 42 + } + ) # Pass the configuration object to the call res = client.link(props) @@ -145,12 +142,13 @@ # Create a new link res = client.links([ - { - channel: "test" - }, - { - channel: "test" - }]) + { + channel: "test" + }, + { + channel: "test" + } + ]) # It should be successbul expect(res).not_to be_nil @@ -172,7 +170,7 @@ end describe "#link_info" do - let!(:url) { client.link(channel: "code", feature: "test", tags: [ "test" ]).url } + let!(:url) { client.link(channel: "code", feature: "test", tags: ["test"]).url } it "succeeds" do expect(client.link_info(url)).to be_success @@ -196,11 +194,11 @@ end describe "#update_link" do - let!(:url) { client.link(channel: "code", feature: "test", tags: [ "test", "test-update" ]).url } + let!(:url) { client.link(channel: "code", feature: "test", tags: ["test", "test-update"]).url } it "succeeds" do expect( - client.update_link(url, channel: "retest") + client.update_link(url, channel: "retest") ).to be_success end @@ -210,6 +208,5 @@ expect(props.channel).to eq("retest") end end - end # /Client end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 374623a..56264ea 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,10 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) +require "simplecov" +require "rspec/simplecov" + +SimpleCov.minimum_coverage 90 +SimpleCov.start + require 'branch_io' require "vcr"