amberframework / granite

ORM Model with Adapters for mysql, pg, sqlite in the Crystal Language.
MIT License
296 stars 87 forks source link

Support for fixtures #163

Open spicybackend opened 6 years ago

spicybackend commented 6 years ago

It would be great to have fixture support (similar to Rails' ActiveRecord::Fixtures) that allows for clean spec setup and scenarios.

robacarp commented 6 years ago

@yumoose thanks for the suggestion.

Until Granite/Amber gets a solution to this, I'd like to propose a solution to this problem which is reasonably easy to configure and extend, and doesn't obfuscate quite like fixtures do.

Create a class called Generate which contains a few class methods which can be used as helpers to quickly generate model instances:

class Generate
  def self.address
    Address.new.tap do |a|
      a.first_name = "Elwin"
      a.last_name = "Ransom"
      a.street_1 = "1 Malacandra Street"
      a.street_2 = "Hyoi's Water Dwelling n1"
      a.city = "Malacandra"

      a.country = Country.usa
      a.province = a.country.provinces.sample
      a.postal_code = '80019'
    end
  end
end

Require this in your test helper file, and then in a test you can do stuff like this:

# create an address with default test data
address = Generate.address

# insert an address into the database
Generate.address.save

# override attributes for an instance
address = Generate.address.tap do |a|
  a.country = "The Shire"
end

# create a helper method which overrides attributes and persists the object
def frodos_address
  Generate.address.tap do |a|
    a.country = "The Shire"
    a.first_name = "Frodo"
    a.last_name = "Baggins"
  end
end

# and use that in a spec
describe "addresses" do
  context "with a country" do
    it "does stuff" do
      frodos_address.should be_an Address
    end
  end
end

This is an application of a pattern I've used in Ruby projects many times and documented as a gist. I'm sure that a few of the metaprogrammy concepts won't translate directly to crystal, but with a little tinkering it wouldn't be hard to come up with a reasonable library.

Blacksmoke16 commented 6 years ago

Once #253 gets merged it could be doable with JSON files. Read JSON/array of JSON from file and instantiate a model with given JSON values.

EDIT: Could also use YAML after #255 ;)

Blacksmoke16 commented 5 years ago

We should have a discussion on how this should work before we/I get too far into the weeds. Currently I have a simple YAML version working, similar to AR.

However, @robacarp had a different approach, similar to his example earlier. @yumoose @drujensen Think we can reach a good pattern on how to set this up?

spicybackend commented 5 years ago

I like @robacarp's generator approach, though this also requires supporting code for each model which can be a bit more of a hassle than static fixture sets for simple models that don't need too much configuration for their use in tests.

I'd personally love something similar to ActiveRecord using YAML files, but that's just what I'm used to. Both choices or a mix would be great for different situations as required.