1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
|
require 'spec_helper'
describe Bogus::CopiesClasses do
module SampleMethods
def foo
end
def bar(x)
end
def baz(x, *y)
end
def bam(opts = {})
end
def baa(x, &block)
end
end
shared_examples_for 'the copied class' do
it "copies methods with no arguments" do
expect(subject).to respond_to(:foo)
subject.foo
end
it "copies methods with explicit arguments" do
expect(subject).to respond_to(:bar)
expect(subject.method(:bar).arity).to eq 1
subject.bar('hello')
end
it "copies methods with variable arguments" do
expect(subject).to respond_to(:baz)
subject.baz('hello', 'foo', 'bar', 'baz')
end
it "copies methods with default arguments" do
expect(subject).to respond_to(:bam)
subject.bam
subject.bam(hello: 'world')
end
it "copies methods with block arguments" do
expect(subject).to respond_to(:baa)
subject.baa('hello')
subject.baa('hello') {}
end
end
let(:copies_classes) { Bogus.inject.copies_classes }
let(:fake_class) { copies_classes.copy(klass) }
let(:fake) { fake_class.new }
class FooWithInstanceMethods
CONST = "the const"
include SampleMethods
end
context "nested constants" do
let(:klass) { FooWithInstanceMethods }
it "does not overwrite nested constants" do
expect(fake_class::CONST).to eq "the const"
end
end
context "instance methods" do
let(:klass) { FooWithInstanceMethods }
subject{ fake }
it_behaves_like 'the copied class'
end
context "constructors" do
let(:klass) {
Class.new do
def initialize(hello)
end
def foo
end
end
}
it "adds a no-arg constructor" do
instance = fake_class.__create__
expect(instance).to respond_to(:foo)
end
it "adds a constructor that allows passing the correct number of arguments" do
instance = fake_class.new('hello')
expect(instance).to respond_to(:foo)
end
end
class ClassWithClassMethods
extend SampleMethods
end
context "class methods" do
let(:klass) { ClassWithClassMethods }
subject{ fake_class }
it_behaves_like 'the copied class'
end
context "identification" do
module SomeModule
class SomeClass
end
end
let(:klass) { SomeModule::SomeClass }
it "should copy the class name" do
expect(fake.class.name).to eq 'SomeModule::SomeClass'
end
it "should override kind_of?" do
expect(fake.kind_of?(SomeModule::SomeClass)).to be_true
end
it "should override instance_of?" do
expect(fake.instance_of?(SomeModule::SomeClass)).to be_true
end
it "should override is_a?" do
expect(fake.is_a?(SomeModule::SomeClass)).to be_true
end
it "should include class name in the output of fake's class #to_s" do
expect(fake.class.to_s).to include(klass.name)
end
it "should include class name in the output of fake's #to_s" do
expect(fake.to_s).to include(klass.name)
end
it 'should override ===' do
expect(SomeModule::SomeClass === fake).to be_true
end
end
shared_examples_for 'spying' do
def should_record(method, *args)
mock(subject).__record__(method, *args)
subject.send(method, *args)
end
it "records method calls with no arguments" do
should_record(:foo)
end
it "records method calls with explicit arguments" do
should_record(:bar, 'hello')
end
it "records method calls with variable arguments" do
should_record(:baz, 'hello', 'foo', 'bar', 'baz')
end
it "records method calls with default arguments" do
should_record(:bam, hello: 'world')
end
end
context "spying on an instance" do
let(:klass) { FooWithInstanceMethods }
subject{ fake }
include_examples 'spying'
end
context "spying on copied class" do
let(:klass) { ClassWithClassMethods }
subject { fake_class }
include_examples 'spying'
end
class SomeModel
def save(*)
# ignores arguments
end
end
context "copying classes with methods with nameless parameters" do
let(:klass) { SomeModel }
it "copies those methods" do
expect(fake).to respond_to(:save)
end
end
end
|