diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4928991 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: Test + +on: + push: + pull_request: + +jobs: + test: + strategy: + fail-fast: false + matrix: + ruby: + - 2.7 + - '3.0' + - '3.1' + services: + mysql: + image: mysql:8 + env: + MYSQL_DATABASE: rating_test + MYSQL_ALLOW_EMPTY_PASSWORD: yes + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: 'Runs tests' + run: bundle exec rake spec + - name: 'Runs tests with config enabled' + run: bundle exec rake spec_config + - name: 'Runs tests with config enabled for extra scopes' + run: bundle exec rake spec_config_with_extra_scopes diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml new file mode 100644 index 0000000..319e46f --- /dev/null +++ b/.github/workflows/rubocop.yml @@ -0,0 +1,17 @@ +name: RuboCop + +on: [push, pull_request] + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + bundler-cache: true # 'bundle install' and cache + - name: Run RuboCop + run: bundle exec rubocop --parallel diff --git a/.rubocop.yml b/.rubocop.yml index efd0435..2038921 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,17 +1,18 @@ require: - rubocop-performance + - rubocop-rails - rubocop-rspec inherit_from: .rubocop_todo.yml -Layout/AlignArguments: +Layout/ArgumentAlignment: EnforcedStyle: with_fixed_indentation -Layout/AlignHash: +Layout/HashAlignment: EnforcedColonStyle: table Enabled: false -Layout/AlignParameters: +Layout/ParameterAlignment: EnforcedStyle: with_fixed_indentation Layout/EmptyLinesAroundArguments: diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e69de29..a0a8298 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -0,0 +1,126 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2022-04-21 22:55:24 UTC using RuboCop version 1.28.1. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 1 +# Configuration parameters: Include. +# Include: **/*.gemspec +Gemspec/RequiredRubyVersion: + Exclude: + - 'rating.gemspec' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 139 + +# Offense count: 3 +# This cop supports unsafe auto-correction (--auto-correct-all). +Lint/NonDeterministicRequireOrder: + Exclude: + - 'spec/rails_helper.rb' + - 'spec/support/factory_bot.rb' + - 'spec/support/migrate.rb' + +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne. +Metrics/ClassLength: + Max: 106 + +# Offense count: 2 +# Configuration parameters: CountKeywordArgs, MaxOptionalParameters. +Metrics/ParameterLists: + Max: 6 + +# Offense count: 1 +# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers. +# SupportedStyles: snake_case, normalcase, non_integer +# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339 +Naming/VariableNumber: + Exclude: + - 'spec/rails_helper.rb' + +# Offense count: 2 +# Configuration parameters: Prefixes. +# Prefixes: when, with, without +RSpec/ContextWording: + Exclude: + - 'spec/models/extension/order_by_rating_spec.rb' + - 'spec/support/shared_context/with_database_records.rb' + +# Offense count: 15 +RSpec/DescribeMethod: + Exclude: + - 'spec/models/extension/after_create_spec.rb' + - 'spec/models/extension/order_by_rating_spec.rb' + - 'spec/models/extension/rate_for_spec.rb' + - 'spec/models/extension/rate_spec.rb' + - 'spec/models/extension/rated_question_spec.rb' + - 'spec/models/extension/rated_spec.rb' + - 'spec/models/extension/rates_spec.rb' + - 'spec/models/extension/unscoped_rating_spec.rb' + - 'spec/models/extension/where_spec.rb' + - 'spec/models/rate/create_spec.rb' + - 'spec/models/rate/rate_for_spec.rb' + - 'spec/models/rating/averager_data_spec.rb' + - 'spec/models/rating/data_spec.rb' + - 'spec/models/rating/update_rating_spec.rb' + - 'spec/models/rating/values_data_spec.rb' + +# Offense count: 6 +RSpec/LetSetup: + Exclude: + - 'spec/support/shared_context/with_database_records.rb' + +# Offense count: 12 +# Configuration parameters: . +# SupportedStyles: have_received, receive +RSpec/MessageSpies: + EnforcedStyle: receive + +# Offense count: 2 +# Configuration parameters: AllowSubject. +RSpec/MultipleMemoizedHelpers: + Max: 12 + +# Offense count: 7 +# Configuration parameters: IgnoreSharedExamples. +RSpec/NamedSubject: + Exclude: + - 'spec/config/rate_table_spec.rb' + - 'spec/config/rating_table_spec.rb' + - 'spec/config/validations_spec.rb' + - 'spec/models/rate_spec.rb' + +# Offense count: 2 +RSpec/RepeatedExampleGroupDescription: + Exclude: + - 'spec/models/extension/rated_spec.rb' + +# Offense count: 2 +# This cop supports safe auto-correction (--auto-correct). +Rails/ApplicationRecord: + Exclude: + - 'lib/rating/models/rating/rate.rb' + - 'lib/rating/models/rating/rating.rb' + +# Offense count: 2 +# This cop supports unsafe auto-correction (--auto-correct-all). +# Configuration parameters: Include. +# Include: **/Rakefile, **/*.rake +Rails/RakeEnvironment: + Exclude: + - 'Rakefile' + +# Offense count: 1 +# This cop supports safe auto-correction (--auto-correct). +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns. +# URISchemes: http, https +Layout/LineLength: + Max: 139 diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index 57cf282..0000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.6.5 diff --git a/Gemfile.lock b/Gemfile.lock index 25ec8fd..0608ba7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,118 +7,126 @@ PATH GEM remote: https://rubygems.org/ specs: - actionpack (6.0.2.1) - actionview (= 6.0.2.1) - activesupport (= 6.0.2.1) - rack (~> 2.0, >= 2.0.8) + actionpack (7.0.2.3) + actionview (= 7.0.2.3) + activesupport (= 7.0.2.3) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actionview (6.0.2.1) - activesupport (= 6.0.2.1) + actionview (7.0.2.3) + activesupport (= 7.0.2.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activemodel (6.0.2.1) - activesupport (= 6.0.2.1) - activerecord (6.0.2.1) - activemodel (= 6.0.2.1) - activesupport (= 6.0.2.1) - activesupport (6.0.2.1) + activemodel (7.0.2.3) + activesupport (= 7.0.2.3) + activerecord (7.0.2.3) + activemodel (= 7.0.2.3) + activesupport (= 7.0.2.3) + activesupport (7.0.2.3) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2) - ast (2.4.0) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + ast (2.4.2) builder (3.2.4) - byebug (11.0.1) - coderay (1.1.2) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.10) crass (1.0.6) - database_cleaner (1.7.0) - diff-lcs (1.3) - erubi (1.9.0) - factory_bot (5.1.1) - activesupport (>= 4.2.0) - factory_bot_rails (5.1.1) - factory_bot (~> 5.1.0) - railties (>= 4.2.0) - i18n (1.8.2) + database_cleaner (2.0.1) + database_cleaner-active_record (~> 2.0.0) + database_cleaner-active_record (2.0.1) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) + diff-lcs (1.5.0) + erubi (1.10.0) + factory_bot (6.2.1) + activesupport (>= 5.0.0) + factory_bot_rails (6.2.0) + factory_bot (~> 6.2.0) + railties (>= 5.0.0) + i18n (1.10.0) concurrent-ruby (~> 1.0) - jaro_winkler (1.5.4) - loofah (2.4.0) + loofah (2.16.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) - method_source (0.9.2) - mini_portile2 (2.4.0) - minitest (5.14.0) + method_source (1.0.0) + mini_portile2 (2.8.0) + minitest (5.15.0) mysql2 (0.5.3) - nokogiri (1.10.7) - mini_portile2 (~> 2.4.0) - parallel (1.19.1) - parser (2.7.0.2) - ast (~> 2.4.0) - pry (0.12.2) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - pry-byebug (3.7.0) - byebug (~> 11.0) - pry (~> 0.10) - rack (2.1.1) + nokogiri (1.13.4) + mini_portile2 (~> 2.8.0) + racc (~> 1.4) + parallel (1.22.1) + parser (3.1.2.0) + ast (~> 2.4.1) + racc (1.6.0) + rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.3.0) + rails-html-sanitizer (1.4.2) loofah (~> 2.3) - railties (6.0.2.1) - actionpack (= 6.0.2.1) - activesupport (= 6.0.2.1) + railties (7.0.2.3) + actionpack (= 7.0.2.3) + activesupport (= 7.0.2.3) method_source - rake (>= 0.8.7) - thor (>= 0.20.3, < 2.0) - rainbow (3.0.0) - rake (13.0.1) - rspec-core (3.9.1) - rspec-support (~> 3.9.1) - rspec-expectations (3.9.0) + rake (>= 12.2) + thor (~> 1.0) + zeitwerk (~> 2.5) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.3.0) + rexml (3.2.5) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-mocks (3.9.1) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.9.0) - rspec-rails (3.9.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.9.0) - rspec-expectations (~> 3.9.0) - rspec-mocks (~> 3.9.0) - rspec-support (~> 3.9.0) - rspec-support (3.9.2) - rubocop (0.79.0) - jaro_winkler (~> 1.5.1) + rspec-support (~> 3.11.0) + rspec-rails (5.1.1) + actionpack (>= 5.2) + activesupport (>= 5.2) + railties (>= 5.2) + rspec-core (~> 3.10) + rspec-expectations (~> 3.10) + rspec-mocks (~> 3.10) + rspec-support (~> 3.10) + rspec-support (3.11.0) + rubocop (1.28.1) parallel (~> 1.10) - parser (>= 2.7.0.1) + parser (>= 3.1.0.0) rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.17.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 1.7) - rubocop-performance (1.5.2) - rubocop (>= 0.71.0) - rubocop-rspec (1.37.1) - rubocop (>= 0.68.1) - ruby-progressbar (1.10.1) - shoulda-matchers (4.2.0) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.17.0) + parser (>= 3.1.1.0) + rubocop-performance (1.13.3) + rubocop (>= 1.7.0, < 2.0) + rubocop-ast (>= 0.4.0) + rubocop-rails (2.14.2) activesupport (>= 4.2.0) - thor (1.0.1) - thread_safe (0.3.6) - tzinfo (1.2.6) - thread_safe (~> 0.1) - unicode-display_width (1.6.1) - zeitwerk (2.2.2) + rack (>= 1.1) + rubocop (>= 1.7.0, < 2.0) + rubocop-rspec (2.10.0) + rubocop (~> 1.19) + ruby-progressbar (1.11.0) + shoulda-matchers (5.1.0) + activesupport (>= 5.2.0) + thor (1.2.1) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) + unicode-display_width (2.1.0) + zeitwerk (2.5.4) PLATFORMS ruby @@ -127,10 +135,10 @@ DEPENDENCIES database_cleaner factory_bot_rails mysql2 - pry-byebug rating! rspec-rails rubocop-performance + rubocop-rails rubocop-rspec shoulda-matchers diff --git a/lib/rating/models/rating/rate.rb b/lib/rating/models/rating/rate.rb index 06dfd4c..a349ab8 100644 --- a/lib/rating/models/rating/rate.rb +++ b/lib/rating/models/rating/rate.rb @@ -19,7 +19,7 @@ module Rating scope: ::Rating::Config.validations['rate']['scope'].map(&:to_sym), } - def self.create(author:, extra_scopes:, metadata:, resource:, scopeable: nil, value:) + def self.create(author:, extra_scopes:, metadata:, resource:, value:, scopeable: nil) attributes = { author: author, resource: resource, scopeable: scopeable }.merge(extra_scopes) record = find_or_initialize_by(attributes) @@ -31,7 +31,7 @@ module Rating record end - def self.rate_for(author:, extra_scopes: {}, resource:, scopeable: nil) + def self.rate_for(author:, resource:, extra_scopes: {}, scopeable: nil) find_by extra_scopes.merge(author: author, resource: resource, scopeable: scopeable) end diff --git a/rating.gemspec b/rating.gemspec index 6b0233a..3cc426d 100644 --- a/rating.gemspec +++ b/rating.gemspec @@ -20,9 +20,9 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'database_cleaner' spec.add_development_dependency 'factory_bot_rails' spec.add_development_dependency 'mysql2' - spec.add_development_dependency 'pry-byebug' spec.add_development_dependency 'rspec-rails' spec.add_development_dependency 'rubocop-performance' + spec.add_development_dependency 'rubocop-rails' spec.add_development_dependency 'rubocop-rspec' spec.add_development_dependency 'shoulda-matchers' end diff --git a/spec/factories/rating/rate.rb b/spec/factories/rating/rate.rb index 618f352..307eb23 100644 --- a/spec/factories/rating/rate.rb +++ b/spec/factories/rating/rate.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true FactoryBot.define do - factory :rating_rate, class: Rating::Rate do + factory :rating_rate, class: 'Rating::Rate' do value { 100 } author { create :author } diff --git a/spec/factories/rating/rating.rb b/spec/factories/rating/rating.rb index 3bba839..8a77209 100644 --- a/spec/factories/rating/rating.rb +++ b/spec/factories/rating/rating.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true FactoryBot.define do - factory :rating_rating, class: Rating::Rating do + factory :rating_rating, class: 'Rating::Rating' do average { 100 } estimate { 100 } sum { 100 } diff --git a/spec/models/extension/rate_for_spec.rb b/spec/models/extension/rate_for_spec.rb index 30aa237..577fa40 100644 --- a/spec/models/extension/rate_for_spec.rb +++ b/spec/models/extension/rate_for_spec.rb @@ -8,7 +8,8 @@ RSpec.describe Rating::Extension, ':rate_for' do context 'with no scopeable' do it 'delegates to rate object' do - expect(Rating::Rate).to receive(:rate_for).with author: author, extra_scopes: {}, resource: article, scopeable: nil + expect(Rating::Rate).to receive(:rate_for).with author: author, extra_scopes: {}, resource: article, + scopeable: nil author.rate_for article end @@ -18,7 +19,8 @@ RSpec.describe Rating::Extension, ':rate_for' do let!(:category) { build :category } it 'delegates to rate object' do - expect(Rating::Rate).to receive(:rate_for).with author: author, extra_scopes: {}, resource: article, scopeable: category + expect(Rating::Rate).to receive(:rate_for).with author: author, extra_scopes: {}, resource: article, + scopeable: category author.rate_for article, scope: category end diff --git a/spec/models/extension/rate_spec.rb b/spec/models/extension/rate_spec.rb index 8163a1f..6ee12c1 100644 --- a/spec/models/extension/rate_spec.rb +++ b/spec/models/extension/rate_spec.rb @@ -51,7 +51,12 @@ RSpec.describe Rating::Extension, ':rate' do context 'with extra_scopes' do it 'delegates to rate object' do expect(Rating::Rate).to receive(:create).with( - author: author, extra_scopes: { scope_1: 'scope_1' }, metadata: { comment: 'comment' }, resource: article, scopeable: nil, value: 3 + author: author, + extra_scopes: { scope_1: 'scope_1' }, + metadata: { comment: 'comment' }, + resource: article, + scopeable: nil, + value: 3 ) author.rate article, 3, extra_scopes: { scope_1: 'scope_1' }, metadata: { comment: 'comment' } diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 0aeabc0..9a291f0 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -4,14 +4,13 @@ ENV['RAILS_ENV'] ||= 'test' require 'active_record/railtie' require 'mysql2' -require 'pry-byebug' require 'rating' -client = Mysql2::Client.new(host: :localhost, username: :root) +client = Mysql2::Client.new(host: '127.0.0.1', username: :root) client.query 'DROP DATABASE IF EXISTS rating_test;' client.query 'CREATE DATABASE IF NOT EXISTS rating_test;' -ActiveRecord::Base.establish_connection adapter: :mysql2, database: :rating_test, username: :root +ActiveRecord::Base.establish_connection adapter: :mysql2, database: :rating_test, username: :root, host: '127.0.0.1' Dir[File.expand_path('support/**/*.rb', __dir__)].each { |file| require file }