require 'rubygems'
require 'bacon'
#Bacon.summary_on_exit
F = ::File
D = ::Dir
ROOT = F.dirname(__FILE__)+'/..'
$:.unshift(ROOT+'/lib')
require 'sequel'
::Sequel::Model.plugin :crushyform
DB = ::Sequel.sqlite
class Haiku < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :title, :crushyform=>{:type=>:custom, :name=>'Nice Title'}
text :body
Boolean :published
foreign_key :author_id, :authors
foreign_key :season_id, :crushyform=>{:type=>:string}
end
create_table unless table_exists?
many_to_one :author
many_to_one :season
one_to_many :reviews
def validate
errors[:title] << "is not good"
errors[:title] << "smells like shit"
end
end
class Author < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :name
String :surname
end
create_table unless table_exists?
one_to_many :haikus
end
Author.create(:name=>'Ray',:surname=>'Bradbury')
Author.create(:name=>'Jorge Luis',:surname=>'Borges')
DB.create_table :reviews do
primary_key :id
String :title
text :body
Integer :rate
foreign_key :haiku_id, :haikus
end
class Review < ::Sequel::Model
many_to_one :haiku
end
class Season < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :name
end
create_table unless table_exists?
one_to_many :haikus
end
class TestDateTime < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
Date :birth
time :meeting
DateTime :when
DateTime :created_at
DateTime :updated_at
end
create_table unless table_exists?
end
class ShippingAddress < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
text :address_body
String :postcode
String :city
end
create_table unless table_exists?
end
ShippingAddress.create(:address_body=>"3 Mulholland Drive\n\rFlat C", :postcode=>'90210', :city=>'Richville')
class Profile < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :fave_lang, :crushyform=>{:type=>:select,:select_options=>['ruby', 'forth', 'asm']}
String :fave_os, :crushyform=>{:type=>:select,:select_options=>[['GNU/Linux','sucker'], ['FreeBSD','saner'], ['Mac OSX','wanker'], ['Windows','loser']]}
String :fave_editor, :crushyform=>{:type=>:select,:select_options=>:editor_list}
String :fave_error, :crushyform=>{:type=>:select,:select_options=>:error_list}
Fixnum :fave_number, :crushyform=>{:type=>:select,:select_options=>[0,1,2,3,4,5,6,7,8,9]}
end
create_table unless table_exists?
def editor_list; ['emacs','vi','ed','sam']; end
end
Profile.create(:fave_lang=>'forth', :fave_os=>'saner', :fave_editor=>'ed', :fave_number=>3)
require 'stash_magic'
class Attached < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :filename, :crushyform=>{:type=>:attachment}
String :filesize, :crushyform=>{:type=>:none}
String :filetype, :crushyform=>{:type=>:none}
String :map, :crushyform=>{:type=>:attachment}
end
create_table unless table_exists?
::StashMagic.with_public_root ROOT+'/test'
end
class Pic < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :name
String :image, :crushyform=>{:type=>:attachment}
end
create_table unless table_exists?
end
class WithAccronymYMCAName < ::Sequel::Model; end
DB.create_table :mismatches do
primary_key :id
String :title
text :body
end
class Mismatch < ::Sequel::Model
plugin :schema
set_schema do
primary_key :id
String :title
end
end
# ========
# = Test =
# ========
describe 'Crushyform when schema plugin is not used' do
should 'have a correct default crushyform_schema' do
Review.default_crushyform_schema.should=={
:id => {:type=>:integer},
:title => {:type=>:string},
:body => {:type=>:text},
:rate => {:type=>:integer},
:haiku_id => {:type=>:parent}
}
end
should 'build the default crushyform_schema on the first query' do
Review.respond_to?(:schema).should==false
Review.crushyform_schema.should==Review.default_crushyform_schema
end
should 'have an updatable crushyform_schema' do
Review.crushyform_schema[:body][:type] = :custom
Review.crushyform_schema.should.not==Review.default_crushyform_schema
Review.crushyform_schema[:body][:type] = :text
end
end
describe 'Crushyform when schema plugin is used' do
should 'use schema declaration for building the default crushyform_schema' do
Haiku.default_crushyform_schema.should=={
:id => {:type=>:integer},
:title => {:type=>:custom,:name=>'Nice Title'},
:body => {:type=>:text},
:published => {:type=>:boolean},
:author_id => {:type=>:parent},
:season_id => {:type=>:string}
}
end
should 'not raise when there is a database column that is not in @schema' do
Mismatch.default_crushyform_schema.should=={
:title=>{:type=>:string},
:id=>{:type=>:integer},
:body=>{:type=>:text}
}
end
end
describe 'Crushyform miscellaneous helpers' do
should 'know its crushyform version' do
Haiku.crushyform_version.size.should==3
end
should 'have a human readable name' do
WithAccronymYMCAName.human_name.should=='With Accronym YMCA Name'
end
should 'have a correct default crushyid' do
ShippingAddress.new.crushyid_for(:address_body).should=='new-ShippingAddress-address_body'
ShippingAddress.first.crushyid_for(:address_body).should=='1-ShippingAddress-address_body'
end
should 'not mark texts as type :string, but :text' do
Haiku.db_schema[:body][:type].should==:string
Haiku.crushyform_schema[:body][:type].should==:text
end
should 'guess label columns using a list of common column names' do
Haiku.label_column.should==:title
Author.label_column.should==:surname # Respect order of search
end
should 'set Model::label_column' do
TestDateTime.label_column.should==nil
TestDateTime.label_column = :birth
TestDateTime.label_column.should==:birth
TestDateTime.label_column = nil
end
should 'have a shortcut for dataset only with columns relevant for building a dropdown' do
a = Author.label_dataset.first
a.surname.should=='Bradbury'
a.name.should==nil
end
should 'have a label based on Model::label_column' do
Author.first.to_label.should=='Bradbury'
Author.new.to_label.should=='New Author'
end
should 'Have a fallback label when label_column is nil' do
ShippingAddress.first.to_label.should=="Shipping Address 1"
ShippingAddress.new.to_label.should=="New Shipping Address"
end
should 'avoid line breaks if label column is a multiline field' do
ShippingAddress.label_column = :address_body
ShippingAddress.first.to_label.should=="3 Mulholland Drive Flat C"
end
should 'build correct dropdowns' do
options = Author.to_dropdown(1)
options.lines.count.should==3
options.should.match(/