Skip to content

Commit

Permalink
implementing attribute conversion (not yet feature-complete, some mis…
Browse files Browse the repository at this point in the history
…sing specs)
  • Loading branch information
ianwhite committed Aug 25, 2010
1 parent f6c6027 commit 7cb3d10
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 9 deletions.
42 changes: 40 additions & 2 deletions lib/pickle/session/conversion.rb
@@ -1,6 +1,9 @@
module Pickle
module Session
# included into Pickle::Session
module Conversion
include Pickle::Parser::Matchers

# convert a string, hash, or ref into a Pickle::Ref, using config
def ref(pickle_ref)
case pickle_ref
Expand All @@ -9,10 +12,45 @@ def ref(pickle_ref)
else Pickle::Ref.new(pickle_ref, :config => config)
end
end

# convert a pickle fields string, or hash, into a hash that is suitable for adapters
def attributes(fields)
fields
if fields.blank?
{}
elsif fields.is_a?(Hash)
fields.each do |key, value|
begin
fields[key] = retrieve(value)
rescue Pickle::UnknownModelError, Pickle::InvalidPickleRefError
end
end
elsif fields.is_a?(String)
attrs = {}
fields.scan(match_field) do |field|
key, value = field.split(':', 2)
value.strip!

model = begin
retrieve(value)
rescue Pickle::UnknownModelError, Pickle::InvalidPickleRefError
end

if model
value = model
else
value = case value
when /^"(.*)"$/ then $1
when /^'(.*)'$/ then $1
when /^(#{match_value})$/ then eval($1)
else
raise UnknownFieldsFormatError, "#{field.inspect} is in an unknown format"
end
end

attrs[key] = value
end
attrs
end
end
end
end
Expand Down
84 changes: 77 additions & 7 deletions spec/pickle/session/conversion_spec.rb
Expand Up @@ -2,23 +2,93 @@

describe Pickle::Session::Conversion do
include Pickle::Session::Conversion

describe "#ref" do
it "<hash> creates a new pickle ref using the hash, and my config" do
it "(<hash>) creates a new pickle ref using the hash, and my config" do
stub!(:config).and_return(mock)
Pickle::Ref.should_receive(:new).with({:foo => :bar, :config => config}).and_return(pickle_ref = mock)
ref({:foo => :bar}).should == pickle_ref
end
it "<string> creates a new pickle ref using the string, and my config" do

it "(<string>) creates a new pickle ref using the string, and my config" do
stub!(:config).and_return(mock)
Pickle::Ref.should_receive(:new).with('foo bar', {:config => config}).and_return(pickle_ref = mock)
ref('foo bar').should == pickle_ref
end
it "<pickle_ref> just returns the pickle_ref" do

it "(<pickle_ref>) just returns the pickle_ref" do
pickle_ref = Pickle::Ref.new('factory')
ref(pickle_ref).should == pickle_ref
end
end
end

describe "#attributes" do
before do
stub!(:config).and_return(Pickle::Config.new)
end

describe "given blank? argument" do
['', [], {}, nil, false].each do |arg|
it "(#{arg.inspect}) should return {}" do
attributes(arg).should == {}
end
end
end

describe "given a hash" do
describe "containing a pickle_ref as a value" do
let(:do_attributes) { attributes(:name => "Foo", :user => 'a user')}
let(:model) { mock }

it "should return a hash containing the retrieved object in place of the pickle ref, and leave other values alone" do
should_receive(:retrieve).with('a user').and_return(model)
should_receive(:retrieve).with(anything).and_raise(Pickle::UnknownModelError)
do_attributes.should == {:name => "Foo", :user => model}
end
end
end

describe "given a string" do
describe "for example: 'name: \"Fred\", age: 23, married: false, address: nil'" do
before(:each) do
stub!(:retrieve).and_raise(Pickle::UnknownModelError)
end
let(:do_attributes) { attributes(%q{name: "Fred", description: ' Fred: a great man. He is what? He is: great ', age: 23, height: 1.95, married: false, address: nil}) }
subject { do_attributes }

it { should include('name' => "Fred") }
it { should include('description' => ' Fred: a great man. He is what? He is: great ')}
it { should include('age' => 23) }
it { should include('height' => 1.95) }
it { should include('married' => false) }
it { should include('address' => nil) }
end

specify "when field is a pickle-ref which refers attributes should contain it" do
fred = mock
should_receive(:retrieve).with('the user "Fred"').and_return fred
attributes(%q(user: the user "Fred")).should == {'user' => fred}
end

# describe "and a user Fred has been stored in pickle" do
# describe 'the user "Fred"' do
# it {should == fred}
# end
#
# describe '"Fred"' do
# it {should == fred}
# end
# end
#
# describe "and a user Fred has not been stored in pickle" do
# describe 'the user "Fred"' do
# it {should == fred}
# end
#
# describe '"Fred"' do
# it {should == "Fred"}
# end
# end
end
end
end

0 comments on commit 7cb3d10

Please sign in to comment.