Get specs passing with latest versions of extension gems

* Get specs passing with latest versions of
    * ActiveRecord  4.0.4
    * ActiveSupport 4.0.4
    * MongoMapper   0.13.0
    * Mongoid       4.0.0
    * ActionView    4.0.4
    * Ripple seems to be abandoned so no changes made.
* Clean up ActiveRecord setup:
    * Creating tableless AR objects seems even trickier in Rails 4 so
      simplify testing setup by using an in-memory SQLite DB back-end.

Conflicts:
	spec/ext/active_record_spec.rb
This commit is contained in:
Eoin Kelly 2014-08-08 13:56:23 +12:00 committed by James Cox
parent 77ceaf5090
commit 52bffc1873
10 changed files with 491 additions and 93 deletions

1
.rspec Normal file
View File

@ -0,0 +1 @@
--color

40
Gemfile
View File

@ -1,3 +1,41 @@
source "https://rubygems.org"
source 'https://rubygems.org'
gemspec
group :development do
# ActionView extension
# ####################
gem 'actionview', '~> 4.1.4'
# ActiveSupport extension
# #######################
gem 'activesupport', '~> 4.1.4'
# ActiveRecord extension
# ######################
# * To simplify creating test models we use an in-memory SQLite DB
gem 'activerecord', '~> 4.1.4'
gem 'sqlite3'
# MongoMapper extension
# #####################
# * cannot be enabled at the same time as mongoid
# gem 'mongo_mapper', '~> 0.13.0'
# gem 'bson_ext'
# Nokogiri extension
# ##################
gem 'nokogiri', '~> 1.6.3.1'
# Ripple extension
# ################
#
# * Ripple is abandoned http://basho.com/tag/ripple-client-apis/
# * Ripple is not currently compatible with Rails 4
# gem 'ripple', '~> 0.9.5'
# Mongoid extension
# #################
# * cannot be enabled at the same time as mongo_mapper
gem 'mongoid', '~> 4.0.0'
end

View File

@ -23,7 +23,7 @@ Gem::Specification.new do |s|
s.executables = []
s.require_paths = ["lib"]
s.add_development_dependency "rspec", ">= 2.6.0"
s.add_development_dependency "rspec", ">= 3.0.0"
s.add_development_dependency "fakefs", ">= 0.2.1"
s.add_development_dependency "actionview"
s.add_development_dependency "activerecord"

View File

@ -0,0 +1,35 @@
require 'active_record'
# Establish connection to in-memory SQLite DB
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
# Create the users table
ActiveRecord::Migration.verbose = false
ActiveRecord::Migration.create_table :users do |t|
t.string :name
t.integer :rank
t.boolean :admin
t.datetime :created_at
end
# Create models
class User < ActiveRecord::Base; end
class SubUser < User; end
# Helper methods
# ##############
def activerecord_version
# ActiveRecord 4+
return ActiveRecord.version.to_s if ActiveRecord.method_defined? :version
# everything else
ActiveRecord::VERSION::STRING
end
# we only work with ActiveRecord 2+
def is_usable_activerecord?
defined?(ActiveRecord::VERSION::MAJOR) && ActiveRecord::VERSION::MAJOR >= 2
end

View File

@ -1,64 +1,10 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
begin
require 'active_record'
require 'awesome_print/ext/active_record'
require File.expand_path(File.dirname(__FILE__) + '/../active_record_helper')
module Rails
def self.env
{}
end
end
if defined?(ActiveRecord::VERSION::MAJOR) && ActiveRecord::VERSION::MAJOR >= 2
# Create tableless ActiveRecord model.
#------------------------------------------------------------------------------
class User < ActiveRecord::Base
def self.columns()
@columns ||= []
end
# Tableless model support for ActiveRecord 3.1 mess.
if self.respond_to?(:column_defaults)
def self.primary_key
:id
end
def self.column_defaults
@column_defaults ||= Hash[columns.map { |column| [column.name, nil] }]
end
def self.columns_hash
@columns_hash ||= Hash[columns.map { |column| [column.name, column] }]
end
end
def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
end
column :id, :integer
column :name, :string
column :rank, :integer
column :admin, :boolean
column :created_at, :datetime
def self.table_exists?
true
end
end
class SubUser < User
def self.columns
User.columns
end
end
class AbstractClass < ActiveRecord::Base
self.abstract_class = true
end
if is_usable_activerecord?
describe "AwesomePrint/ActiveRecord" do
before do
@ -136,9 +82,110 @@ EOS
it "display single record" do
out = @ap.send(:awesome, @diana)
if activerecord_version >= "4.1"
str = <<-EOS.strip
#<User:0x01234567
@_start_transaction_state = {},
@aggregation_cache = {},
@attributes_cache = {},
@column_types = {
"admin" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "admin",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "boolean",
attr_reader :type = :boolean
>,
"created_at" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "created_at",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "datetime",
attr_reader :type = :datetime
>,
"id" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = true,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "id",
attr_reader :null = false,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "INTEGER",
attr_reader :type = :integer
>,
"name" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = 255,
attr_reader :name = "name",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "varchar(255)",
attr_reader :type = :string
>,
"rank" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "rank",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "integer",
attr_reader :type = :integer
>
},
@column_types_override = nil,
@destroyed = false,
@marked_for_destruction = false,
@new_record = true,
@readonly = false,
@reflects_state = [
[0] false
],
@transaction_state = nil,
@txn = nil,
attr_accessor :attributes = {
"admin" => false,
"created_at" => "1992-10-10 12:30:00",
"id" => nil,
"name" => "Diana",
"rank" => 1
},
attr_accessor :destroyed_by_association = nil,
attr_reader :association_cache = {},
attr_reader :changed_attributes = {
"admin" => nil,
"created_at" => nil,
"name" => nil,
"rank" => nil
}
>
EOS
# ActiveRecord 3.1 and on.
#--------------------------------------------------------------------------
if ActiveRecord::VERSION::STRING >= "3.1"
elsif activerecord_version >= "3.1"
str = <<-EOS.strip
#<User:0x01234567
@aggregation_cache = {},
@ -168,7 +215,7 @@ EOS
EOS
# ActiveRecord 3.0.x
#--------------------------------------------------------------------------
elsif ActiveRecord::VERSION::STRING.start_with?('3.0')
elsif activerecord_version.start_with?('3.0')
str = <<-EOS.strip
#<User:0x01234567
@attributes_cache = {},
@ -193,7 +240,7 @@ EOS
EOS
# ActiveRecord 2.x
#--------------------------------------------------------------------------
elsif ActiveRecord::VERSION::STRING.start_with?('2.')
elsif activerecord_version.start_with?('2.')
str = <<-EOS.strip
#<User:0x01234567
@attributes_cache = {},
@ -220,9 +267,206 @@ EOS
it "display multiple records" do
out = @ap.send(:awesome, [ @diana, @laura ])
# ActiveRecord 3.1 and on.
#--------------------------------------------------------------------------
if ActiveRecord::VERSION::STRING >= "3.1"
if activerecord_version >= "4.1"
str = <<-EOS.strip
[
[0] #<User:0x01234567
@_start_transaction_state = {},
@aggregation_cache = {},
@attributes_cache = {},
@column_types = {
"admin" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "admin",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "boolean",
attr_reader :type = :boolean
>,
"created_at" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "created_at",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "datetime",
attr_reader :type = :datetime
>,
"id" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = true,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "id",
attr_reader :null = false,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "INTEGER",
attr_reader :type = :integer
>,
"name" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = 255,
attr_reader :name = "name",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "varchar(255)",
attr_reader :type = :string
>,
"rank" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "rank",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "integer",
attr_reader :type = :integer
>
},
@column_types_override = nil,
@destroyed = false,
@marked_for_destruction = false,
@new_record = true,
@readonly = false,
@reflects_state = [
[0] false
],
@transaction_state = nil,
@txn = nil,
attr_accessor :attributes = {
"admin" => false,
"created_at" => "1992-10-10 12:30:00",
"id" => nil,
"name" => "Diana",
"rank" => 1
},
attr_accessor :destroyed_by_association = nil,
attr_reader :association_cache = {},
attr_reader :changed_attributes = {
"admin" => nil,
"created_at" => nil,
"name" => nil,
"rank" => nil
}
>,
[1] #<User:0x01234567
@_start_transaction_state = {},
@aggregation_cache = {},
@attributes_cache = {},
@column_types = {
"admin" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "admin",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "boolean",
attr_reader :type = :boolean
>,
"created_at" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "created_at",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "datetime",
attr_reader :type = :datetime
>,
"id" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = true,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "id",
attr_reader :null = false,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "INTEGER",
attr_reader :type = :integer
>,
"name" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = 255,
attr_reader :name = "name",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "varchar(255)",
attr_reader :type = :string
>,
"rank" => #<ActiveRecord::ConnectionAdapters::SQLite3Column:0x01234567
attr_accessor :coder = nil,
attr_accessor :primary = false,
attr_reader :default = nil,
attr_reader :default_function = nil,
attr_reader :limit = nil,
attr_reader :name = "rank",
attr_reader :null = true,
attr_reader :precision = nil,
attr_reader :scale = nil,
attr_reader :sql_type = "integer",
attr_reader :type = :integer
>
},
@column_types_override = nil,
@destroyed = false,
@marked_for_destruction = false,
@new_record = true,
@readonly = false,
@reflects_state = [
[0] false
],
@transaction_state = nil,
@txn = nil,
attr_accessor :attributes = {
"admin" => true,
"created_at" => "2003-05-26 14:15:00",
"id" => nil,
"name" => "Laura",
"rank" => 2
},
attr_accessor :destroyed_by_association = nil,
attr_reader :association_cache = {},
attr_reader :changed_attributes = {
"admin" => nil,
"created_at" => nil,
"name" => nil,
"rank" => nil
}
>
]
EOS
elsif ActiveRecord::VERSION::STRING >= "3.1"
str = <<-EOS.strip
[
[0] #<User:0x01234567
@ -389,7 +633,8 @@ EOS
end
it "should print the class for non-direct subclasses of ActiveRecord::Base" do
expect(@ap.send(:awesome, SubUser)).to eq <<-EOS.strip
out = @ap.send(:awesome, SubUser)
expect(out).to eq <<-EOS.strip
class SubUser < User {
:id => :integer,
:name => :string,
@ -403,10 +648,6 @@ EOS
it "should print ActiveRecord::Base objects (ex. ancestors)" do
expect { @ap.send(:awesome, User.ancestors) }.not_to raise_error
end
it "should print an abstract class" do
expect(@ap.send(:awesome, AbstractClass)).to eq("AbstractClass(abstract) < ActiveRecord::Base")
end
end
#------------------------------------------------------------------------------
@ -416,6 +657,7 @@ EOS
end
it "should format class methods properly" do
# spec 1
out = @ap.send(:awesome, User.methods.grep(/first/))
if ActiveRecord::VERSION::STRING >= "3.2"
@ -428,15 +670,23 @@ EOS
expect(out).to match(/\sfirst\(\*arg.*?\)\s+User \(ActiveRecord::Base\)/)
end
# spec 2
out = @ap.send(:awesome, User.methods.grep(/primary_key/))
expect(out).to match(/\sprimary_key\(.*?\)\s+User/)
if activerecord_version >= "4.1"
expect(out).to match(/\sprimary_key\(.*?\)\s+Class \(ActiveRecord::AttributeMethods::PrimaryKey::ClassMethods\)/)
else
expect(out).to match(/\sprimary_key\(.*?\)\s+User/)
end
# spec 3
out = @ap.send(:awesome, User.methods.grep(/validate/))
if ActiveRecord::VERSION::MAJOR < 3
expect(out).to match(/\svalidate\(\*arg.*?\)\s+User \(ActiveRecord::Base\)/)
else
expect(out).to match(/\svalidate\(\*arg.*?\)\s+Class \(ActiveModel::Validations::ClassMethods\)/)
end
end
end
end

View File

@ -1,7 +1,7 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
begin
require 'active_support'
require 'active_support/all'
require 'awesome_print/ext/active_support'
describe "AwesomePrint::ActiveSupport" do

View File

@ -30,8 +30,90 @@ begin
it "should print class instance" do
user = MongoUser.new(:first_name => "Al", :last_name => "Capone")
out = @ap.send(:awesome, user)
str = <<-EOS.strip
out.gsub!(/#\<Proc:.+?\>/, 'AWESOME_PRINT_PROC_STUB')
out.gsub!(/BSON::ObjectId\('[\da-f]+?'\)/, "BSON::ObjectId('123456789')")
if MongoMapper::Version >= "0.13"
str = <<-EOS.strip
#<MongoUser:0x01234567
@__mm_default_keys = [
[0] #<MongoMapper::Plugins::Keys::Key:0x01234567
@dynamic = false,
@embeddable = false,
@has_default = true,
@is_id = true,
@typecast = nil,
attr_accessor :accessors = [],
attr_accessor :default = AWESOME_PRINT_PROC_STUB,
attr_accessor :ivar = :@_id,
attr_accessor :name = "_id",
attr_accessor :options = {
:default => AWESOME_PRINT_PROC_STUB
},
attr_accessor :type = ObjectId < Object
>
],
@__mm_keys = {
"_id" => #<MongoMapper::Plugins::Keys::Key:0x01234567
@dynamic = false,
@embeddable = false,
@has_default = true,
@is_id = true,
@typecast = nil,
attr_accessor :accessors = [],
attr_accessor :default = AWESOME_PRINT_PROC_STUB,
attr_accessor :ivar = :@_id,
attr_accessor :name = "_id",
attr_accessor :options = {
:default => AWESOME_PRINT_PROC_STUB
},
attr_accessor :type = ObjectId < Object
>,
"first_name" => #<MongoMapper::Plugins::Keys::Key:0x01234567
@dynamic = false,
@embeddable = false,
@has_default = false,
@is_id = false,
@typecast = nil,
attr_accessor :accessors = [],
attr_accessor :ivar = :@first_name,
attr_accessor :name = "first_name",
attr_accessor :options = {},
attr_accessor :type = String < Object
>,
"last_name" => #<MongoMapper::Plugins::Keys::Key:0x01234567
@dynamic = false,
@embeddable = false,
@has_default = false,
@is_id = false,
@typecast = nil,
attr_accessor :accessors = [],
attr_accessor :ivar = :@last_name,
attr_accessor :name = "last_name",
attr_accessor :options = {},
attr_accessor :type = String < Object
>
},
@__mm_pre_cast = {
"first_name" => "Al",
"last_name" => "Capone"
},
@_dynamic_attributes = {},
@_new = true,
attr_accessor :_id = BSON::ObjectId('123456789'),
attr_accessor :attributes = nil,
attr_accessor :first_name = "Al",
attr_accessor :last_name = "Capone",
attr_reader :changed_attributes = {
"first_name" => nil,
"last_name" => nil
}
>
EOS
else
str = <<-EOS.strip
#<MongoUser:0x01234567
@_new = true,
attr_accessor :first_name = "Al",
@ -44,6 +126,7 @@ begin
attr_reader :last_name_before_type_cast = "Capone"
>
EOS
end
out.gsub!(/0x([a-f\d]+)/, "0x01234567")
expect(out).to eq(str)
end

View File

@ -19,7 +19,7 @@ begin
Object.instance_eval{ remove_const :Chamelion }
end
before do
before do
stub_dotfile!
@ap = AwesomePrint::Inspector.new :plain => true, :sort_keys => true
end
@ -28,7 +28,7 @@ begin
user = MongoUser.new :first_name => "Al", :last_name => "Capone"
out = @ap.send :awesome, user
object_id = defined?(::Moped) ? '"424242424242424242424242"' : "BSON::ObjectId('424242424242424242424242')"
object_id = user.id.inspect
str = <<-EOS.strip
#<MongoUser:0x01234567> {
:_id => #{object_id},
@ -37,20 +37,13 @@ begin
}
EOS
out.gsub!(/0x([a-f\d]+)/, "0x01234567")
if defined?(::Moped)
out.gsub!(/:_id => \"[^"]+/, ":_id => \"424242424242424242424242")
else
out.gsub!(/Id\('[^']+/, "Id('424242424242424242424242")
end
expect(out).to eq(str)
end
it "should print the class" do
moped_or_not = defined?(::Moped) ? 'moped/' : ''
expect(@ap.send(:awesome, MongoUser)).to eq <<-EOS.strip
class MongoUser < Object {
:_id => :"#{moped_or_not}bson/object_id",
:_type => :string,
:_id => :"bson/object_id",
:first_name => :string,
:last_name => :string
}
@ -63,12 +56,10 @@ EOS
field :last_attribute
end
moped_or_not = defined?(::Moped) ? 'moped/' : ''
last_attribute = defined?(::Moped) ? 'object' : '"mongoid/fields/serializable/object"'
expect(@ap.send(:awesome, Chamelion)).to eq <<-EOS.strip
class Chamelion < Object {
:_id => :"#{moped_or_not}bson/object_id",
:_type => :string,
:_id => :"bson/object_id",
:last_attribute => :#{last_attribute}
}
EOS

View File

@ -254,11 +254,11 @@ EOS
before do
@hash = { 1 => { :sym => { "str" => { [1, 2, 3] => { { :k => :v } => Hash } } } } }
end
it "empty hash" do
expect({}.ai).to eq("{}")
end
it "plain multiline" do
expect(@hash.ai(:plain => true)).to eq <<-EOS.strip
{
@ -378,7 +378,7 @@ EOS
EOS
end
end
it "plain multiline with sorted keys" do
expect(@hash.ai(:plain => true, :sort_keys => true)).to eq <<-EOS.strip
{
@ -569,11 +569,11 @@ EOS
@struct.name = "Herman Munster"
@struct.address = "1313 Mockingbird Lane"
end
it "empty struct" do
expect(Struct.new("EmptyStruct").ai).to eq("\e[1;33mStruct::EmptyStruct < Struct\e[0m")
end
it "plain multiline" do
s1 = <<-EOS.strip
{
@ -695,7 +695,7 @@ EOS
end
my = My.new
expect(my.methods.ai(:plain => true)).not_to raise_error
expect { my.methods.ai(:plain => true) }.not_to raise_error
end
it "should handle a class defines its own #method method (ex. request.method)" do
@ -706,7 +706,7 @@ EOS
end
my = My.new
expect(my.methods.ai(:plain => true)).not_to raise_error
expect { my.methods.ai(:plain => true) }.not_to raise_error
end
end
end

View File

@ -449,7 +449,7 @@ describe "Methods arrays" do
it "appending garbage to methods array should not raise error" do
arr = 42.methods << [ :wtf ]
expect(arr.ai(:plain => true)).not_to raise_error
expect { arr.ai(:plain => true) }.not_to raise_error
if RUBY_VERSION < '1.9.2'
expect(arr.ai(:plain => true)).to match(/\s+wtf\(\?\)\s+\?/) # [ :wtf ].to_s => "wtf"
else