# encoding: utf-8 describe Policy::Follower do let(:test_class) { Class.new.send(:include, described_class) } subject { test_class.new } describe ".policies" do it "is a collection of policies" do expect(test_class.policies).to be_kind_of Policy::Follower::Policies end it "refers to itself" do expect(test_class.policies.follower).to eq test_class end end # describe .policies describe ".follows_policy" do it "adds a name to the collection of policies" do expect(test_class.policies).to receive(:add).with("foo") test_class.follows_policy "foo" end it "returns the name of the method" do expect(test_class.follows_policy "foo").to eq :follows_policy end end # describe .follows_policy describe ".follows_policies" do it "adds all names to the collection of policies" do expect(test_class.policies).to receive(:add).with("foo").ordered expect(test_class.policies).to receive(:add).with("bar").ordered test_class.follows_policies "foo", "bar" end it "returns the name of the method" do expect(test_class.follows_policies "foo").to eq :follows_policies end end # describe .follows_policies describe "#follow_policies?" do before { test_class.follows_policies :one, :two } context "with valid policies" do let(:one) { double valid?: true } before { allow(subject).to receive(:one) { one } } it "returns true" do expect(subject.follow_policies? :one).to eq true end end # context context "with invalid policy's name" do let(:one) { double valid?: false, errors: [] } before { allow(subject).to receive(:one) { one } } it "raises ViolationError" do expect { subject.follow_policies? :one } .to raise_error Policy::Follower::ViolationError end it "stores both the follower and policy in the exception" do begin subject.follow_policies? :one rescue => exception expect(exception.follower).to eq subject expect(exception.policy).to eq one end end end # context context "with undefined name" do it "raises NoMethodError" do expect { subject.follow_policies? :one } .to raise_error NoMethodError end end # context context "with unregistered name" do it "raises NameError" do expect { subject.follow_policies? :three } .to raise_error Policy::Follower::NameError end it "stores both the follower class and name in the exception" do begin subject.follow_policies? :three rescue => exception expect(exception.follower).to eq test_class expect(exception.name).to eq :three end end end # context context "with a list of names" do let(:one) { double valid?: true } let(:two) { double valid?: true } before { allow(subject).to receive(:one) { one } } before { allow(subject).to receive(:two) { two } } it "checks listed policies in given order" do expect(two).to receive(:valid?).ordered expect(one).to receive(:valid?).ordered subject.follow_policies? :two, :one end end # context context "without names" do let(:one) { double valid?: true } let(:two) { double valid?: true } before { allow(subject).to receive(:one) { one } } before { allow(subject).to receive(:two) { two } } it "checks listed policies in predefined order" do expect(one).to receive(:valid?).ordered expect(two).to receive(:valid?).ordered subject.follow_policies? [] end end # context end # describe #follow_policies? describe "#follow_policy?" do it "is an alias for #follow_policies?" do expect(subject).to receive(:follow_policies?).with "foo" subject.follow_policy? "foo" end end # describe #follow_policy? end # describe Policy::Follower