passing a method as a paramter

S

Sarah Allen

I'm probably missing some basic Ruby syntax, but I'm relatively new to
Ruby and can't figure this out from the various references I've looked
at

I'd like to use this nifty test helper:

# Calls creation_method with nil values for field_names and asserts
that
# the resulting object was not saved and that errors were added for
that field.
#
# assert_required_fields :create_article, :subject, :body, :author
def assert_required_fields(creation_method, *field_names)
field_names.each do |field|
record = send(creation_method, field => nil)
assert_equal false, record.valid?
assert_not_nil record.errors.on(field)
end
end

However, I don't know how to pass the creation method. My basic test
would be:

def test_should_create_user
user = User.create:)email => "(e-mail address removed)", :lastname => "jones",
:password => "secret");
assert user.valid?, "User was invalid:\n#{user.to_yaml}"
end

I tried this for the failure case...
def test_should_not_create_user_unless_default_fields
assert_required_fields User::create, :email, :lastname, :password
end

But that reports an error:
1) Error:
test_should_not_create_user_unless_default_fields(UserTest):
TypeError: #<User uuid: nil, firstname: nil, lastname: nil, login: nil,
email: nil, ...> is not a symbol

Can someone advise me of the correct syntax?

Thanks,
Sarah
 
L

Leo

=A0 =A0 assert_required_fields User::create, :email, :lastname, :password

Instead of User::create, which doesn't return the method as it would
in some other languages but calls it right away, you could use either
one of:

User.method:)create)
lambda {|*args| User.create(*args)}

HTH
 
S

Sarah Allen

Hi Leo,

This gave me the same error:
assert_required_fields User.method:)create), :email, :lastname,
:password

I got a different error with this:
assert_required_fields {|*args| User.create(*args)}, :email, :lastname,
:password

test/unit/user_test.rb:15: syntax error, unexpected ',', expecting kEND
assert_required_fields {|*args| User.create(*args)}, :email,
:lastname, :password

Am I missing something?

Thanks,
Sarah
 
M

Michael Fellinger

I'm probably missing some basic Ruby syntax, but I'm relatively new to
Ruby and can't figure this out from the various references I've looked
at

I'd like to use this nifty test helper:

=C2=A0# Calls creation_method with nil values for field_names and asserts
that
=C2=A0# the resulting object was not saved and that errors were added for
that field.
=C2=A0#
=C2=A0# =C2=A0assert_required_fields :create_article, :subject, :body, :a= uthor
=C2=A0def assert_required_fields(creation_method, *field_names)
=C2=A0 =C2=A0field_names.each do |field|
=C2=A0 =C2=A0 =C2=A0record =3D send(creation_method, field =3D> nil)
=C2=A0 =C2=A0 =C2=A0assert_equal false, record.valid?
=C2=A0 =C2=A0 =C2=A0assert_not_nil record.errors.on(field)
=C2=A0 =C2=A0end
=C2=A0end

## Using blocks:

def assert_required_fields(*field_names, &block)
field_names.each do |field_name|
record =3D yield(field_name =3D> nil)
assert_equal(false, record.valid?)
assert_not_nil(record.errors.on(field)
end
end

# Usage:
assert_required_fields:)email, :lastname, :password){|field|
User::create(field) }


## Using the method itself

def assert_required_fields(method, *field_names)
field_names.each do |field_name|
record =3D method.call(field_name =3D> nil)
assert_equal(false, record.valid?)
assert_not_nil(record.errors.on(field)
end
end

# Usage
assert_required_fields(User.method:)create), :email, :lastname, :password)


## Using send
def assert_required_fields(obj, method, *field_names)
field_names.each do |field_name|
record =3D obj.send(method, field_name =3D> nil)
assert_equal(false, record.valid?)
assert_not_nil(record.errors.on(field)
end
end

# Usage
assert_required_fields(User, :create, :email, :lastname, :password)


^ manveru
 
S

Sarah Allen

Wow. Awesome run through of various Ruby syntax options -- I think I'll
print that out and hang it on my wall. Oddly none of those match the
original definition which uses send but has just a single
"creation_method" parameter...

Any thoughts on how that could be called?

Thanks,
Sarah
 
M

Michael Fellinger

Wow. =C2=A0Awesome run through of various Ruby syntax options -- I think = I'll
print that out and hang it on my wall. =C2=A0Oddly none of those match th= e
original definition which uses send but has just a single
"creation_method" parameter...


Any thoughts on how that could be called?

It's the second example, you cannot obtain an instance of Method like
you would do in Python or JavaScript by simply omitting the
parenthesis, you have to use the Object#method method.

All of these are equivalent:

User.create
User.create()
User.method:)create).call
User.send:)create)

^ manveru
 
S

Sarah Allen

Michael said:
It's the second example, you cannot obtain an instance of Method like
you would do in Python or JavaScript by simply omitting the
parenthesis, you have to use the Object#method method.

All of these are equivalent:

User.create
User.create()
User.method:)create).call
User.send:)create)

^ manveru

I get the error: (ActiveRecord::Base).create> is not a symbol
calling:
assert_required_fields User.method:)create), :create, :email,
:lastname, :password

the code in my library uses send, not call

Of course, I could just change the definition of assert_required_fields,
but since it is part of a plugin
(http://topfunky.net/svn/plugins/topfunky_power_tools/lib/topfunky/test_helper.rb
), I figure there must be some standard way to call it

Thanks for your help,
Sarah
 
M

Michael Fellinger

I get the error: (ActiveRecord::Base).create> is not a symbol
calling:
=C2=A0assert_required_fields User.method:)create), :create, :email,
:lastname, :password

Sorry, with rails all bets on normally behaving ruby code are off.

^ manveru
 
R

Rick DeNatale

[Note: parts of this message were removed to make it a legal post.]

I get the error: (ActiveRecord::Base).create> is not a symbol
calling:
assert_required_fields User.method:)create), :create, :email,
:lastname, :password

the code in my library uses send, not call

Of course, I could just change the definition of assert_required_fields,
but since it is part of a plugin
(
http://topfunky.net/svn/plugins/topfunky_power_tools/lib/topfunky/test_helper.rb
), I figure there must be some standard way to call it


Yes, you need to pass a symbol, just as the error is trying to tell you:

def test_should_not_create_user_unless_default_fields
assert_required_fields :create, :email, :lastname, :password
end

I'm assuming that this is in the unit test for the User model.


--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 
S

Sarah Allen

Rick said:
Yes, you need to pass a symbol, just as the error is trying to tell you:

def test_should_not_create_user_unless_default_fields
assert_required_fields :create, :email, :lastname, :password
end

I'm assuming that this is in the unit test for the User model.

So, how would it magically know to call create on User and not some
other class? as I might expect, I get this error:

1) Error:
test_should_not_create_user_unless_default_fields(UserTest):
NoMethodError: undefined method `create' for #<UserTest:0x1e93a58>


Thanks,
Sarah:w
 
R

Rick DeNatale

[Note: parts of this message were removed to make it a legal post.]

So, how would it magically know to call create on User and not some
other class? as I might expect, I get this error:

1) Error:
test_should_not_create_user_unless_default_fields(UserTest):
NoMethodError: undefined method `create' for #<UserTest:0x1e93a58>

Okay, I'm curious where you found the topfunky power tools plugin. There's
not much that google reveals about the usage.

However, it appears to come from a very early Peepcode screen cast on Test
First Design (Peepcode #4 to be exact). I did a quick look at the
screencast and it depends on having helper method called ceate in the test
case. So you should have something like:

class UserTest < Test::Unit::TestCase
#...
def test_should_not_create_user_unless_default_fields
assert_required_fields :create, :email, :lastname, :password
end

private
def create(options={})
User.create({
:email => "(e-mail address removed)",
:last_name => "jones",
:password => "secret"
}.merge(options)
)
end
end

The create method creates a valid record, and the assert_required_fields
nils out each field asserted to be required, calls the create method with
that field set to nil and ensures that the resulting record has an error on
that field.

And given that helper method, the other test can be re-written as:

def test_should_create_user
user = create
assert user.valid?, "User was invalid:\n#{user.to_yaml}"
end

Now, as I say, this plugin doesn't seem to be very popular based on a google
search, and it's rather old. There are probably more 'modern' approaches to
testing required field validations these days using Test::Unit tests in
Rails, I'm not as up on that as I tend to use RSpec rather than Test::Unit.

And since this really IS a Rails question, it probably would have gotten a
better response, quicker if it had been submitted ot the ruby on rails
mailing list.
--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
 
G

Gary Wright

Okay, I'm curious where you found the topfunky power tools plugin.
There's
not much that google reveals about the usage.

However, it appears to come from a very early Peepcode screen cast
on Test
First Design (Peepcode #4 to be exact). I did a quick look at the
screencast and it depends on having helper method called ceate in
the test
case. So you should have something like:

Wow. +10 to Rick for his google-ruby-rails-test-unit-mentoring-fu

Gary Wright
 
S

Sarah Allen

Rick said:
Okay, I'm curious where you found the topfunky power tools plugin.
There's not much that google reveals about the usage.

I'm just getting into TDD. I experimented with cucumber a bit and really
liked it, but I'm diving into an old codebase with lots of pre-existing
unit tests. I wanted to understand the basics, so (as you guessed) I
bought the peepcode tutorial.
Now, as I say, this plugin doesn't seem to be very popular based on a
google search, and it's rather old. There are probably more 'modern'
approaches to
testing required field validations these days using Test::Unit tests in
Rails, I'm not as up on that as I tend to use RSpec rather than
Test::Unit.

If its wisdom is out of date, is there another resource you recommend?
Or is everyone just skipping unit tests these days in favor of the BDD
tools?
And since this really IS a Rails question, it probably would have gotten
a better response, quicker if it had been submitted ot the ruby on rails
mailing list.

Yeah, I see that in retrospect -- seemed like a basic language question
at the time. Thanks so much for digging in and letting me know the
scoop, which I clearly didn't fully understand from the screencast. Of
course, now I know four ways to pass a method as a parameter, which is
fabulous.

Cheers,
Sarah
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top