Skip to content
Browse files

get ready for testing with rspec and cucumber

  • Loading branch information...
1 parent cdac37d commit d20c21cb2d8233e0bf6a8b4154a2ac95d3eff98e @btelles committed
View
BIN .Gemfile.swp
Binary file not shown.
View
3 .gitignore
@@ -0,0 +1,3 @@
+*.swp
+debug.log
+*.db
View
3 features/step_definitions/web_steps.rb
@@ -21,9 +21,6 @@ def with_scope(locator)
visit path_to(page_name)
end
-Given /^An? existing report with "([^"]*)" "([^"]*)"/ do |property, value|
- @report = Report.make(property.to_sym => value)
-end
When /^(?:|I )go to (.+)$/ do |page_name|
visit path_to(page_name)
end
View
54 features/support/debug.log
@@ -0,0 +1,54 @@
+# Logfile created on Tue Oct 12 23:23:25 -0400 2010 by logger.rb
+ SQL (0.2ms) select sqlite_version(*)
+ SQL (0.2ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (87.3ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "full_name" varchar(255), "email" varchar(255), "amount" decimal(10,2)) 
+ SQL (0.1ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (82.5ms) CREATE TABLE "articles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "content" varchar(255), "person_id" integer) 
+ SQL (0.1ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (79.5ms) CREATE TABLE "vehicles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "year" integer, "model" varchar(255), "make" varchar(255), "person_id" integer) 
+ SQL (0.1ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (52.5ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL) 
+ SQL (0.0ms) PRAGMA index_list("schema_migrations")
+ SQL (79.2ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
+ SQL (0.1ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (0.0ms) SELECT version FROM "schema_migrations"
+ SQL (91.2ms) INSERT INTO "schema_migrations" (version) VALUES ('1')
+ SQL (0.2ms) select sqlite_version(*)
+ SQL (0.3ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (111.9ms) DROP TABLE "users"
+ SQL (83.1ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "full_name" varchar(255), "email" varchar(255), "amount" decimal(10,2))
+ SQL (0.1ms)  SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (82.9ms) DROP TABLE "articles"
+ SQL (91.5ms) CREATE TABLE "articles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "content" varchar(255), "person_id" integer) 
+ SQL (0.1ms) SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (87.3ms) DROP TABLE "vehicles"
+ SQL (74.8ms) CREATE TABLE "vehicles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "year" integer, "model" varchar(255), "make" varchar(255), "person_id" integer)
+ SQL (0.1ms)  SELECT name
+ FROM sqlite_master
+ WHERE type = 'table' AND NOT name = 'sqlite_sequence'
+
+ SQL (0.1ms) SELECT version FROM "schema_migrations"
View
210 lib/flag_shih_tzu.rb
@@ -0,0 +1,210 @@
+module FlagShihTzu
+ TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'] # taken from ActiveRecord::ConnectionAdapters::Column
+ DEFAULT_COLUMN_NAME = 'flags'
+
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ class IncorrectFlagColumnException < Exception; end
+ class NoSuchFlagQueryModeException < Exception; end
+ class NoSuchFlagException < Exception; end
+
+ module ClassMethods
+ def has_flags(*args)
+ flag_hash, opts = parse_options(*args)
+ opts = {
+ :named_scopes => true,
+ :column => DEFAULT_COLUMN_NAME,
+ :flag_query_mode => :in_list
+ }.update(opts)
+ colmn = opts[:column]
+
+ return unless check_flag_column(colmn)
+
+ # options are stored in a class level hash and apply per-column
+ class_inheritable_hash :flag_options
+ write_inheritable_attribute(:flag_options, {}) if flag_options.nil?
+ flag_options[colmn] = opts
+
+ # the mappings are stored in this class level hash and apply per-column
+ class_inheritable_hash :flag_mapping
+ write_inheritable_attribute(:flag_mapping, {}) if flag_mapping.nil?
+ flag_mapping[colmn] ||= {}
+
+ flag_hash.each do |flag_key, flag_name|
+ raise ArgumentError, "has_flags: flag keys should be positive integers, and #{flag_key} is not" unless is_valid_flag_key(flag_key)
+ raise ArgumentError, "has_flags: flag names should be symbols, and #{flag_name} is not" unless is_valid_flag_name(flag_name)
+ next if flag_mapping[colmn][flag_name] & (1 << (flag_key - 1)) # next if already methods defined by flagshitzu
+ raise ArgumentError, "has_flags: flag name #{flag_name} already defined, please choose different name" if method_defined?(flag_name)
+
+ flag_mapping[colmn][flag_name] = 1 << (flag_key - 1)
+
+ class_eval <<-EVAL
+ def #{flag_name}
+ flag_enabled?(:#{flag_name}, '#{colmn}')
+ end
+
+ def #{flag_name}?
+ flag_enabled?(:#{flag_name}, '#{colmn}')
+ end
+
+ def #{flag_name}=(value)
+ FlagShihTzu::TRUE_VALUES.include?(value) ? enable_flag(:#{flag_name}, '#{colmn}') : disable_flag(:#{flag_name}, '#{colmn}')
+ end
+
+ def self.#{flag_name}_condition(options = {})
+ sql_condition_for_flag(:#{flag_name}, '#{colmn}', true, options[:table_alias] || self.table_name)
+ end
+
+ def self.not_#{flag_name}_condition
+ sql_condition_for_flag(:#{flag_name}, '#{colmn}', false)
+ end
+ EVAL
+
+ # Define the named scopes if the user wants them and AR supports it
+ if flag_options[colmn][:named_scopes] && respond_to?(named_scope_method)
+ class_eval <<-EVAL
+ #{named_scope_method} :#{flag_name}, lambda { { :conditions => #{flag_name}_condition } }
+ #{named_scope_method} :not_#{flag_name}, lambda { { :conditions => not_#{flag_name}_condition } }
+ EVAL
+ end
+ end
+
+ end
+
+ def check_flag(flag, colmn)
+ raise ArgumentError, "Column name '#{colmn}' for flag '#{flag}' is not a string" unless colmn.is_a?(String)
+ raise ArgumentError, "Invalid flag '#{flag}'" if flag_mapping[colmn].nil? || !flag_mapping[colmn].include?(flag)
+ end
+
+ private
+
+ def parse_options(*args)
+ options = args.shift
+ if args.size >= 1
+ add_options = args.shift
+ else
+ add_options = options.keys.select {|key| !key.is_a?(Fixnum)}.inject({}) do |hash, key|
+ hash[key] = options.delete(key)
+ hash
+ end
+ end
+ return options, add_options
+ end
+
+ def check_flag_column(colmn, table_name = self.table_name)
+ # If you aren't using ActiveRecord (eg. you are outside rails) then do not fail here
+ # If you are using ActiveRecord then you only want to check for the table if the table exists so it won't fail pre-migration
+ has_ar = !!defined?(ActiveRecord) && self.respond_to?(:descends_from_active_record?)
+ # Supposedly Rails 2.3 takes care of this, but this precaution is needed for backwards compatibility
+ has_table = has_ar ? ActiveRecord::Base.connection.tables.include?(table_name) : true
+
+ logger.warn("Error: Table '#{table_name}' doesn't exist") and return false unless has_table
+
+ if !has_ar || (has_ar && has_table)
+ if found_column = columns.find {|column| column.name == colmn}
+ raise IncorrectFlagColumnException, "Warning: Column '#{colmn}'must be of type integer in order to use FlagShihTzu" unless found_column.type == :integer
+ else
+ # Do not raise an exception since the migration to add the flags column might still be pending
+ logger.warn("Warning: Table '#{table_name}' must have an integer column named '#{colmn}' in order to use FlagShihTzu") and return false
+ end
+ end
+
+ true
+ end
+
+ def sql_condition_for_flag(flag, colmn, enabled = true, table_name = self.table_name)
+ check_flag(flag, colmn)
+
+ if flag_options[colmn][:flag_query_mode] == :bit_operator
+ # use & bit operator directly in the SQL query.
+ # This has the drawback of not using an index on the flags colum.
+ "(#{table_name}.#{colmn} & #{flag_mapping[colmn][flag]} = #{enabled ? flag_mapping[colmn][flag] : 0})"
+ elsif flag_options[colmn][:flag_query_mode] == :in_list
+ # use IN() operator in the SQL query.
+ # This has the drawback of becoming a big query when you have lots of flags.
+ neg = enabled ? "" : "not "
+ "(#{table_name}.#{colmn} #{neg}in (#{sql_in_for_flag(flag, colmn).join(',')}))"
+ else
+ raise NoSuchFlagQueryModeException
+ end
+ end
+
+ # returns an array of integers suitable for a SQL IN statement.
+ def sql_in_for_flag(flag, colmn)
+ val = flag_mapping[colmn][flag]
+ num = 2 ** flag_mapping[flag_options[colmn][:column]].length
+ (1..num).select {|i| i & val == val}
+ end
+
+ def is_valid_flag_key(flag_key)
+ flag_key > 0 && flag_key == flag_key.to_i
+ end
+
+ def is_valid_flag_name(flag_name)
+ flag_name.is_a?(Symbol)
+ end
+
+ # Returns the correct method to create a named scope.
+ # Use to prevent deprecation notices on Rails 3 when using +named_scope+ instead of +scope+.
+ def named_scope_method
+ # Can't use respond_to because both AR 2 and 3 respond to both +scope+ and +named_scope+.
+ ActiveRecord::VERSION::MAJOR == 2 ? :named_scope : :scope
+ end
+ end
+
+ # Performs the bitwise operation so the flag will return +true+.
+ def enable_flag(flag, colmn = nil)
+ colmn = determine_flag_colmn_for(flag) if colmn.nil?
+ self.class.check_flag(flag, colmn)
+
+ set_flags(self.flags(colmn) | self.class.flag_mapping[colmn][flag], colmn)
+ end
+
+ # Performs the bitwise operation so the flag will return +false+.
+ def disable_flag(flag, colmn = nil)
+ colmn = determine_flag_colmn_for(flag) if colmn.nil?
+ self.class.check_flag(flag, colmn)
+
+ set_flags(self.flags(colmn) & ~self.class.flag_mapping[colmn][flag], colmn)
+ end
+
+ def flag_enabled?(flag, colmn = nil)
+ colmn = determine_flag_colmn_for(flag) if colmn.nil?
+ self.class.check_flag(flag, colmn)
+
+ get_bit_for(flag, colmn) == 0 ? false : true
+ end
+
+ def flag_disabled?(flag, colmn = nil)
+ colmn = determine_flag_colmn_for(flag) if colmn.nil?
+ self.class.check_flag(flag, colmn)
+
+ !flag_enabled?(flag, colmn)
+ end
+
+ def flags(colmn = DEFAULT_COLUMN_NAME)
+ self[colmn] || 0
+ end
+
+ def set_flags(value, colmn)
+ self[colmn] = value
+ end
+
+ private
+
+ def get_bit_for(flag, colmn)
+ self.flags(colmn) & self.class.flag_mapping[colmn][flag]
+ end
+
+ def determine_flag_colmn_for(flag)
+ return DEFAULT_COLUMN_NAME if self.class.flag_mapping.nil?
+ self.class.flag_mapping.each_pair do |colmn, mapping|
+ return colmn if mapping.include?(flag)
+ end
+ raise NoSuchFlagException.new("determine_flag_colmn_for: Couldn't determine column for your flags!")
+ end
+
+end
+
View
2 lib/granular_permissions.rb
@@ -1 +1,3 @@
# GranularPermissions
+
+require 'flag_shih_tzu'
View
4 spec/database.yml
@@ -1,4 +1,4 @@
sqlite3:
:adapter: sqlite3
- :dbfile: vendor/plugins/reporter/spec/db/granular_permissions_plugin.sqlite3.db
- :database: vendor/plugins/reporter/spec/db/granular_permissions_plugin.sqlite3.db
+ :dbfile: vendor/plugins/granular_permissions/spec/db/granular_permissions_plugin.sqlite3.db
+ :database: vendor/plugins/granular_permissions/spec/db/granular_permissions_plugin.sqlite3.db
View
0 spec/db/ gem 'sqlite3-ruby', :require => 'sqlite3'
No changes.
View
BIN spec/db/granular_permissions_plugin.sqlite3.db
Binary file not shown.

0 comments on commit d20c21c

Please sign in to comment.
Something went wrong with that request. Please try again.