require "spec_helper" describe Schematic::Serializers::Xsd do before do class EmptyModel < ActiveRecord::Base def self.columns [] end end end describe ".to_xsd" do context "XSD validation" do context "when the model is not namespaced" do subject { SomeModel.to_xsd } with_model :some_model do table do |t| t.string "some_string" t.text "some_text" t.float "some_float" t.integer "some_integer" t.datetime "some_datetime" t.date "some_date" t.boolean "some_boolean" t.text "method_is_also_columns" end model do validates :some_string, :presence => true, :length => { :maximum => 100 } validates :some_text, :presence => true validates :some_date, :presence => true, :allow_blank => true validates :some_datetime, :presence => true, :allow_blank => false attr_accessor :additional_method_array class << self def xsd_methods {:foo => { :bar => { :baz => nil }, :quz => [:qaz] }, :method_is_also_columns => [:method_is_also_column], :additional_method_array => [] } end end def to_xml(options) super({:methods => [:additional_method_array]}.merge(options)) end end end it "should generate a valid XSD" do validate_xsd(subject) end it "should validate against it's own XSD" do instance = SomeModel.new(:some_string => "ExampleString", :some_date => Date.today, :some_text => "here is some text", :some_datetime => DateTime.new, :some_boolean => true, :some_float => 1.5, :method_is_also_columns => [{:some => "somevalues"}], :additional_method_array => {"somevalue" => "somekey"}, :some_integer => 2) xml = [instance].to_xml validate_xml_against_xsd(xml, subject) end end context "when the model is namespaced" do before do module Namespace; end end subject { Namespace::SomeModel.to_xsd } with_model :some_model do table do |t| t.string "some_string" end model do validates :some_string, :presence => true end end before do class Namespace::SomeModel < SomeModel end end it "should generate a valid XSD" do validate_xsd(subject) end end context "when the model has a nested attribute on a subclass with a reference to the superclass" do with_model :parent do table {} model do has_many :children accepts_nested_attributes_for :children end end with_model :child do table do |t| t.integer :parent_id end model do belongs_to :parent end end before do module Namespace; end class Namespace::Child < Child accepts_nested_attributes_for :parent end end subject { Namespace::Child.to_xsd } it "should generate a valid XSD" do validate_xsd(subject) end end context "when the model has a circular nested attribute reference" do with_model :blog do table {} model do has_many :posts accepts_nested_attributes_for :posts end end with_model :post do table do |t| t.integer :blog_id end model do belongs_to :blog accepts_nested_attributes_for :blog end end subject { Post.to_xsd } it "should generate a valid XSD" do validate_xsd(subject) end end end context "for an empty model with no attributes or validations" do subject { sanitize_xml(EmptyModel.to_xsd) } it "should return an xsd for an array of the model" do xsd = <<-XML XML subject.should == sanitize_xml(xsd) end end context "for a model with attributes" do subject { sanitize_xml(SomeModel.to_xsd) } context "for a any attribute" do with_model :some_model do table :id => false do |t| t.float 'some_float' end end it "should define the correct xsd element" do xsd = generate_xsd_for_model(SomeModel) do <<-XML XML end subject.should == xsd end end describe "additional methods" do with_model :some_model do table {} end it "should include the additional method" do xsd = generate_xsd_for_model(SomeModel) do <<-XML XML end sanitize_xml(SomeModel.to_xsd(:methods => {:foo_bar => nil})).should == xsd end end end end end