Skip to content

Commit

Permalink
Merge pull request #19 from vasilakisfil/tests/documents-lambda-asser…
Browse files Browse the repository at this point in the history
…tions

Refactor lambda tests, add complementary tests for collection options
  • Loading branch information
vasilakisfil authored Nov 10, 2018
2 parents b0a659a + 661c6b0 commit 5c692aa
Show file tree
Hide file tree
Showing 15 changed files with 1,410 additions and 10 deletions.
2 changes: 2 additions & 0 deletions lib/simple_ams/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ def embedded
class Folder < self
include Enumerable
attr_reader :members
alias collection resource

def initialize(options, embedded_options = nil)
@_options = options
@embedded_options = embedded_options
@options = @_options.collection_options

@members = options.collection
@resource = options.resource
end

def each(&block)
Expand Down
4 changes: 2 additions & 2 deletions lib/simple_ams/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def serializer_class
def collection_serializer_class
return @collection_serializer_class if defined?(@collection_serializer_class)

if serializer_class.is_a?(Proc)
if serializer_class.is_a?(Proc) #TODO: maybe we should do duck typing instead?
@collection_serializer_class = injected_options[:collection_serializer]
if @collection_serializer_class.nil?
raise "In case of a proc serializer, you need to specify a collection_serializer"
Expand Down Expand Up @@ -288,7 +288,7 @@ def _relation_options
#TODO: raise exception if both are nil!
def fetch_allowed_options
_serializer_class = self.serializer_class
if _serializer_class.is_a?(Proc)
if _serializer_class.is_a?(Proc) #TODO: maybe we should do duck typing instead?
_serializer_class = self.collection_serializer_class
end

Expand Down
2 changes: 1 addition & 1 deletion lib/simple_ams/options/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ class SimpleAMS::Options
class Adapter
include SimpleAMS::Options::Concerns::ValueHash

alias_method :klass, :value
alias :klass :value
end
end
3 changes: 1 addition & 2 deletions lib/simple_ams/options/concerns/value_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class SimpleAMS::Options
module Concerns
module ValueHash
attr_reader :value, :options
alias :name :value

def initialize(value, options = {}, resource:, serializer:)
if value.is_a?(Proc) #TODO: maybe we should do duck typing instead?
Expand All @@ -21,8 +22,6 @@ def initialize(value, options = {}, resource:, serializer:)
end
end

alias_method :name, :value

def raw
[value, options]
end
Expand Down
306 changes: 306 additions & 0 deletions spec/document/folder/collection/name_value_hash_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
require "spec_helper"

RSpec.describe SimpleAMS::Document::Folder, '(collection) name_value_hash' do
[:generic, :link, :meta, :form].map(&:to_s).each do |element|
element.send(:extend, Module.new{
def plural
"#{self.to_s}s"
end
})

describe "(#{element.plural})" do
context "with no #{element.plural} in general" do
before do
@folder = SimpleAMS::Document::Folder.new(
SimpleAMS::Options.new(User.array, {
injected_options: Helpers.random_options(with: {
serializer: UserSerializer,
}).tap{|h| h.delete(element.to_sym)}
})
)
end

describe "members" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).to eq({})
end
end
end

describe "values" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).to respond_to(:each)
document.send(element.plural).each do |field|
fail('this should never happen as fields should be empty')
end
end
end
end
end

context "with no injected #{element.plural}" do
before do
@allowed_elements = Elements.send(element.plural)
@allowed_elements.each do |el|
UserSerializer.send(element, *el.as_input)
end

@folder = SimpleAMS::Document::Folder.new(
SimpleAMS::Options.new(User.array, {
injected_options: Helpers.random_options(with: {
serializer: UserSerializer
}).tap{|h| h.delete(element.plural.to_sym)}
})
)

@uniq_allowed_elements = @allowed_elements.uniq{|el| el.name}
end

describe "members" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).not_to eq({})
end
end
end

it "returns the allowed ones" do
@folder.each do |document|
expect(document.send(element.plural).map(&:name)).to eq @uniq_allowed_elements.map(&:name)
expect(document.send(element.plural).map(&:value)).to eq @uniq_allowed_elements.map(&:value)
expect(document.send(element.plural).map(&:options)).to eq @uniq_allowed_elements.map(&:options)
end
end
end

context "with empty injected #{element.plural}" do
before do
@allowed_elements = Elements.send(element.plural)
@allowed_elements.each do |el|
UserSerializer.send(element, *el.as_input)
end

@folder = SimpleAMS::Document::Folder.new(
SimpleAMS::Options.new(User.array, {
injected_options: Helpers.random_options(with: {
serializer: UserSerializer,
element.plural.to_sym => []
})
})
)
end

describe "members" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).to(eq({}))
end
end
end

describe "values" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).to respond_to(:each)
document.send(element.plural).each do |field|
fail('this should never happen as fields should be empty')
end
end
end
end
end

context "with no allowed #{element.plural} but injected ones" do
before do
@folder = SimpleAMS::Document::Folder.new(
SimpleAMS::Options.new(User.array, {
injected_options: Helpers.random_options(with: {
serializer: UserSerializer,
})
})
)
end

describe "members" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).to eq({})
end
end
end

describe "values" do
it "returns an empty array" do
@folder.each do |document|
expect(document.send(element.plural)).to respond_to(:each)
document.send(element.plural).each do |field|
fail('this should never happen as fields should be empty')
end
end
end
end
end

context "with various injected #{element.plural}" do
before do
@allowed_elements = Elements.send(element.plural)
@allowed_elements.each do |el|
UserSerializer.send(element, *el.as_input)
end
@injected_elements = Elements.as_options_for(
Helpers.pick(@allowed_elements)
)

injected_options = Helpers.random_options(with: {
serializer: UserSerializer,
element.plural.to_sym => @injected_elements
})
@folder = SimpleAMS::Document::Folder.new(
SimpleAMS::Options.new(User.array, injected_options: injected_options)
)
end

it "holds the uniq union of injected and allowed #{element.plural}" do
@folder.each do |document|
elements_got = document.send(element.plural)
elements_expected = (Elements.as_elements_for(
@injected_elements, klass: Object.const_get("Elements::#{element.capitalize}")
) + @allowed_elements).uniq{|q| q.name}.select{|l|
@allowed_elements.map(&:name).include?(l.name) && @injected_elements.keys.include?(l.name)
}

expect(elements_got.map(&:name)).to eq(elements_expected.map(&:name))
expect(elements_got.map(&:value)).to eq(elements_expected.map(&:value))
expect(elements_got.map(&:options).count).to eq(elements_expected.map(&:options).count)
expect(elements_got.map(&:options)).to eq(elements_expected.map(&:options))
end
end
end

context "with repeated (allowed) #{element.plural}" do
before do
@allowed_elements = Elements.send(element.plural)
2.times{
@allowed_elements.each do |el|
UserSerializer.send(element, *el.as_input)
end
}
@injected_elements = Elements.as_options_for(
Helpers.pick(@allowed_elements)
)

injected_options = Helpers.random_options(with: {
serializer: UserSerializer,
element.plural.to_sym => @injected_elements
})
@folder = SimpleAMS::Document::Folder.new(
SimpleAMS::Options.new(User.array, injected_options: injected_options)
)
end

it "holds the uniq union of injected and allowed #{element.plural}" do
@folder.each do |document|
elements_got = document.send(element.plural)
_injected_elements = Elements.as_elements_for(
@injected_elements, klass: Object.const_get("Elements::#{element.capitalize}")
)

elements_expected = (_injected_elements.map(&:name) & @allowed_elements.map(&:name)).map{|name|
_injected_elements.find{|el| el.name == name}
}

expect(elements_got.map(&:name)).to eq(elements_expected.map(&:name))
expect(elements_got.map(&:value)).to eq(elements_expected.map(&:value))
expect(elements_got.map(&:options)).to eq(elements_expected.map(&:options))
end
end
end

context "with lambda" do
context "allowed #{element.plural}" do
before do
@users = User.array
@allowed_elements = [
Object.const_get("#{Elements}::#{element.capitalize}").new(
name: :user, value: ->(obj, s){
["api/v1/users/#{obj.id}", {rel: :user}]
}
),
Object.const_get("#{Elements}::#{element.capitalize}").new(
name: :root, value: "api/v1/root", options: {rel: :root}
),
]
@allowed_elements.each do |el|
UserSerializer.send(element, *el.as_input)
end

options = SimpleAMS::Options.new(@users, {
injected_options: Helpers.random_options(with: {
serializer: UserSerializer
}, without: [element.plural.to_sym])
})

@folder = SimpleAMS::Document::Folder.new(options)
end

it "holds the unwrapped #{element.plural}" do
@folder.each do |document|
expect(document.send(element.plural).count).to eq(2)

expect(document.send(element.plural).first.name).to(
eq(@allowed_elements.first.name)
)
expect(document.send(element.plural).first.value).to(
eq(@allowed_elements.first.value.call(document.resource, nil).first)
)
expect(document.send(element.plural).first.options).to(
eq(@allowed_elements.first.value.call(document.resource, nil).last)
)

expect(document.send(element.plural).map.to_a.last.name).to eq(@allowed_elements.last.name)
expect(document.send(element.plural).map.to_a.last.value).to eq(@allowed_elements.last.value)
expect(document.send(element.plural).map.to_a.last.options).to eq(@allowed_elements.last.options)
end
end
end

context "injected #{element.plural}" do
before do
@users = User.array
@allowed_elements = Elements.send(element.plural)
@allowed_elements.each do |el|
UserSerializer.send(element, *el.as_input)
end

@injected_elements = [@allowed_elements.first].inject({}) { |memo, el|
memo[el.name] = ->(obj, s){ ["/api/v1/#{obj.id}/#{el.name}", rel: el.name] }
memo
}

options = SimpleAMS::Options.new(@users, {
injected_options: Helpers.random_options(with: {
serializer: UserSerializer,
element.plural.to_sym => @injected_elements
})
})

@folder = SimpleAMS::Document::Folder.new(options)
end

it "holds the injected lambda #{element.plural}" do
@folder.each do |document|
expect(document.send(element.plural).count).to eq(@injected_elements.count)

document.send(element.plural).each do |el|
expect(el.name).to eq(@injected_elements.find{|l| l.first == el.name}[0])
expect(el.value).to eq(@injected_elements[el.name].call(document.resource, nil).first)
end
end
end
end
end
end
end
end
Loading

0 comments on commit 5c692aa

Please sign in to comment.