__FILE__ for requiring file

J

Jim Freeze

Hello

I keep wondering if there is a way to have __FILE__ be delayed
in its evaluation. For example, in my tests cases, I usually do the
following so that my test cases are imune to where they are run from:

class TestMyClass < Test::Unit::TestCase

TEST_DIR = File.dirname(__FILE__)
DATA_DIR = File.join(TEST_DIR, "data")

def data_file(file)
File.join(DATA_DIR, file)
end

def test_xyz
open(data_file("fred"))
assert ...
end
end

The problem is I have to add this to every test case since I can't put
data_file inside a module and include it without also having o define
TEST_DIR as a constant of Object inside every testcase.

In other words, I don't want to do:

TEST_DIR = File.dirname(__FILE__)
class TestMyClass < Test::Unit::TestCase
require 'test_helper'
include TestHelper
TestHelper.init __FILE__
end

This just seems a bit verbose.

I guess what I need is something like: __REQUIRING_FILE__
so my TestHelper module could be written as:

module TestHelper
TEST_DIR = File.dirname(__REQUIRING_FILE__)
DATA_DIR = ...as above
end

Has anyone ever needed such a thing? Is there a better way of solving
this problem?

Thanks
 
R

Robert Klemme

Jim said:
Hello

I keep wondering if there is a way to have __FILE__ be delayed
in its evaluation. For example, in my tests cases, I usually do the
following so that my test cases are imune to where they are run from:

class TestMyClass < Test::Unit::TestCase

TEST_DIR = File.dirname(__FILE__)
DATA_DIR = File.join(TEST_DIR, "data")

def data_file(file)
File.join(DATA_DIR, file)
end

def test_xyz
open(data_file("fred"))
assert ...
end
end

The problem is I have to add this to every test case since I can't put
data_file inside a module and include it without also having o define
TEST_DIR as a constant of Object inside every testcase.

In other words, I don't want to do:

TEST_DIR = File.dirname(__FILE__)
class TestMyClass < Test::Unit::TestCase
require 'test_helper'
include TestHelper
TestHelper.init __FILE__
end

This just seems a bit verbose.

I guess what I need is something like: __REQUIRING_FILE__
so my TestHelper module could be written as:

module TestHelper
TEST_DIR = File.dirname(__REQUIRING_FILE__)
DATA_DIR = ...as above
end

Has anyone ever needed such a thing? Is there a better way of solving
this problem?

Thanks

Untested - just sketching ideas:

mytest.rb:

require 'test/unit'

class TC < Test::Unit::TestCase
def open_data(f,&b)
File.open(File.join(get_dir, f), &b)
end

def get_dir
x = caller(2).shift
if /^(.*):\d+:in / =~ x
File.dirname $1
else
raise "Whatever"
end
end
end


your_test.rb:

class TestFoo < TC
def test_x
open_data("foo") do |io|
io.each_line ...
end
end
end

robert
 
L

Louis J Scoras

I think this could get there:

def __REQUIRING_FILE__; caller[1] =~ /([^:]*):/; $1 end

But probably only if you don't call it within any other methods. I'll
have to play around some more.
 
R

Robert Klemme

Louis said:
I think this could get there:

def __REQUIRING_FILE__; caller[1] =~ /([^:]*):/; $1 end

But probably only if you don't call it within any other methods. I'll
have to play around some more.

I played around already :)

def find_dir
caller.each do |cl|
if %r{^(.*):\d+(?::in )?$} =~ cl
f = $1
return File.dirname(f) if f != __FILE__
end
end
raise "Not found"
end

Regards

robert
 
L

Louis J Scoras

I played around already :)

def find_dir
caller.each do |cl|
if %r{^(.*):\d+(?::in )?$} =~ cl
f = $1
return File.dirname(f) if f != __FILE__
end
end
raise "Not found"
end

Very nice.

I realized after I posted that ':' could be a valid character in a
filename, so my above try at it won't work anyway.
 
A

ara.t.howard

Hello

I keep wondering if there is a way to have __FILE__ be delayed in its
evaluation. For example, in my tests cases, I usually do the following so
that my test cases are imune to where they are run from:

you can defer the evaluation by simply using methods:


harp:~/d > cat test/test.rb
require 'test/unit'
class TestMyClass < Test::Unit::TestCase
require 'test/helper' and include TestHelper

def __file__() __FILE__ end
def test_dir() File.dirname __file__ end

def test_that_it_works()
assert_nothing_raised{ p data_file('forty-two') }
end
end


harp:~/d > cat test/helper.rb
module TestHelper
def data_dir() File.join test_dir, 'data' end
def data_file(file) File.join data_dir, file end
end


harp:~/d > ruby test/test.rb
Loaded suite test/test
Started
."test/data/forty-two"
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top