no_fly_list 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NoFlyList
4
- # This module provides functionality for a tag table that contains global tags for a model.
4
+ # This module provides functionality for a tagging table that contains tags relationship for a model.
5
5
  #
6
- # This concern can be included in models that represent tags to manage global tags across different records.
6
+ # This concern can be included in models that represent tags to manage the relationship between the tag and the model.
7
7
  #
8
8
  # @example Usage
9
- # class User::Tag < ApplicationRecord
9
+ # class User::Tagging < ApplicationRecord
10
10
  # include NoFlyList::TaggingModel
11
11
  # end
12
12
  module TaggingRecord
@@ -1,15 +1,95 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NoFlyList
4
- # = NoFlyList Test Helper
5
- #
6
- # Include <tt>NoFlyList::TestHelper</tt> in your test case to get access to the assertion methods.
7
4
  module TestHelper
5
+ # Asserts that a model class is properly set up for tagging in the given context
8
6
  def assert_taggable_record(klass, *contexts)
9
- assert klass.respond_to?(:has_tags), "#{klass} does not respond to has_tags"
10
7
  contexts.each do |context|
11
- assert klass.new.respond_to?(:"#{context}_list"), "#{klass} does not respond to #{context}_list"
8
+ assert klass._no_fly_list.tag_contexts.key?(context),
9
+ "#{klass} should have #{context} in its tag contexts"
10
+
11
+ assert_respond_to klass.new, "#{context}_list",
12
+ "#{klass} should respond to #{context}_list"
12
13
  end
13
14
  end
15
+
16
+ # Asserts that a model class has proper tagging setup for a specific context
17
+ def assert_tagging_context(klass, context, polymorphic: false)
18
+ singular_name = context.to_s.singularize
19
+
20
+ # Check the context is registered
21
+ assert klass._no_fly_list.tag_contexts.key?(context),
22
+ "#{context} is not registered as a tag context for #{klass}"
23
+
24
+ # Check configuration
25
+ context_config = klass._no_fly_list.tag_contexts[context]
26
+ assert_equal polymorphic, context_config[:polymorphic],
27
+ "#{context} should #{polymorphic ? '' : 'not '}be configured as polymorphic"
28
+
29
+ # Check tagging associations
30
+ assert_respond_to klass.new, "#{singular_name}_taggings",
31
+ "Missing taggings association for #{context}"
32
+ assert_respond_to klass.new, context,
33
+ "Missing tags association for #{context}"
34
+
35
+ # Check if correct classes exist
36
+ if polymorphic
37
+ assert_polymorphic_tag_classes_exist(klass, context)
38
+ else
39
+ assert_local_tag_classes_exist(klass, context)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def assert_polymorphic_tag_classes_exist(tags_klass, tagging_klass)
46
+ # Verify they include the correct modules
47
+ assert tags_klass.include?(NoFlyList::ApplicationTag),
48
+ 'Polymorphic Tag should include NoFlyList::ApplicationTag'
49
+ assert tagging_klass.include?(NoFlyList::ApplicationTagging),
50
+ 'Polymorphic Tagging should include NoFlyList::ApplicationTagging'
51
+ end
52
+
53
+ def assert_local_tag_classes_exist(klass, context)
54
+ context.to_s.singularize
55
+
56
+ # Check tag class exists
57
+ tag_class = "#{klass.name}Tag"
58
+ assert tag_class.safe_constantize,
59
+ "Tag class #{tag_class} should exist"
60
+
61
+ # Check tagging class exists
62
+ tagging_class = "#{klass.name}::Tagging"
63
+ assert tagging_class.safe_constantize,
64
+ "Tagging class #{tagging_class} should exist"
65
+
66
+ # Verify they include the correct modules
67
+ assert tag_class.constantize.include?(NoFlyList::TagRecord),
68
+ "#{tag_class} should include NoFlyList::TagRecord"
69
+ assert tagging_class.constantize.include?(NoFlyList::TaggingRecord),
70
+ "#{tagging_class} should include NoFlyList::TaggingRecord"
71
+ end
72
+
73
+ # Asserts that a specific record has a tag in a given context
74
+ def assert_has_tag(record, tag_name, context)
75
+ tag_list = record.send("#{context}_list")
76
+ assert_includes tag_list.to_a, tag_name,
77
+ "Expected #{record.class.name} ##{record.id} to have tag '#{tag_name}' in context '#{context}'"
78
+ end
79
+
80
+ # Asserts that a specific record does not have a tag in a given context
81
+ def assert_has_no_tag(record, tag_name, context)
82
+ tag_list = record.send("#{context}_list")
83
+ refute_includes tag_list.to_a, tag_name,
84
+ "Expected #{record.class.name} ##{record.id} to not have tag '#{tag_name}' in context '#{context}'"
85
+ end
86
+
87
+ # Asserts that a specific record has exactly the given tags in a context
88
+ def assert_has_exactly_tags(record, tags, context)
89
+ actual_tags = record.send("#{context}_list").to_a.sort
90
+ expected_tags = Array(tags).sort
91
+ assert_equal expected_tags, actual_tags,
92
+ "Expected #{record.class.name} ##{record.id} to have exactly #{expected_tags.inspect} in context '#{context}', but got #{actual_tags.inspect}"
93
+ end
14
94
  end
15
95
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NoFlyList
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/no_fly_list.rb CHANGED
@@ -6,7 +6,6 @@ require 'active_support/rails'
6
6
  require 'active_support/core_ext/numeric/time'
7
7
  require_relative 'no_fly_list/version'
8
8
  require 'no_fly_list/railtie' if defined?(Rails)
9
- require 'ostruct'
10
9
 
11
10
  module NoFlyList
12
11
  extend ActiveSupport::Autoload
@@ -16,9 +15,17 @@ module NoFlyList
16
15
 
17
16
  # Common tagging tables
18
17
  autoload :TaggableRecord
18
+
19
19
  autoload_under 'taggable_record' do
20
20
  autoload :Configuration
21
+ autoload :Config
22
+ autoload_under 'taggable_record/query' do
23
+ autoload :SqliteStrategy
24
+ autoload :MysqlStrategy
25
+ autoload :PostgresqlStrategy
26
+ end
21
27
  end
28
+
22
29
  autoload :TaggingRecord
23
30
  autoload :TagRecord
24
31
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: no_fly_list
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-06 00:00:00.000000000 Z
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '7.2'
27
- - !ruby/object:Gem::Dependency
28
- name: ostruct
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
27
  description: Tagging system for ActiveRecord models inspired by the TSA
42
28
  email:
43
29
  - terminale@gmail.com
@@ -63,9 +49,14 @@ files:
63
49
  - lib/no_fly_list/railties/tasks.rake
64
50
  - lib/no_fly_list/tag_record.rb
65
51
  - lib/no_fly_list/taggable_record.rb
52
+ - lib/no_fly_list/taggable_record/config.rb
66
53
  - lib/no_fly_list/taggable_record/configuration.rb
67
54
  - lib/no_fly_list/taggable_record/mutation.rb
68
55
  - lib/no_fly_list/taggable_record/query.rb
56
+ - lib/no_fly_list/taggable_record/query/mysql_strategy.rb
57
+ - lib/no_fly_list/taggable_record/query/postgresql_strategy.rb
58
+ - lib/no_fly_list/taggable_record/query/sqlite_strategy.rb
59
+ - lib/no_fly_list/taggable_record/tag_setup.rb
69
60
  - lib/no_fly_list/tagging_proxy.rb
70
61
  - lib/no_fly_list/tagging_record.rb
71
62
  - lib/no_fly_list/test_helper.rb