diff --git a/spec/rich_enums_spec.rb b/spec/rich_enums_spec.rb index 8b7cbcd..37ba0ae 100644 --- a/spec/rich_enums_spec.rb +++ b/spec/rich_enums_spec.rb @@ -1,10 +1,149 @@ +require "spec_helper" + RSpec.describe RichEnums do - it "has a version number" do - expect(RichEnums::VERSION).not_to be nil + describe "error scenarios" do + it "raises an error if the argument to rich_enum is not a Hash" do + expect do + Temping.create(:course_class) do + include RichEnums + rich_enum([]) + end + end.to raise_error(RichEnums::Error) + end + + it "raises an error if an empty Hash is passed to rich_enum" do + expect do + Temping.create(:course_class) do + include RichEnums + rich_enum({}) + end + end.to raise_error(RichEnums::Error) + end + + it "raises an error if the enum definition uses the Array form" do + # This is not supported yet + expect do + Temping.create(:course_class) do + include RichEnums + rich_enum({status: [:active, :inactive]}) + end + end.to raise_error(RichEnums::Error) + end end - it "does something useful" do - # TODO write tests - expect(false).to eq(true) + describe "rich_enum usage" do + context "it calls the ActiveRecord::Enum.enum method" do + let(:course_class) do + Temping.create(:course_class) do + with_columns do |t| + t.integer :status + t.string :category + end + + include RichEnums + end + end + + it "invokes the enum method with the correct arguments" do + allow(course_class).to receive(:enum).and_call_original + + course_class.rich_enum status: { active: 0, inactive: 1 }, alt: :name + # it passes only the necessary arguments to the enum method, stripping out the alt: option + expect(course_class).to have_received(:enum).with(status: { active: 0, inactive: 1 }) + end + + it "invokes the enum method with the correct arguments" do + allow(course_class).to receive(:enum).and_call_original + + course_class.rich_enum status: { active: [0, 'LIVE'], inactive: [1, 'NOT_LIVE'] }, alt: :name + # it passes only the necessary arguments to the enum method, + # stripping out the alternate names LIVE and NOT_LIVE and the alt: option + expect(course_class).to have_received(:enum).with(status: { active: 0, inactive: 1 }) + end + + it "invokes the enum method with the correct arguments" do + allow(course_class).to receive(:enum).and_call_original + course_class.rich_enum status: { active: [0, 'LIVE'], inactive: [1, 'NOT_LIVE'] }, _prefix: true, alt: 'state' + # it passes only the necessary arguments to the enum method, + # stripping out the alternate names LIVE and NOT_LIVE and the alt: option + expect(course_class).to have_received(:enum).with(status: { active: 0, inactive: 1 }, _prefix: true) + end + end + + context "with only an alternate name specified without additional mapping" do + let(:course_class) do + Temping.create(:course_class) do + with_columns do |t| + t.integer :status + t.string :category + end + + include RichEnums + rich_enum status: { active: 0, inactive: 1 }, alt: :name + end + end + let(:test_instance) { course_class.new } + + it "defines a class method for each enum" do + expect(course_class).to respond_to(:status_names) + end + + it "returns a hash of enum values and names" do + expect(course_class.status_names).to eq({"active"=>"active", "inactive"=>"inactive"}) + end + + it "defines an instance method for each enum" do + expect(test_instance).to respond_to(:status_name) + end + + it "returns the value in response to alternate name" do + test_instance.status = 0 + expect(test_instance.status_name).to eq(test_instance.status) + test_instance.status = 1 + expect(test_instance.status_name).to eq(test_instance.status) + test_instance.status = :active + expect(test_instance.status_name).to eq(test_instance.status) + test_instance.status = 'inactive' + expect(test_instance.status_name).to eq(test_instance.status) + end + end + + context "with an alternate name and mapping specified" do + let(:course_class) do + Temping.create(:course_class) do + with_columns do |t| + t.string :status + end + + include RichEnums + rich_enum status: { active: [0, 'LIVE'], inactive: [1, 'NOT_LIVE'] }, alt: :name + end + end + + let(:test_instance) { course_class.new } + + it "defines a class method for each enum" do + expect(course_class).to respond_to(:status_names) + end + + it "returns a hash of enum values and names" do + expect(course_class.status_names).to eq({"active"=>"LIVE", "inactive"=>"NOT_LIVE"}) + end + + it "defines an instance method for each enum" do + expect(test_instance).to respond_to(:status_name) + end + + it "returns the alternate name of the enum value" do + test_instance.status = 0 + expect(test_instance.status_name).to eq("LIVE") + test_instance.status = 1 + expect(test_instance.status_name).to eq("NOT_LIVE") + test_instance.status = :active + expect(test_instance.status_name).to eq("LIVE") + test_instance.status = 'inactive' + expect(test_instance.status_name).to eq("NOT_LIVE") + end + end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ccf0686..2a61bd0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ require "bundler/setup" require "rich_enums" +require "temping" RSpec.configure do |config| # Enable flags like --only-failures and --next-failure @@ -11,4 +12,15 @@ config.expect_with :rspec do |c| c.syntax = :expect end + + config.before(:all) do + ActiveRecord::Base.establish_connection( + adapter: "sqlite3", + database: ":memory:" + ) + end + + config.after do + Temping.teardown + end end