gitlab-org--gitlab-foss/spec/lib/gitlab/patch/prependable_spec.rb
Lin Jen-Shin 07da8f9128 Preserve prepend semantics for Ruby
However we still want to make ClassMethods work!

And we'll need to fix codes using the wrong include/prepend
along the way. There were a lot of misuses.
2018-09-11 18:45:49 +08:00

190 lines
3.5 KiB
Ruby

# frozen_string_literal: true
require 'fast_spec_helper'
# Patching ActiveSupport::Concern
require_relative '../../../../config/initializers/0_as_concern'
describe Gitlab::Patch::Prependable do
let(:prepended_modules) { [] }
let(:ee) do
# So that block in Module.new could see them
prepended_modules_ = prepended_modules
Module.new do
extend ActiveSupport::Concern
class_methods do
def class_name
super.tr('C', 'E')
end
end
this = self
prepended do
prepended_modules_ << [self, this]
end
def name
super.tr('c', 'e')
end
end
end
let(:ce) do
prepended_modules_ = prepended_modules
ee_ = ee
Module.new do
extend ActiveSupport::Concern
prepend ee_
class_methods do
def class_name
'CE'
end
end
this = self
prepended do
prepended_modules_ << [self, this]
end
def name
'ce'
end
end
end
describe 'a class including a concern prepending a concern' do
subject { Class.new.include(ce) }
it 'returns values from prepended module ee' do
expect(subject.new.name).to eq('ee')
expect(subject.class_name).to eq('EE')
end
it 'prepends only once' do
ce.prepend(ee)
ce.prepend(ee)
subject
expect(prepended_modules).to eq([[ce, ee]])
end
context 'overriding a method' do
before do
subject.module_eval do
def self.class_name
'Custom'
end
def name
'custom'
end
end
end
it 'returns values from the class' do
expect(subject.new.name).to eq('custom')
expect(subject.class_name).to eq('Custom')
end
end
end
describe 'a class prepending a concern prepending a concern' do
subject { Class.new.prepend(ce) }
it 'returns values from prepended module ee' do
expect(subject.new.name).to eq('ee')
expect(subject.class_name).to eq('EE')
end
it 'prepends only once' do
subject.prepend(ce)
expect(prepended_modules).to eq([[ce, ee], [subject, ce]])
end
end
describe 'a class prepending a concern' do
subject do
ee_ = ee
Class.new do
prepend ee_
def self.class_name
'CE'
end
def name
'ce'
end
end
end
it 'returns values from prepended module ee' do
expect(subject.new.name).to eq('ee')
expect(subject.class_name).to eq('EE')
end
it 'prepends only once' do
subject.prepend(ee)
expect(prepended_modules).to eq([[subject, ee]])
end
end
describe 'simple case' do
subject do
foo_ = foo
Class.new do
prepend foo_
def value
10
end
end
end
let(:foo) do
Module.new do
extend ActiveSupport::Concern
prepended do
def self.class_value
20
end
end
def value
super * 10
end
end
end
context 'class methods' do
it "has a method" do
expect(subject).to respond_to(:class_value)
end
it 'can execute a method' do
expect(subject.class_value).to eq(20)
end
end
context 'instance methods' do
it "has a method" do
expect(subject.new).to respond_to(:value)
end
it 'chains a method execution' do
expect(subject.new.value).to eq(100)
end
end
end
end