All Projects → Casecommons → With_model

Casecommons / With_model

Licence: mit
Dynamically build an Active Record model (with table) within a test context

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to With model

bdd
Given/When/Then/And/But output to RSpec and Minitest
Stars: ✭ 33 (-72.27%)
Mutual labels:  rspec, minitest
factory bot-preload
Preload factories (factory_bot) just like fixtures. It will be easy and, probably, faster!
Stars: ✭ 68 (-42.86%)
Mutual labels:  rspec, minitest
capybara select2
Capybara helpers for https://select2.org select box (supports Select2 version 2/3/4)
Stars: ✭ 48 (-59.66%)
Mutual labels:  rspec, minitest
Action Cable Testing
Action Cable testing utils
Stars: ✭ 192 (+61.34%)
Mutual labels:  rspec, minitest
Fabrication
This project has moved to GitLab! Please check there for the latest updates.
Stars: ✭ 1,017 (+754.62%)
Mutual labels:  activerecord, rspec
Still life
Rails upgrade's best friend
Stars: ✭ 213 (+78.99%)
Mutual labels:  rspec, minitest
LocalSupport
A directory of local support services and volunteer opportunities
Stars: ✭ 60 (-49.58%)
Mutual labels:  activerecord, rspec
knapsack pro-ruby
Knapsack Pro gem splits tests across parallel CI nodes and makes sure that tests will run in optimal time on each node.
Stars: ✭ 101 (-15.13%)
Mutual labels:  rspec, minitest
Aruba
Test command-line applications with Cucumber-Ruby, RSpec or Minitest. The most up to date documentation can be found on Cucumber.Pro (https://app.cucumber.pro/projects/aruba)
Stars: ✭ 900 (+656.3%)
Mutual labels:  rspec, minitest
Knapsack
Knapsack splits tests evenly across parallel CI nodes to run fast CI build and save you time.
Stars: ✭ 430 (+261.34%)
Mutual labels:  rspec, minitest
Factory trace
Simple tool to maintain factories and traits from FactoryBot
Stars: ✭ 184 (+54.62%)
Mutual labels:  rspec, minitest
Email Spec
Collection of RSpec/MiniTest matchers and Cucumber steps for testing email in a ruby app using ActionMailer or Pony
Stars: ✭ 1,142 (+859.66%)
Mutual labels:  rspec, minitest
Mutant
Automated code reviews via mutation testing - semantic code coverage.
Stars: ✭ 1,794 (+1407.56%)
Mutual labels:  rspec, minitest
Rantly
Ruby Imperative Random Data Generator and Quickcheck
Stars: ✭ 241 (+102.52%)
Mutual labels:  rspec, minitest
Lurker
📖 The ultimate tool for documenting and testing APIs in Rails
Stars: ✭ 120 (+0.84%)
Mutual labels:  rspec, minitest
N plus one control
RSpec and Minitest matchers to prevent N+1 queries problem
Stars: ✭ 345 (+189.92%)
Mutual labels:  rspec, minitest
Vscode Ruby Test Adapter
A Ruby test adapter extension for the VS Code Test Explorer
Stars: ✭ 50 (-57.98%)
Mutual labels:  rspec, minitest
Fake ftp
A fake FTP server for use with ruby tests
Stars: ✭ 77 (-35.29%)
Mutual labels:  rspec, minitest
Active record replica
Redirect ActiveRecord (Rails) reads to replica databases while ensuring all writes go to the primary database.
Stars: ✭ 96 (-19.33%)
Mutual labels:  activerecord
Counter culture
Turbo-charged counter caches for your Rails app.
Stars: ✭ 1,397 (+1073.95%)
Mutual labels:  activerecord

with_model

Gem Version Build Status API Documentation

with_model dynamically builds an ActiveRecord model (with table) before each test in a group and destroys it afterwards.

Development status

with_model is actively maintained. It is quite stable, so while updates may appear infrequent, it is only because none are needed.

Installation

Install as usual: gem install with_model or add gem 'with_model' to your Gemfile. See .travis.yml for supported (tested) Ruby versions.

RSpec

Extend WithModel into RSpec:

require 'with_model'

RSpec.configure do |config|
  config.extend WithModel
end

minitest/spec

Extend WithModel into minitest/spec:

require 'with_model'

class Minitest::Spec
  extend WithModel
end

Usage

After setting up as above, call with_model and inside its block pass it a table block and a model block.

require 'spec_helper'

describe "A blog post" do
  module MyModule; end

  with_model :BlogPost do
    # The table block (and an options hash) is passed to ActiveRecord migration’s `create_table`.
    table do |t|
      t.string :title
      t.timestamps null: false
    end

    # The model block is the ActiveRecord model’s class body.
    model do
      include MyModule
      has_many :comments
      validates_presence_of :title

      def self.some_class_method
        'chunky'
      end

      def some_instance_method
        'bacon'
      end
    end
  end

  # with_model classes can have associations.
  with_model :Comment do
    table do |t|
      t.string :text
      t.belongs_to :blog_post
      t.timestamps null: false
    end

    model do
      belongs_to :blog_post
    end
  end

  it "can be accessed as a constant" do
    expect(BlogPost).to be
  end

  it "has the module" do
    expect(BlogPost.include?(MyModule)).to eq true
  end

  it "has the class method" do
    expect(BlogPost.some_class_method).to eq 'chunky'
  end

  it "has the instance method" do
    expect(BlogPost.new.some_instance_method).to eq 'bacon'
  end

  it "can do all the things a regular model can" do
    record = BlogPost.new
    expect(record).to_not be_valid
    record.title = "foo"
    expect(record).to be_valid
    expect(record.save).to eq true
    expect(record.reload).to eq record
    record.comments.create!(:text => "Lorem ipsum")
    expect(record.comments.count).to eq 1
  end

  # with_model classes can have inheritance.
  class Car < ActiveRecord::Base
    self.abstract_class = true
  end

  with_model :Ford, superclass: Car do
  end

  it "has a specified superclass" do
    expect(Ford < Car).to eq true
  end
end

describe "with_model can be run within RSpec :all hook" do
  with_model :BlogPost, scope: :all do
    table do |t|
      t.string :title
    end
  end

  before :all do
    BlogPost.create # without scope: :all these will fail
  end

  it "has been initialized within before(:all)" do
    expect(BlogPost.count).to eq 1
  end
end

describe "another example group" do
  it "does not have the constant anymore" do
    expect(defined?(BlogPost)).to be_falsy
  end
end

describe "with table options" do
  with_model :WithOptions do
    table :id => false do |t|
      t.string 'foo'
      t.timestamps null: false
    end
  end

  it "respects the additional options" do
    expect(WithOptions.columns.map(&:name)).to_not include("id")
  end
end

Requirements

See the gemspec metadata for dependency requirements. RSpec and minitest are indirect dependencies, and with_model should support any maintained version of both.

Thread-safety

  • A unique table name is used for tables generated via with_model/WithModel::Model.new. This allows with_model (when limited to this API) to run concurrently (in processes or threads) with a single database schema. While there is a possibility of collision, it is very small.
  • A user-supplied table name is used for tables generated via with_table/WithModel::Table.new. This may cause collisions at runtime if tests are run concurrently against a single database schema, unless the caller takes care to ensure the table names passed as arguments are unique across threads/processes.
  • Generated models are created in stubbed constants, which are global; no guarantee is made to the uniqueness of a constant, and this may be unsafe.
  • Generated classes are ActiveRecord subclasses:
    • This library makes no guarantee is made as to the thread-safety of creating ActiveRecord subclasses concurrently.
    • This library makes no guarantee is made as to the thread-safety of cleaning up ActiveRecord/ActiveSupport’s internals which are polluted upon class creation.

In general, with_model is not guaranteed to be thread-safe, but is, in certain usages, safe to use concurrently across multiple processes with a single database schema.

Versioning

with_model uses Semantic Versioning 2.0.0.

License

Copyright © 2010–2018 Case Commons, Inc. Licensed under the MIT license, see LICENSE file.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].