Skip to content
Browse files

cleanup, no more global namespace pollution, specs and readme

  • Loading branch information...
1 parent b389bb7 commit 6bfce886f081ae61785968fd3faa69b8e0ff4c5c grosser committed Dec 26, 2008
View
20 README.markdown 100644 → 100755
@@ -1,12 +1,13 @@
PROBLEM
=======
- fixtures are not maintainable
- - validation change, code breaks
+ - validation change, tests/code breaks
- forms need to be filled with valid attributes
SOLUTION
========
+(for RSpec and Test::Unit)
- simple and robust validation testing `User.email expected to be invalid when set to <xx@yy>`
- create a valid record without fixtures
- create edge-case records without fixtures
@@ -15,16 +16,27 @@ SOLUTION
INSTALL
=======
-Fill the test/fixtures/valid/valid.yml with 1 valid set of attributes per model
-(can be attr_protected/not attr_accessible)
+Fill the test/valid_attributes.yml with 1 valid set of attributes per model
+(can be attr_protected or not-attr_accessible)
Example:
user:
name: Hans
login: hand
address_id: 1
-
+When using Rspec: add to `spec/spec_helper.rb`:
+
+ Spec::Runner.configure do |config|
+ ...
+ config.include(ValidAttributes)
+ ...
+ end
+
+When using `Test::Unit`: add to `test/test_helper.rb`
+
+ include ValidAttributes
+
USAGE
=====
- `assert_invalid_attributes(User, :email=>[nil,'s','@','asd@sdf'], :name=>[nil,'x','admin'])`
View
12 Rakefile.rb
@@ -0,0 +1,12 @@
+require 'rubygems'
+require 'spec'
+
+desc 'Default: run spec.'
+task :default => :spec
+
+desc "Run all specs in spec directory"
+task :spec do |t|
+ options = "--colour --format progress --loadby --reverse"
+ files = FileList['spec/**/*_spec.rb']
+ system("spec #{options} #{files}")
+end
View
0 init.rb 100644 → 100755
File mode changed.
View
0 install.rb 100644 → 100755
File mode changed.
View
95 lib/valid_attributes.rb 100644 → 100755
@@ -1,60 +1,61 @@
-#create a valid new record
-#attributes are set separetly(no mass-assignment)
-#valid User or valid 'user' or valid User, :name=>'Peter'
-def valid(type,attributes={})
- record = type.to_s.camelcase.constantize.new
- valid_attributes(type.to_s.underscore).merge(attributes).each do |k,v|
- record.send("#{k}=",v)
+module ValidAttributes
+ # create a valid new record
+ # attributes are set separetly(no mass-assignment)
+ # valid User or valid 'user' or valid User, :name=>'Peter'
+ def valid(type,attributes={})
+ klas = type.to_s.camelcase.constantize
+ record = klas.new
+ valid_attributes(klas.to_s.underscore).merge(attributes).each do |field,value|
+ record.send("#{field}=",value)
+ end
+ record
end
- record
-end
-
-def create_valid(type,attributes={})
- record = valid(type,attributes)
- record.save!
- record
-end
-def valid_attributes(record_name,attributes={})
- Grosser::Valid.load_valid_attributes(record_name).merge(attributes.to_options)
-end
+ def create_valid(type,attributes={})
+ record = valid(type,attributes)
+ record.save!
+ record
+ end
-#example: User, :login=>['',nil,'admin'], :email=>['',nil,'aa','@','a@','@a']
-def assert_invalid_attributes(model_class, attributes)
- attributes.each_pair do |attribute, value|
- assert_invalid_value model_class, attribute, value
+ def valid_attributes(record_name,attributes={})
+ ValidAttributesHelper.valid_attributes(record_name).merge(attributes.to_options)
end
-end
-#example: User, :login, ['',nil,'admin']
-def assert_invalid_value(model_class, attribute, value)
- if value.kind_of? Array
- value.each { |v| assert_invalid_value model_class, attribute, v }
- else
- record = valid model_class
- record.send(attribute.to_s+'=',value)
- assert_block "<#{model_class}.#{attribute}> expected to be invalid when set to <#{value}>" do
- record.valid? # Must be called to generate the errors
- record.errors.invalid? attribute
+ #example: User, :login=>['',nil,'admin'], :email=>['',nil,'aa','@','a@','@a']
+ def assert_invalid_attributes(model_class, attributes)
+ attributes.each_pair do |attribute, value|
+ assert_invalid_value model_class, attribute, value
end
end
-end
-module Grosser
- class Valid
- def self.load_valid_attributes(record_name)
- name = record_name.to_s.underscore
- @@valid_attributes ||= YAML::load_file(path_to_valid_yml)
- begin
- attrs = @@valid_attributes[name].to_options!
- rescue
- raise "attributes for #{name} not found! --> valid.yml"
+ #example: User, :login, ['',nil,'admin']
+ def assert_invalid_value(klas, attribute, values)
+ [*values].each do |value|
+ record = valid klas
+ record.send(attribute.to_s+'=',value)
+ assert_block "<#{klas}.#{attribute}> expected to be invalid when set to <#{value}>" do
+ record.valid? # Must be called to generate the errors
+ record.errors.invalid? attribute
end
- attrs
end
-
- def self.path_to_valid_yml
- File.join(RAILS_ROOT,'test','fixtures','valid','valid.yml')
+ end
+end
+
+class ValidAttributesHelper
+ cattr_accessor :stored_valid_attributes
+
+ def self.valid_attributes(record_name)
+ name = record_name.to_s.underscore
+ self.stored_valid_attributes ||= YAML::load_file(path_to_valid_yml)
+ begin
+ attrs = stored_valid_attributes[name].to_options!
+ rescue
+ raise "attributes for #{name} not found! --> #{path_to_valid_yml}"
end
+ attrs
+ end
+
+ def self.path_to_valid_yml
+ File.join(RAILS_ROOT,'test','valid_attributes.yml')
end
end
View
18 spec/setup_test_model.rb
@@ -0,0 +1,18 @@
+require 'rubygems'
+require 'active_record'
+
+#create model table
+ActiveRecord::Schema.define(:version => 1) do
+ create_table "users" do |t|
+ t.string "name"
+ t.integer "age"
+ t.boolean "ugly"
+ t.timestamps
+ end
+end
+
+#create model
+class User < ActiveRecord::Base
+ validates_presence_of :name
+ attr_accessible :name, :age
+end
View
46 spec/spec_helper.rb
@@ -0,0 +1,46 @@
+# ---- requirements
+require 'rubygems'
+require 'spec'
+require 'mocha'
+
+#strip_tags
+require 'actionpack'
+require 'action_controller'
+
+$LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
+
+
+# ---- rspec
+Spec::Runner.configure do |config|
+ config.mock_with :mocha
+end
+
+
+# ---- bugfix
+#`exit?': undefined method `run?' for Test::Unit:Module (NoMethodError)
+#can be solved with require test/unit but this will result in extra test-output
+module Test
+ module Unit
+ def self.run?
+ true
+ end
+ end
+end
+
+# ---- load active record
+require 'active_record'
+
+
+RAILS_ENV = "test"
+ActiveRecord::Base.configurations = {"test" => {
+ :adapter => "sqlite3",
+ :database => ":memory:",
+}.with_indifferent_access}
+
+ActiveRecord::Base.logger = Logger.new(File.directory?("log") ? "log/#{RAILS_ENV}.log" : "/dev/null")
+ActiveRecord::Base.establish_connection(:test)
+
+
+# ---- setup environment/plugin
+require File.expand_path("../init", File.dirname(__FILE__))
+load File.expand_path("setup_test_model.rb", File.dirname(__FILE__))
View
4 spec/valid_attributes.yml
@@ -0,0 +1,4 @@
+user:
+ name: Hans
+ age: 11
+ ugly: true
View
104 spec/valid_attributes_spec.rb
@@ -0,0 +1,104 @@
+require File.expand_path("spec_helper", File.dirname(__FILE__))
+
+VALID_ATTRIBUTES_YML = File.join(File.dirname(__FILE__),'valid_attributes.yml')
+ValidAttributesHelper.stored_valid_attributes = YAML.load(IO.read(VALID_ATTRIBUTES_YML))
+
+include ValidAttributes
+
+def preserving_rails_root
+ temp = defined?(RAILS_ROOT) ? RAILS_ROOT : nil
+ yield
+ const_set('RAILS_ROOT',temp) if temp
+end
+
+describe :path_to_valid_yml do
+ it "builds depending on RAILS_ROOT" do
+ preserving_rails_root do
+ RAILS_ROOT='xxx'
+ ValidAttributesHelper.path_to_valid_yml.should == 'xxx/test/valid_attributes.yml'
+ end
+ end
+end
+
+describe :valid_attributes do
+ it "loads from valid_attributes.yml" do
+ ValidAttributesHelper.stored_valid_attributes = nil
+ ValidAttributesHelper.expects(:path_to_valid_yml).returns VALID_ATTRIBUTES_YML
+ ValidAttributesHelper.valid_attributes(User)[:name].should == 'Hans'
+ end
+ it "uses the given stored attributes" do
+ valid_attributes(:user)[:name].should == 'Hans'
+ end
+ it "can use String and Symbol" do
+ valid_attributes('user')[:name].should == 'Hans'
+ valid_attributes(User)[:name].should == 'Hans'
+ end
+ it "merges the given attributes" do
+ valid_attributes(User,:name=>'Peter')[:name].should == 'Peter'
+ end
+end
+
+describe :valid do
+ it "creates a new record with all(even not-accessible) attributes" do
+ user = valid User
+ valid_attributes(User).each do |field,value|
+ user.send(field).should == value
+ end
+ end
+ it "can use String or Symbol" do
+ valid('user').attributes.should == valid(User).attributes
+ valid(:user).attributes.should == valid(User).attributes
+ end
+ it "adds given set of attributes(even not-accessible)" do
+ changed = {:age=>valid_attributes(User)[:age] + 10,:ugly=>!valid_attributes(User)[:ugly]}
+ user = valid User, changed
+ changed.each do |field,value|
+ user.send(field).should == value
+ end
+ end
+end
+
+describe :create_valid do
+ it "creates a valid record" do
+ user = create_valid User
+ user.name.should == 'Hans'
+ user.should_not be_new_record
+ end
+ it "passes values to valid" do
+ expects(:valid).with(User,:age=>123).returns User.new(:name=>'Peter')
+ create_valid(User,:age=>123)
+ end
+end
+
+describe :assert_invalid_value do
+ class VATestException < Exception
+ end
+
+ def assert_block(text)
+ raise VATestException.new("failed") unless yield
+ end
+
+ it "passes for single invalid value" do
+ assert_invalid_value(User,:name,nil)
+ end
+ it "passes for multiple invalid values" do
+ assert_invalid_value(User,:name,[nil,''])
+ end
+ it "fails for multiple valid value" do
+ lambda{assert_invalid_value(User,:name,[nil,'Hans'])}.should raise_error(VATestException)
+ end
+ it "builds a readable failure message" do
+ expects(:assert_block).with do |text|
+ text == '<User.name> expected to be invalid when set to <>'
+ end
+ assert_invalid_value(User,:name,nil)
+ end
+end
+
+describe :assert_invalid_attributes do
+ it "calls assert_invalid_value for each set" do
+ expects(:assert_invalid_value).with(User,:name,['Hans',nil])
+ expects(:assert_invalid_value).with(User,:age,11)
+ assert_invalid_attributes(User,:name=>['Hans',nil],:age=>11)
+ end
+end

0 comments on commit 6bfce88

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