Skip to content

Commit

Permalink
Implement generic Cuprum::Collections::Scope.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepingkingstudios committed Jan 8, 2024
1 parent 4ecca86 commit 37e33ae
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,23 @@ module ShouldBeACriteriaScopeContract
# which the contract is applied.
# @param abstract [Boolean] if true, the scope is abstract and does not
# define a #call implementation. Defaults to false.
contract do |abstract: false|
contract do |abstract: false, constructor: true|
shared_context 'with criteria' do
let(:criteria) do
operators = Cuprum::Collections::Queries::Operators

[
['title', 'eq', 'Gideon the Ninth'],
['author', 'eq', 'Tamsyn Muir']
['title', operators::EQUAL, 'Gideon the Ninth'],
['author', operators::EQUAL, 'Tamsyn Muir']
]
end
end

let(:criteria) { [] }

describe '.new' do
next unless constructor

it 'should define the constructor' do
expect(described_class)
.to be_constructible
Expand Down
29 changes: 29 additions & 0 deletions lib/cuprum/collections/scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# frozen_string_literal: true

require 'cuprum/collections'
require 'cuprum/collections/scopes/criteria_scope'

module Cuprum::Collections
# Generic scope class for defining collection-independent criteria scopes.
class Scope < Cuprum::Collections::Scopes::CriteriaScope
# @override build(value = nil, &block)
# (see Cuprum::Collections::Scopes::Criteria::ClassMethods.build)
def self.build(...)
new(...)
end

# @override initialize(value = nil, &block)
# @param value [Hash, nil] the keys and values to parse.
#
# @return [Array] the generated criteria.
#
# @yield the query block.
#
# @yieldreturn [Hash] a Hash with String keys.
def initialize(...)
criteria = self.class.parse(...)

super(criteria: criteria)
end
end
end
7 changes: 4 additions & 3 deletions lib/cuprum/collections/scopes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
module Cuprum::Collections
# Namespace for scope functionality, which filters query data.
module Scopes
autoload :Base, 'cuprum/collections/scopes/base'
autoload :Collection, 'cuprum/collections/scopes/collection'
autoload :Criteria, 'cuprum/collections/scopes/criteria'
autoload :Base, 'cuprum/collections/scopes/base'
autoload :Collection, 'cuprum/collections/scopes/collection'
autoload :Criteria, 'cuprum/collections/scopes/criteria'
autoload :CriteriaScope, 'cuprum/collections/scopes/criteria_scope'
end
end
2 changes: 1 addition & 1 deletion lib/cuprum/collections/scopes/criteria.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def build(...)
end

# @override parse(value = nil, &block)
# (see Cuprum::Collections::Scopes::Parser#parse)
# (see Cuprum::Collections::Scopes::Criteria::Parser#parse)
def parse(*args, &block)
parser = Cuprum::Collections::Scopes::Criteria::Parser.instance

Expand Down
11 changes: 11 additions & 0 deletions lib/cuprum/collections/scopes/criteria_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

require 'cuprum/collections/scopes'
require 'cuprum/collections/scopes/base'
require 'cuprum/collections/scopes/criteria'

module Cuprum::Collections::Scopes
class CriteriaScope < Cuprum::Collections::Scopes::Base
include Cuprum::Collections::Scopes::Criteria
end
end
4 changes: 0 additions & 4 deletions spec/cuprum/collections/basic/scopes/criteria_scope_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,4 @@ def filtered_data
end
end
end

describe '#type' do
include_examples 'should define reader', :type, :criteria
end
end
38 changes: 38 additions & 0 deletions spec/cuprum/collections/scope_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require 'cuprum/collections/scope'
require 'cuprum/collections/rspec/contracts/scopes/criteria_contracts'

RSpec.describe Cuprum::Collections::Scope do
include Cuprum::Collections::RSpec::Contracts::Scopes::CriteriaContracts

subject(:scope) do
described_class.new(*constructor_args, &constructor_block)
end

let(:constructor_args) do
criteria
.to_h { |(attribute, _, value)| [attribute, value] }
.then { |hsh| [hsh] }
end
let(:constructor_block) { nil }

describe '.new' do
def parse_criteria(...)
described_class.new(...).criteria
end

it 'should define the constructor' do
expect(described_class)
.to be_constructible
.with(0..1).arguments
.and_a_block
end

include_contract 'should parse criteria'
end

include_contract 'should be a criteria scope',
abstract: true,
constructor: false
end
14 changes: 14 additions & 0 deletions spec/cuprum/collections/scopes/criteria_scope_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

require 'cuprum/collections/scopes/criteria_scope'
require 'cuprum/collections/rspec/contracts/scopes/criteria_contracts'

RSpec.describe Cuprum::Collections::Scopes::CriteriaScope do
include Cuprum::Collections::RSpec::Contracts::Scopes::CriteriaContracts

subject(:scope) { described_class.new(criteria: criteria) }

let(:criteria) { [] }

include_contract 'should be a criteria scope', abstract: true
end

0 comments on commit 37e33ae

Please sign in to comment.