Skip to content

Instantly share code, notes, and snippets.

@namutaka
Created November 18, 2010 15:58
Show Gist options
  • Save namutaka/705173 to your computer and use it in GitHub Desktop.
Save namutaka/705173 to your computer and use it in GitHub Desktop.
ActiveLdap用 Fixture
#
# ActiveLdap Fixture
#
# class TestCase
# include ActiveLdap::TestLdapFixture
# self.ldap_fixture_path = "#{RAILS_ROOT}/test/fixtures/ldap"
# end
#
# class HogeTest < TestCase
# ldap_fixtures :people
# end
class LdapFixture < Fixture
def find
if model_class
model_class.find(self[model_class.dn_attribute])
else
raise FixtureClassNotFound, "No class attached to find."
end
end
end
class LdapFixtures < Fixtures
def self.create_fixture(fixture_directory, fixture_names, class_names = {})
fixture_map = {}
fixtures_list = fixture_names.map do |fixture_name|
fixture_map[fixture_name] = LdapFixtures.new(fixture_name, class_names[fixture_name],
File.join(fixture_directory, fixture_name))
end
fixtures_list.reverse.each { |fixtures| fixtures.delete_fixtures }
fixtures_list.each { |fixtures| fixtures.insert_fixtures }
fixtures = fixture_map.values_at(*fixture_names)
fixtures.size > 1 ? fixtures : fixtures.first
end
attr_reader :fixture_name
alias :name :fixture_name
def initialize(fixture_name, class_name, fixture_path)
@fixture_name = fixture_name
@class_name = class_name || fixture_name.camelize
@fixture_path = fixture_path
read_fixture_files
end
def insert_fixtures
# allow a standard key to be used for doing defaults in YAML
if is_a?(Hash)
delete('DEFAULTS')
else
delete(assoc('DEFAULTS'))
end
each do |name, fixture|
instance = model_class.new(Hash[fixture])
instance.save false
end
end
def delete_fixtures
each do |name, fixture|
begin
fixture.find.delete
rescue ActiveLdap::EntryNotFound => e
# DO NOTHING
end
end
end
private
def read_yaml_fixture_files
yaml_string = ""
Dir["#{@fixture_path}/**/*.yml"].select { |f| test(?f, f) }.each do |subfixture_path|
yaml_string << IO.read(subfixture_path)
end
yaml_string << IO.read(yaml_file_path)
if yaml = parse_yaml_string(yaml_string)
# If the file is an ordered map, extract its children.
yaml_value =
if yaml.respond_to?(:type_id) && yaml.respond_to?(:value)
yaml.value
else
[yaml]
end
yaml_value.each do |fixture|
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{fixture}" unless fixture.respond_to?(:each)
fixture.each do |name, data|
unless data
raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
end
self[name] = LdapFixture.new(data, model_class, @connection)
end
end
end
end
def read_csv_fixture_files
reader = CSV.parse(erb_render(IO.read(csv_file_path)))
header = reader.shift
i = 0
reader.each do |row|
data = {}
row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip }
self["#{@class_name.to_s.underscore}_#{i+=1}"] = LdapFixture.new(data, model_class, @connection)
end
end
end
module ActiveLdap
module TestLdapFixture
def self.included(base)
base.class_eval do
setup :setup_ldap_fixtures
teardown :teardown_ldap_fixtures
superclass_delegating_accessor :ldap_fixture_path
superclass_delegating_accessor :ldap_fixture_names
superclass_delegating_accessor :ldap_fixture_class_names
self.ldap_fixture_names = []
self.ldap_fixture_class_names = {}
end
base.extend ClassMethods
end
module ClassMethods
def set_ldap_fixture_class(class_names = {})
self.ldap_fixture_class_names = self.ldap_fixture_class_names.merge(class_names)
end
def ldap_fixtures(*table_names)
if table_names.first == :all
table_names = Dir["#{ldap_fixture_path}/*.yml"] + Dir["#{ldap_fixture_path}/*.csv"]
table_names.map! { |f| File.basename(f).split('.')[0..-2].join('.') }
else
table_names = table_names.flatten.map { |n| n.to_s }
end
self.ldap_fixture_names |= table_names
setup_ldap_fixture_accessors(table_names)
end
def setup_ldap_fixture_accessors(table_names = nil)
table_names = [table_names] if table_names && !table_names.respond_to?(:each)
(table_names || ldap_fixture_names).each do |table_name|
define_method(table_name) do |*fixtures|
force_reload = fixtures.pop if fixtures.last == true || fixtures.last == :reload
@fixture_ldap_cache[table_name] ||= {}
instances = fixtures.map do |fixture|
@fixture_ldap_cache[table_name].delete(fixture) if force_reload
if @loaded_ldap_fixtures[table_name][fixture.to_s]
@fixture_ldap_cache[table_name][fixture] ||= @loaded_ldap_fixtures[table_name][fixture.to_s].find
else
raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
end
end
instances.size == 1 ? instances.first : instances
end
private table_name
end
end
end
def setup_ldap_fixtures
return unless defined?(ActiveLdap) && !ActiveLdap::Base.configurations.blank?
@fixture_ldap_cache = {}
load_ldap_fixtures
end
def teardown_ldap_fixtures
return unless defined?(ActiveLdap) && !ActiveLdap::Base.configurations.blank?
@loaded_ldap_fixtures.values.each do |fixtures|
fixtures.delete_fixtures
end
end
private
def load_ldap_fixtures
@loaded_ldap_fixtures = {}
fixtures = LdapFixtures.create_fixture(self.class.ldap_fixture_path,
ldap_fixture_names, ldap_fixture_class_names)
unless fixtures.nil?
if fixtures.instance_of?(Fixtures)
@loaded_ldap_fixtures[fixtures.name] = fixtures
else
fixtures.each { |f| @loaded_ldap_fixtures[f.name] = f }
end
end
end
end
end
#
# Ldap Fixture rake task
#
namespace :ldap do
namespace :fixtures do
desc 'Load Ldap fixtures.'
task :load => :environment do
require 'ldap_fixtures'
base_dir = File.join(Rails.root, 'test', 'fixtures')
fixtures_dir = ENV['FIXTURES_DIR'] ?
File.join(base_dir, ENV['FIXTURES_DIR']) : File.join(base_dir, 'ldap')
class_names = {'people' => People, 'group' => Group}
( ENV['FIXTURES'] ?
ENV['FIXTURES'].split(/,/).map {|f| File.join(fixtures_dir, f) } :
Dir.glob(File.join(fixtures_dir, '*.{yml,csv}')) ).each do |fixture_file|
fixture_name = File.basename(fixture_file, '.*')
if loadable?(class_names[fixture_name.to_sym])
Fixtures.create_fixtures(File.dirname(fixture_file), fixture_name, class_names)
end
end
end
def loadable?(model_class)
return true unless model_class and model_class < ActiveLdap::Base
if model_class.base.parent.to_s ==
ActiveLdap::Base.configurations['production']['bind_dn']
puts "Execute in development or test env : #{model_class.name}."
return false
end
return true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment