gutentag 2.5.2 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e934d0f1e941db5003a28ee2dc0ca30592db0b594f5633eeac2374f6a0ee8f9f
4
- data.tar.gz: 8972fd4264e0dad5499ddbd7c9642caf8b15052fa78b63bebec6de4c57f1b9b6
3
+ metadata.gz: 4a57320061f9e3181385744a38c797564a7ce45c2fceb6e51ba3bc7a5e7a4d68
4
+ data.tar.gz: 86d6f5d761a18434e20919b1996234896f33f5764ed2f6032cca5dbe82164e2a
5
5
  SHA512:
6
- metadata.gz: 55961186203575a716c658bd966102d344badbe8940f88523e6e4e76d795b8a9089be43320fd40735b749ed7f4507d3fe7d509bdd6f942dd9d2fabfb0d32e89b
7
- data.tar.gz: 90f27936f1f5a96b522d26ad53ce8c74309fdc62c4409cb662112ee8603e610158ae379785646217b0cc61ea5a5e4150d31eaea77ea83033828c0d0af2db8771
6
+ metadata.gz: 45e211fdef9849824571e960dfe21d68eaa77ca2244375952e823e031bc112d797f55513aa7adf25c6469d399ba9f7e045c7714cf875c13a754823e91cea3f17
7
+ data.tar.gz: 86f48f5be03702882c074ff36d055ca735ca97ef0ae9befa1fd95e750cbcea7c44b0f00e52a4df19f8007fb361816661e7415035a083ed288fd01e4f003884b8
@@ -0,0 +1,90 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-18.04
8
+
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
13
+ bundler: [ '1.17.3', '2.1.4' ]
14
+ database: [ 'mysql', 'postgresql', 'sqlite' ]
15
+ exclude:
16
+ - ruby: '2.4'
17
+ bundler: '2.1.4'
18
+ - ruby: '2.5'
19
+ bundler: '2.1.4'
20
+ - ruby: '2.6'
21
+ bundler: '2.1.4'
22
+ - ruby: '2.7'
23
+ bundler: '1.17.3'
24
+ - ruby: '3.0'
25
+ bundler: '1.17.3'
26
+
27
+ services:
28
+ postgres:
29
+ image: postgres:10
30
+ env:
31
+ POSTGRES_USER: root
32
+ POSTGRES_PASSWORD: gutentag
33
+ POSTGRES_DB: test
34
+ ports: ['5432:5432']
35
+ # needed because the postgres container does not provide a healthcheck
36
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
37
+
38
+ mysql:
39
+ image: mysql:5.7
40
+ env:
41
+ MYSQL_ROOT_PASSWORD: gutentag
42
+ MYSQL_DATABASE: test
43
+ ports: ['3306:3306']
44
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
45
+
46
+ steps:
47
+ - name: Check out code
48
+ uses: actions/checkout@v2
49
+ - name: Set up ruby
50
+ uses: ruby/setup-ruby@v1
51
+ with:
52
+ ruby-version: ${{ matrix.ruby }}
53
+ bundler: ${{ matrix.bundler }}
54
+ bundler-cache: true
55
+
56
+ - name: Set up Bundler
57
+ run: |
58
+ export BUNDLER_VERSION=${{ matrix.bundler }}
59
+ export BUNDLE_PATH=$PWD/vendor/bundle
60
+
61
+ gem update --system
62
+
63
+ bundle _${{ matrix.bundler }}_ config set path $PWD/$BUNDLE_PATH
64
+ bundle _${{ matrix.bundler }}_ install --jobs=4 --retry=3
65
+ bundle _${{ matrix.bundler }}_ update
66
+ - name: Set up Appraisal
67
+ run: bundle exec appraisal update
68
+ - name: Test
69
+ env:
70
+ CI: "true"
71
+ DATABASE: ${{ matrix.database }}
72
+ DB_USERNAME: root
73
+ DB_PASSWORD: gutentag
74
+ DB_HOST: 127.0.0.1
75
+ run: bundle exec appraisal rspec
76
+
77
+ rubocop:
78
+ runs-on: ubuntu-18.04
79
+
80
+ steps:
81
+ - name: Check out code
82
+ uses: actions/checkout@v2
83
+ - name: Set up ruby
84
+ uses: ruby/setup-ruby@v1
85
+ with:
86
+ ruby-version: 2.7
87
+ bundler: 2.1.4
88
+ bundler-cache: true
89
+ - name: Rubocop
90
+ run: bundle exec rubocop
data/.gitignore CHANGED
@@ -2,4 +2,5 @@
2
2
  gemfiles
3
3
  pkg/*
4
4
  spec/internal/db/*.sqlite
5
+ spec/internal/db/migrate/
5
6
  .rubocop-*-yml
data/.rubocop.yml CHANGED
@@ -7,6 +7,10 @@ AllCops:
7
7
  TargetRubyVersion: 2.3
8
8
  Exclude:
9
9
  - gemfiles/*.gemfile
10
+ - vendor/**/*
11
+
12
+ Bundler/DuplicatedGem:
13
+ Enabled: false
10
14
 
11
15
  Metrics/MethodLength:
12
16
  Exclude:
@@ -20,3 +24,19 @@ Style/MultilineIfModifier:
20
24
  Style/MultilineTernaryOperator:
21
25
  Exclude:
22
26
  - db/migrate/*.rb
27
+
28
+ # 0.80
29
+
30
+ Style/HashEachMethods:
31
+ Enabled: true
32
+ Style/HashTransformKeys:
33
+ Enabled: true
34
+ Style/HashTransformValues:
35
+ Enabled: true
36
+
37
+ # 0.81
38
+
39
+ Lint/RaiseException:
40
+ Enabled: true
41
+ Lint/StructNewOverride:
42
+ Enabled: true
data/Appraisals CHANGED
@@ -17,27 +17,34 @@ appraise "rails_4_2" do
17
17
  gem "activerecord-jdbcmysql-adapter", "~> 1.3.23", :platform => :jruby
18
18
  gem "activerecord-jdbcpostgresql-adapter", "~> 1.3.23", :platform => :jruby
19
19
  gem "activerecord-jdbcsqlite3-adapter", "~> 1.3.23", :platform => :jruby
20
- end
20
+ end if RUBY_VERSION.to_f < 2.7
21
21
 
22
22
  appraise "rails_5_0" do
23
23
  gem "rails", "~> 5.0.3"
24
24
  gem "mysql2", "~> 0.4.0", :platform => :ruby
25
- end if RUBY_VERSION.to_f >= 2.2
25
+ end if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.7
26
26
 
27
27
  appraise "rails_5_1" do
28
28
  gem "rails", "~> 5.1.1"
29
29
  gem "mysql2", "~> 0.4.0", :platform => :ruby
30
- end if RUBY_VERSION.to_f >= 2.2
30
+ end if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.7
31
31
 
32
32
  appraise "rails_5_2" do
33
33
  gem "rails", "~> 5.2.0"
34
34
  gem "pg", "~> 1.0", :platform => :ruby
35
35
  gem "mysql2", "~> 0.5.0", :platform => :ruby
36
- end if RUBY_VERSION.to_f >= 2.2
36
+ end if RUBY_VERSION.to_f >= 2.2 && RUBY_VERSION.to_f <= 2.7
37
37
 
38
38
  appraise "rails_6_0" do
39
- gem "rails", "~> 6.0.0.rc1"
39
+ gem "rails", "~> 6.0.0"
40
40
  gem "pg", "~> 1.0", :platform => :ruby
41
41
  gem "mysql2", "~> 0.5.0", :platform => :ruby
42
- gem "sqlite3", "~> 1.4", :platform => :ruby
42
+ gem "sqlite3", "~> 1.4", :platform => :ruby
43
+ end if RUBY_VERSION.to_f >= 2.5 && RUBY_PLATFORM != "java"
44
+
45
+ appraise "rails_6_1" do
46
+ gem "rails", "~> 6.1.0"
47
+ gem "pg", "~> 1.0", :platform => :ruby
48
+ gem "mysql2", "~> 0.5.0", :platform => :ruby
49
+ gem "sqlite3", "~> 1.4", :platform => :ruby
43
50
  end if RUBY_VERSION.to_f >= 2.5 && RUBY_PLATFORM != "java"
data/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  All notable changes to this project (at least, from v0.5.0 onwards) will be documented in this file.
4
4
 
5
+ ## 2.6.1 - 2021-09-18
6
+
7
+ ### Fixed
8
+
9
+ * The initially-generated migrations now work out of the box with Rails 5.0+, using the 4.2 version. The generator will now update that version to the latest, or remove it for Rails 4.2. See later discussion in [#80](https://github.com/pat/gutentag/issues/80).
10
+
11
+ ## 2.6.0 - 2021-07-10
12
+
13
+ ### Added
14
+
15
+ * Queries can now be made for objects that have _none_ of the specified tags using `:match => :none` ([Rares S](https://github.com/laleshii) in [#79](https://github.com/pat/gutentag/pull/79)).
16
+ * Added a generator `gutentag:migration_versions` to update generated migrations so they use the current version of Rails/ActiveRecord's Migration superclass. See discussion in [#80](https://github.com/pat/gutentag/issues/80).
17
+
18
+ ### Changed
19
+
20
+ * When adding Gutentag to a new app, the migrations require the `gutentag:migration_versions` generator to be run to ensure the latest ActiveRecord migration superclass is used. This change has no impact to existing apps. See discussion in [#80](https://github.com/pat/gutentag/issues/80).
21
+
22
+ ## 2.5.4 - 2021-02-21
23
+
24
+ ### Fixed
25
+
26
+ * Don't apply the tag length validation when `ActiveRecord::ConnectionNotEstablished` exceptions are raised. ([John Duff](https://github.com/jduff) in [#77](https://github.com/pat/gutentag/pull/77)).
27
+
28
+ ## 2.5.3 - 2020-06-28
29
+
30
+ ### Fixed
31
+
32
+ * Use `saved_change_to_tag_names?` instead of `tag_names_previously_changed?` for Rails 5.1+ ([Morten Trolle](https://github.com/mtrolle) in [#70](https://github.com/pat/gutentag/pull/70)).
33
+ * `Gutentag::Tag.names_for_scope` now handles empty scopes ([Mike Gunderloy](https://github.com/ffmike) in [#73](https://github.com/pat/gutentag/pull/73)).
34
+
5
35
  ## 2.5.2 - 2019-07-08
6
36
 
7
37
  ### Fixed
data/Gemfile CHANGED
@@ -8,7 +8,12 @@ gem "test-unit", :platform => :ruby_22
8
8
 
9
9
  gem "mysql2", "~> 0.3", :platform => :ruby
10
10
  gem "pg", "~> 0.18", :platform => :ruby
11
- gem "sqlite3", "~> 1.3.13", :platform => :ruby
11
+
12
+ if RUBY_VERSION.to_f < 3.0
13
+ gem "sqlite3", "~> 1.3.13"
14
+ else
15
+ gem "sqlite3", "~> 1.4"
16
+ end
12
17
 
13
18
  gem "activerecord-jdbcmysql-adapter", ">= 1.3.23", :platform => :jruby
14
19
  gem "activerecord-jdbcpostgresql-adapter", ">= 1.3.23", :platform => :jruby
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # Gutentag
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/gutentag.png)](http://badge.fury.io/rb/gutentag)
4
- [![Build Status](https://travis-ci.org/pat/gutentag.png?branch=master)](https://travis-ci.org/pat/gutentag)
5
- [![Code Climate](https://codeclimate.com/github/pat/gutentag.png)](https://codeclimate.com/github/pat/gutentag)
3
+ [![Gem Version](https://badge.fury.io/rb/gutentag.svg)](http://badge.fury.io/rb/gutentag)
4
+ [![Build Status](https://travis-ci.org/pat/gutentag.svg?branch=master)](https://travis-ci.org/pat/gutentag)
5
+ [![Code Climate](https://codeclimate.com/github/pat/gutentag.svg)](https://codeclimate.com/github/pat/gutentag)
6
6
 
7
7
  A good, simple, solid tagging extension for ActiveRecord.
8
8
 
9
9
  This was initially built partly as a proof-of-concept, partly to see how a tagging gem could work when it's not all stuffed within models, and partly just because I wanted a simpler tagging library. It's now a solid little tagging Rails engine.
10
10
 
11
- If you want to know more, read [this blog post](http://freelancing-gods.com/posts/gutentag_simple_rails_tagging).
11
+ If you want to know more, read [this blog post](http://freelancing-gods.com/posts/gutentag_simple_rails_tagging), or have a look at [the Examples page](https://github.com/pat/gutentag/wiki/Examples) in the wiki (which includes a starting point for accepting tag values in a form).
12
12
 
13
13
  ## Contents
14
14
 
@@ -67,6 +67,13 @@ To return records that have _all_ specified tags, use `:match => :all`:
67
67
  Article.tagged_with(:ids => [tag_a.id, tag_b.id], :match => :all)
68
68
  ```
69
69
 
70
+ To return records that have _none_ of the specified tags, use `:match => :none`:
71
+
72
+ ```ruby
73
+ # Returns all articles that have *neither* tag_a nor tag_b.
74
+ Article.tagged_with(:ids => [tag_a.id, tag_b.id], :match => :none)
75
+ ```
76
+
70
77
  <h2 id="installation">Installation</h2>
71
78
 
72
79
  ### Dependencies
@@ -74,7 +81,7 @@ Article.tagged_with(:ids => [tag_a.id, tag_b.id], :match => :all)
74
81
  These are the versions the test suite runs against. It's possible it may work on older versions of Ruby, but it definitely won't work on older versions of Rails.
75
82
 
76
83
  * Ruby: MRI v2.3-v2.6, JRuby v9.2.5
77
- * Rails/ActiveRecord: v4.0-v6.0
84
+ * Rails/ActiveRecord: v4.0-v6.1
78
85
 
79
86
  If you're using MRI v2.2 and/or ActiveRecord v3.2, the last version of Gutentag that fully supported those versions is v2.4.1.
80
87
 
@@ -83,14 +90,15 @@ If you're using MRI v2.2 and/or ActiveRecord v3.2, the last version of Gutentag
83
90
  Get it into your Gemfile - and don't forget the version constraint!
84
91
 
85
92
  ```Ruby
86
- gem 'gutentag', '~> 2.5'
93
+ gem 'gutentag', '~> 2.6'
87
94
  ```
88
95
 
89
- Next: your tags get persisted to your database, so let's import and run the migrations to get the tables set up:
96
+ Next: your tags get persisted to your database, so let's import the migrations, update them to your current version of Rails, and then migrate:
90
97
 
91
98
  ```Bash
92
- rake gutentag:install:migrations
93
- rake db:migrate
99
+ bundle exec rake gutentag:install:migrations
100
+ bundle exec rails generate gutentag:migration_versions
101
+ bundle exec rake db:migrate
94
102
  ```
95
103
 
96
104
  If you're using UUID primary keys, make sure you alter the migration files before running `db:migrate` to use UUIDs for the `taggable_id` foreign key column (as noted in [issue 57](https://github.com/pat/gutentag/issues/57).)
@@ -171,4 +179,4 @@ Please note that this project now has a [Contributor Code of Conduct](http://con
171
179
 
172
180
  <h2 id="licence">Licence</h2>
173
181
 
174
- Copyright (c) 2013-2015, Gutentag is developed and maintained by Pat Allan, and is released under the open MIT Licence.
182
+ Copyright (c) 2013-2021, Gutentag is developed and maintained by Pat Allan, and is released under the open MIT Licence.
@@ -21,7 +21,9 @@ class Gutentag::Tag < ActiveRecord::Base
21
21
 
22
22
  def self.names_for_scope(scope)
23
23
  join_conditions = {:taggable_type => scope.name}
24
- if scope.current_scope.present?
24
+ if scope.is_a?(ActiveRecord::Relation)
25
+ return Gutentag::Tag.none unless scope.current_scope.present?
26
+
25
27
  join_conditions[:taggable_id] = scope.select(:id)
26
28
  end
27
29
 
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- superclass = ActiveRecord::VERSION::MAJOR < 5 ?
4
- ActiveRecord::Migration : ActiveRecord::Migration[4.2]
5
- class GutentagTables < superclass
3
+ class GutentagTables < ActiveRecord::Migration[4.2]
6
4
  def up
7
5
  create_table :gutentag_taggings do |t|
8
6
  t.integer :tag_id, :null => false
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- superclass = ActiveRecord::VERSION::MAJOR < 5 ?
4
- ActiveRecord::Migration : ActiveRecord::Migration[4.2]
5
- class GutentagCacheCounter < superclass
3
+ class GutentagCacheCounter < ActiveRecord::Migration[4.2]
6
4
  def up
7
5
  add_column :gutentag_tags, :taggings_count, :integer, :default => 0
8
6
  add_index :gutentag_tags, :taggings_count
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- superclass = ActiveRecord::VERSION::MAJOR < 5 ?
4
- ActiveRecord::Migration : ActiveRecord::Migration[4.2]
5
- class NoNullCounters < superclass
3
+ class NoNullCounters < ActiveRecord::Migration[4.2]
6
4
  def up
7
5
  change_column :gutentag_tags, :taggings_count, :integer,
8
6
  :default => 0,
data/gutentag.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "gutentag"
5
- s.version = "2.5.2"
5
+ s.version = "2.6.1"
6
6
  s.authors = ["Pat Allan"]
7
7
  s.email = ["pat@freelancing-gods.com"]
8
8
  s.homepage = "https://github.com/pat/gutentag"
@@ -16,12 +16,12 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_runtime_dependency "activerecord", ">= 3.2.0"
18
18
 
19
- s.add_development_dependency "appraisal", "~> 2.1.0"
20
- s.add_development_dependency "bundler", "~> 1.17"
19
+ s.add_development_dependency "appraisal", "~> 2.4.1"
20
+ s.add_development_dependency "bundler", ">= 1.17"
21
21
  s.add_development_dependency "combustion", "~> 1.1"
22
22
  s.add_development_dependency "database_cleaner", "~> 1.6"
23
23
  s.add_development_dependency "rails"
24
24
  s.add_development_dependency "rspec-rails", "~> 3.1"
25
- s.add_development_dependency "rubocop", "~> 0.72.0"
25
+ s.add_development_dependency "rubocop", "~> 0.81.0"
26
26
  s.add_development_dependency "rubocop-performance", "~> 1"
27
27
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  # For Rails 5.0+
4
4
  module Gutentag::ActiveRecord::InstanceMethods
5
+ AR_VERSION = ActiveRecord::VERSION::STRING.to_f
6
+
5
7
  # If the tag_names attribute was one of the modified values, then let's just
6
8
  # use the modifications, rather than overwriting the stored value.
7
9
  #
@@ -9,7 +11,12 @@ module Gutentag::ActiveRecord::InstanceMethods
9
11
  # the instance directly (e.g. article.tags << tag), which invokes the save
10
12
  # callbacks, but the old tag_names value is stored but not updated.
11
13
  def reset_tag_names
12
- return if tag_names_previously_changed?
14
+ # Rails 5.1 introduces major changes to how ActiveModel::Dirty works:
15
+ # https://github.com/pat/gutentag/pull/70#issuecomment-524605448
16
+ # For Rails <5.1 we'll use *_previously_changed?
17
+ # and for 5.1+ we'll use saved_change_to_*?
18
+ return if AR_VERSION < 5.1 && tag_names_previously_changed?
19
+ return if AR_VERSION >= 5.1 && saved_change_to_tag_names?
13
20
 
14
21
  # Update the underlying value rather than going through the setter, to
15
22
  # ensure this update doesn't get marked as a 'change'.
@@ -2,4 +2,8 @@
2
2
 
3
3
  class Gutentag::Engine < Rails::Engine
4
4
  engine_name :gutentag
5
+
6
+ generators do
7
+ require "gutentag/generators/migration_versions_generator"
8
+ end
5
9
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Gutentag
6
+ module Generators
7
+ class MigrationVersionsGenerator < Rails::Generators::Base
8
+ desc "Update the ActiveRecord version in Gutentag migrations"
9
+
10
+ def update_migration_versions
11
+ superclass = "ActiveRecord::Migration[#{rails_version}]"
12
+
13
+ if ::ActiveRecord::VERSION::MAJOR < 5
14
+ superclass = "ActiveRecord::Migration"
15
+ end
16
+
17
+ migration_files.each do |file|
18
+ gsub_file file,
19
+ /< ActiveRecord::Migration\[4\.2\]$/,
20
+ "< #{superclass}"
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def migration_files
27
+ Dir[Rails.root.join("db/migrate/*.rb")].select do |path|
28
+ known_migration_names.any? do |known|
29
+ File.basename(path)[/\A\d+_#{known}\.gutentag.rb\z/]
30
+ end
31
+ end
32
+ end
33
+
34
+ def known_migration_names
35
+ @known_migration_names ||= begin
36
+ Dir[File.join(__dir__, "../../../db/migrate/*.rb")].collect do |path|
37
+ File.basename(path).gsub(/\A\d+_/, "").gsub(/\.rb\z/, "")
38
+ end
39
+ end
40
+ end
41
+
42
+ def rails_version
43
+ @rails_version ||= [
44
+ ::ActiveRecord::VERSION::MAJOR,
45
+ ::ActiveRecord::VERSION::MINOR
46
+ ].join(".")
47
+ end
48
+ end
49
+ end
50
+ end
@@ -13,6 +13,7 @@ class Gutentag::TagValidations
13
13
  if ActiveRecord::VERSION::STRING.to_f > 4.0
14
14
  classes << ActiveRecord::NoDatabaseError
15
15
  end
16
+ classes << ActiveRecord::ConnectionNotEstablished
16
17
  classes << Mysql2::Error if defined?(::Mysql2)
17
18
  classes << PG::ConnectionBad if defined?(::PG)
18
19
  classes
@@ -8,7 +8,7 @@ class Gutentag::TaggedWith::Query
8
8
  end
9
9
 
10
10
  def call
11
- model.where "#{model_id} IN (#{query.to_sql})"
11
+ model.where "#{model_id} #{operator} (#{query.to_sql})"
12
12
  end
13
13
 
14
14
  private
@@ -20,8 +20,16 @@ class Gutentag::TaggedWith::Query
20
20
  end
21
21
 
22
22
  def query
23
- return taggable_ids_query if match == :any || values.length == 1
23
+ return taggable_ids_query if match_any_or_none? || values.length == 1
24
24
 
25
25
  taggable_ids_query.having("COUNT(*) = #{values.length}").group(:taggable_id)
26
26
  end
27
+
28
+ def operator
29
+ match == :none ? "NOT IN" : "IN"
30
+ end
31
+
32
+ def match_any_or_none?
33
+ %i[any none].include?(match)
34
+ end
27
35
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe "Removing unused" do
5
+ RSpec.describe "Removing unused" do
6
6
  let(:article) { Article.create }
7
7
 
8
8
  it "deletes only unused tags" do
@@ -27,4 +27,12 @@ RSpec.describe "Tag names for scopes" do
27
27
  expect(Gutentag::Tag.names_for_scope(Article)).
28
28
  to match_array(%w[ koala wombat cassowary ])
29
29
  end
30
+
31
+ it "returns an empty array for an empty scope" do
32
+ Article.create :title => "mammals", :tag_names => %w[ koala wombat ]
33
+ Article.create :title => "birds", :tag_names => %w[ cassowary ]
34
+
35
+ expect(Gutentag::Tag.names_for_scope(Article.where(:title => "reptiles"))).
36
+ to match_array([])
37
+ end
30
38
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe "Managing tags via names" do
5
+ RSpec.describe "Managing tags via names" do
6
6
  let(:article) { Article.create }
7
7
 
8
8
  it "returns tag names" do
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe "Adding and removing tags" do
5
+ RSpec.describe "Adding and removing tags" do
6
6
  let(:article) { Article.create }
7
7
  let(:pancakes) { Gutentag::Tag.create :name => "pancakes" }
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag::ActiveRecord do
5
+ RSpec.describe Gutentag::ActiveRecord do
6
6
  describe ".tagged_with" do
7
7
  let!(:melbourne_article) do
8
8
  article = Article.create :title => "Overview"
@@ -160,6 +160,26 @@ describe Gutentag::ActiveRecord do
160
160
  it { is_expected.not_to include oregon_article }
161
161
  end
162
162
 
163
+ context "matching excluding one tag" do
164
+ subject do
165
+ Article.tagged_with(:names => %w[ melbourne ], :match => :none)
166
+ end
167
+
168
+ it { expect(subject.count).to eq 1 }
169
+ it { is_expected.to include oregon_article }
170
+ it do
171
+ is_expected.not_to include melbourne_oregon_article, melbourne_article
172
+ end
173
+ end
174
+
175
+ context "matching excluding all tags" do
176
+ subject do
177
+ Article.tagged_with(:names => %w[ melbourne oregon ], :match => :none)
178
+ end
179
+
180
+ it { expect(subject.count).to eq 0 }
181
+ end
182
+
163
183
  it "should work on STI subclasses" do
164
184
  thinkpiece = Thinkpiece.create! :tag_names => ["pancakes"]
165
185
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag do
5
+ RSpec.describe Gutentag do
6
6
  describe ".normalizer" do
7
7
  it "downcases the provided name" do
8
8
  expect(Gutentag.normaliser.call("Tasty Pancakes")).to eq("tasty pancakes")
@@ -2,11 +2,26 @@
2
2
  test:
3
3
  adapter: mysql2
4
4
  database: gutentag
5
- username: root
5
+ username: <%= ENV.fetch("DB_USERNAME", "root") %>
6
+ <% if ENV["DB_HOST"] %>
7
+ host: <%= ENV["DB_HOST"] %>
8
+ <% end %>
9
+ <% if ENV["DB_PASSWORD"] %>
10
+ password: <%= ENV["DB_PASSWORD"] %>
11
+ <% end %>
6
12
  <% elsif ENV["DATABASE"] == "postgres" %>
7
13
  test:
8
14
  adapter: postgresql
9
15
  database: gutentag
16
+ <% if ENV["DB_HOST"] %>
17
+ host: <%= ENV["DB_HOST"] %>
18
+ <% end %>
19
+ <% if ENV["DB_USERNAME"] %>
20
+ username: <%= ENV["DB_USERNAME"] %>
21
+ <% end %>
22
+ <% if ENV["DB_PASSWORD"] %>
23
+ password: <%= ENV["DB_PASSWORD"] %>
24
+ <% end %>
10
25
  <% else %>
11
26
  test:
12
27
  adapter: sqlite3
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag::Tag, :type => :model do
5
+ RSpec.describe Gutentag::Tag, :type => :model do
6
6
  describe ".find_by_name" do
7
7
  it "returns a tag with the same name" do
8
8
  existing = Gutentag::Tag.create! :name => "pancakes"
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Gutentag::Tagging, :type => :model do
5
+ RSpec.describe Gutentag::Tagging, :type => :model do
6
6
  describe "#valid?" do
7
7
  let(:tag) { Gutentag::Tag.create! :name => "pancakes" }
8
8
  let(:taggable) { Article.create! }
data/spec/spec_helper.rb CHANGED
@@ -4,14 +4,17 @@ require "bundler/setup"
4
4
 
5
5
  Bundler.require :default, :development
6
6
 
7
- Dir["#{__dir__}/support/**/*.rb"].each { |file| require file }
7
+ Dir["#{__dir__}/support/**/*.rb"].sort.each { |file| require file }
8
8
 
9
- Combustion.initialize! :active_record
9
+ Combustion.initialize! :active_record, :database_migrate => false
10
+ AdjustMigrations.call(Combustion::Application)
10
11
  ActiveSupport.run_load_hooks :gutentag unless defined?(Gutentag::Engine)
11
12
 
12
13
  require "rspec/rails"
13
14
 
14
15
  RSpec.configure do |config|
16
+ config.disable_monkey_patching!
17
+
15
18
  if config.respond_to?(:use_transactional_tests)
16
19
  config.use_transactional_tests = false
17
20
  else
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "gutentag/generators/migration_versions_generator"
5
+
6
+ class AdjustMigrations
7
+ def self.call(application)
8
+ new(application).call
9
+ end
10
+
11
+ def initialize(application)
12
+ @application = application
13
+ end
14
+
15
+ def call
16
+ copy_migrations_to_app
17
+ run_generator
18
+ run_migrations
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :application
24
+
25
+ def copy_migrations_to_app
26
+ FileUtils.mkdir_p application.root.join("db/migrate")
27
+
28
+ Dir["#{__dir__}/../../db/migrate/*.rb"].each do |file|
29
+ name = File.basename(file.gsub(/rb\z/, "gutentag.rb"))
30
+ destination = application.root.join("db/migrate/#{name}")
31
+
32
+ FileUtils.cp file, destination.to_s
33
+ end
34
+ end
35
+
36
+ def migration_context
37
+ if ActiveRecord::MigrationContext.instance_method(:initialize).arity <= 1
38
+ ActiveRecord::MigrationContext.new migration_paths
39
+ else
40
+ ActiveRecord::MigrationContext.new(
41
+ migration_paths, ActiveRecord::Base.connection.schema_migration
42
+ )
43
+ end
44
+ end
45
+
46
+ def migration_paths
47
+ application.root.join("db/migrate")
48
+ end
49
+
50
+ def run_generator
51
+ Gutentag::Generators::MigrationVersionsGenerator.start(
52
+ ["--quiet"], :destination_root => application.root
53
+ )
54
+ end
55
+
56
+ def run_migrations
57
+ if ActiveRecord::VERSION::STRING.to_f >= 5.2
58
+ migration_context.migrate
59
+ else
60
+ ActiveRecord::Migrator.migrate migration_paths, nil
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gutentag
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.2
4
+ version: 2.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pat Allan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-08 00:00:00.000000000 Z
11
+ date: 2021-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -30,26 +30,26 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.1.0
33
+ version: 2.4.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.1.0
40
+ version: 2.4.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '1.17'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.17'
55
55
  - !ruby/object:Gem::Dependency
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.72.0
117
+ version: 0.81.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.72.0
124
+ version: 0.81.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: rubocop-performance
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -143,9 +143,9 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
+ - ".github/workflows/ci.yml"
146
147
  - ".gitignore"
147
148
  - ".rubocop.yml"
148
- - ".travis.yml"
149
149
  - Appraisals
150
150
  - CHANGELOG.md
151
151
  - Gemfile
@@ -167,6 +167,7 @@ files:
167
167
  - lib/gutentag/change_state.rb
168
168
  - lib/gutentag/dirty.rb
169
169
  - lib/gutentag/engine.rb
170
+ - lib/gutentag/generators/migration_versions_generator.rb
170
171
  - lib/gutentag/persistence.rb
171
172
  - lib/gutentag/remove_unused.rb
172
173
  - lib/gutentag/tag_names.rb
@@ -191,6 +192,7 @@ files:
191
192
  - spec/models/gutentag/tag_spec.rb
192
193
  - spec/models/gutentag/tagging_spec.rb
193
194
  - spec/spec_helper.rb
195
+ - spec/support/adjust_migrations.rb
194
196
  - spec/support/mysql.rb
195
197
  homepage: https://github.com/pat/gutentag
196
198
  licenses:
@@ -211,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
213
  - !ruby/object:Gem::Version
212
214
  version: '0'
213
215
  requirements: []
214
- rubygems_version: 3.0.3
216
+ rubygems_version: 3.1.2
215
217
  signing_key:
216
218
  specification_version: 4
217
219
  summary: Good Tags
data/.travis.yml DELETED
@@ -1,22 +0,0 @@
1
- language: ruby
2
- dist: xenial
3
- script: bundle exec appraisal rake
4
- rvm:
5
- - 2.3.8
6
- - 2.4.6
7
- - 2.5.5
8
- - 2.6.3
9
- # - jruby-9.2.8.0
10
- before_install:
11
- - gem install bundler --version 1.17.3
12
- install:
13
- - bundle _1.17.3_ install --jobs=3 --retry=3
14
- before_script:
15
- - bundle exec appraisal install
16
- env:
17
- - DATABASE=postgres
18
- - DATABASE=mysql
19
- - DATABASE=sqlite
20
- services:
21
- - mysql
22
- - postgresql