jsl-archived_attributes 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require 'rake'
5
+ require 'spec/rake/spectask'
6
+ require 'rake/rdoctask'
7
+
8
+ desc 'Test the plugin.'
9
+ Spec::Rake::SpecTask.new(:spec) do |t|
10
+ t.spec_opts = ["--format", "specdoc", "--colour"]
11
+ t.libs << 'lib'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc "Run all the tests"
16
+ task :default => :spec
17
+
18
+ desc 'Generate documentation for the compressed_attributes plugin.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'ArchivedAttributes'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
@@ -0,0 +1,30 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "archived_attributes"
3
+ s.version = "0.0.1"
4
+ s.date = "2009-01-25"
5
+ s.summary = "Rails plugin to save content to a pluggable back-end"
6
+ s.email = "justin@phq.org"
7
+ s.homepage = "http://github.com/jsl/archived_attributes"
8
+ s.description = "ArchivedAttributes allows for data to be saved to a backend other than the rdbms"
9
+ s.has_rdoc = true
10
+ s.authors = ["Justin Leitgeb"]
11
+ s.files = [
12
+ "Rakefile",
13
+ "archived_attributes.gemspec",
14
+ "init.rb",
15
+ "config/archived_attributes.yml",
16
+ "lib/archived_attributes.rb",
17
+ "lib/archived_attributes/archived_attribute.rb",
18
+ "lib/archived_attributes/global_configuration.rb",
19
+ "lib/archived_attributes/backends/s3.rb",
20
+ "lib/archived_attributes/backends/filesystem.rb"
21
+ ]
22
+ s.test_files = [
23
+ "spec/archived_attributes/global_configuration_spec.rb",
24
+ "spec/archived_attributes/archived_attribute_spec.rb",
25
+ "spec/archived_attributes/backends/filesystem_spec.rb",
26
+ "spec/archived_attributes/backends/s3_spec.rb"
27
+ ]
28
+ s.add_dependency("right_aws", ["> 0.0.0"])
29
+ s.add_dependency("assaf-uuid", ["> 0.0.0"])
30
+ end
@@ -0,0 +1,19 @@
1
+ test:
2
+ storage: filesystem
3
+ s3:
4
+ bucket: test_archived_attributes
5
+ access_key: your access key
6
+ secret_key: your secret key
7
+ protocol: https
8
+
9
+ development:
10
+ storage: s3
11
+ s3:
12
+ bucket: development_archived_attributes
13
+ access_key: your access key
14
+ secret_key: your secret key
15
+
16
+ anotherenv:
17
+ storage: filesystem
18
+ filesystem:
19
+ archive_root: /tmp/archived_attributes
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[lib archived_attributes]))
2
+
3
+ ActiveRecord::Base.send(:include, ArchivedAttributes)
4
+
@@ -0,0 +1,72 @@
1
+ require 'activesupport'
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__),
4
+ %w[ backends filesystem ]))
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[ backends s3 ]))
7
+
8
+ module ArchivedAttributes
9
+
10
+ class ArchivedAttribute
11
+ attr_reader :name, :instance
12
+
13
+ def initialize(name, instance, opts = {})
14
+ @name = name
15
+ @instance = instance
16
+ @dirty = false
17
+
18
+ @_options = ArchivedAttributes::GlobalConfiguration.instance.to_hash.
19
+ merge(opts)
20
+
21
+ @backend = instantiate_backend_from(options)
22
+ end
23
+
24
+ def value
25
+ val = defined?(@stashed_value) ? @stashed_value : @backend.load
26
+ val = compress? ? Zlib::Inflate.inflate(val) : val
27
+ val = marshal? ? Marshal.load(val) : val
28
+ end
29
+
30
+ def value=(other)
31
+ other = marshal? ? Marshal.dump(other) : other
32
+ other = compress? && !other.nil? ? Zlib::Deflate.deflate(other) : other
33
+ @stashed_value = other
34
+ @dirty = true
35
+ end
36
+
37
+ def dirty?
38
+ @dirty
39
+ end
40
+
41
+ # First saves this record to the back-end. If backend storage raises an
42
+ # error, we capture it and add it to the AR validation errors.
43
+ def save
44
+ @backend.save(@stashed_value) if self.dirty?
45
+ end
46
+
47
+ def destroy
48
+ @backend.destroy
49
+ end
50
+
51
+ # Returns a backend object based on the options given (e.g., filesystem,
52
+ # s3).
53
+ def instantiate_backend_from(options)
54
+ "ArchivedAttributes::Backends::#{options[:storage].to_s.camelize}".
55
+ constantize.new(self)
56
+ end
57
+
58
+ def options
59
+ @_options
60
+ end
61
+
62
+ private
63
+
64
+ [:marshal, :compress].each do |sym|
65
+ define_method("#{sym}?") do # def marshal?
66
+ options[sym].nil? ? false : options[sym] # options[:marshal].nil? ? false : options[:marshal]
67
+ end # end
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,58 @@
1
+ module ArchivedAttributes
2
+ module Backends
3
+
4
+ class Filesystem
5
+
6
+ def initialize(archived_attribute)
7
+ @archived_attribute = archived_attribute
8
+ end
9
+
10
+ def save(content)
11
+ create_filesystem_path unless File.exist?(filepath)
12
+ write_to_disk(content)
13
+ end
14
+
15
+ def destroy
16
+ FileUtils.rm_f(filename)
17
+ end
18
+
19
+ def load
20
+ File.read( filename ) if File.exist?( filename )
21
+ end
22
+
23
+ # Returns the full file path + name of this archived attribute
24
+ def filename
25
+ File.join(filepath, @archived_attribute.name.to_s)
26
+ end
27
+
28
+ private
29
+
30
+ # Writes content to disk, or raises an error if the content is unable to
31
+ # be saved
32
+ def write_to_disk(content)
33
+ File.open(filename, 'w') { |f| f.write(content) }
34
+ end
35
+
36
+ def create_filesystem_path
37
+ FileUtils.mkdir_p(filepath)
38
+ end
39
+
40
+ # The file path used for archiving this attribute. Includes either the
41
+ # options[:filesystem][:archive_root] attribute, if available, or the
42
+ # RAILS_ROOT/tmp/archived_attribute_archive/attribute_name.
43
+ def filepath
44
+ config_path = @archived_attribute.options[:filesystem][:archive_root]
45
+
46
+ base_path = config_path || File.join(
47
+ %W[#{RAILS_ROOT} tmp archived_attribute_archive]
48
+ )
49
+
50
+ File.expand_path( File.join(base_path,
51
+ @archived_attribute.name.to_s,
52
+ @archived_attribute.instance.uuid ))
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,58 @@
1
+ require 'right_aws'
2
+
3
+ module ArchivedAttributes
4
+ module Backends
5
+
6
+ class S3
7
+
8
+ def initialize(archived_attribute)
9
+ @archived_attribute = archived_attribute
10
+ @config = ArchivedAttributes::GlobalConfiguration.instance[:s3]
11
+ end
12
+
13
+ def save(content)
14
+ bucket.put( key_name, StringIO.new( content ) ) unless content.nil?
15
+ end
16
+
17
+ def destroy
18
+ bucket.key(key_name).delete
19
+ end
20
+
21
+ def load
22
+ bucket.get(key_name)
23
+ end
24
+
25
+ private
26
+
27
+ def bucket
28
+ @bucket ||= right_aws_s3.bucket(bucket_name)
29
+ end
30
+
31
+ def right_aws_s3
32
+ @s3 ||= RightAws::S3.new(
33
+ @config[:access_key],
34
+ @config[:secret_key]
35
+ )
36
+ end
37
+
38
+ # Returns the bucket name to be used based on attributes of the archived
39
+ # attribute.
40
+ def bucket_name
41
+ @config[:bucket]
42
+ end
43
+
44
+ def key_name
45
+ [ @archived_attribute.instance.class.table_name,
46
+ @archived_attribute.name,
47
+ @archived_attribute.instance.uuid ].join('/')
48
+ end
49
+
50
+ # Returns a string representing whether we use http or https for this
51
+ # connection.
52
+ def protocol
53
+ @config[:protocol] || 'https'
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,49 @@
1
+ module ArchivedAttributes
2
+
3
+ # Singleton class for reading the defaults archived attribute configuration
4
+ # for this environment.
5
+ class GlobalConfiguration
6
+ include Singleton
7
+
8
+ DEFAULTS = HashWithIndifferentAccess.new({
9
+ :storage => 'filesystem',
10
+ :marshal => false,
11
+ :compress => false,
12
+ :s3 => {
13
+ :protocol => 'https'
14
+ },
15
+ :filesystem => {
16
+ :archive_root => nil
17
+ }
18
+ })
19
+
20
+ def [](val)
21
+ config[val]
22
+ end
23
+
24
+ def to_hash
25
+ config
26
+ end
27
+
28
+ def to_s
29
+ config.inspect
30
+ end
31
+
32
+ private
33
+
34
+ def config
35
+ @config ||= HashWithIndifferentAccess.new(
36
+ DEFAULTS.merge(load_yaml_configuration)
37
+ )
38
+
39
+ @config.dup
40
+ end
41
+
42
+ def load_yaml_configuration
43
+ YAML.load_file(
44
+ File.join( RAILS_ROOT, 'config', 'archived_attributes.yml' )
45
+ )[RAILS_ENV]
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,80 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[archived_attributes archived_attribute] ))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[archived_attributes global_configuration] ))
3
+
4
+ require 'uuid'
5
+
6
+ module ArchivedAttributes
7
+
8
+ def self.included(base)
9
+ base.extend(SingletonMethods)
10
+ end
11
+
12
+ module SingletonMethods
13
+
14
+ def archived_attribute(*args)
15
+ attribute = args.first
16
+
17
+ options = args.extract_options!
18
+ options.reverse_merge! :marshalled => false
19
+
20
+ if archived_attribute_definitions.nil?
21
+ write_inheritable_attribute(:archived_attribute_definitions, {})
22
+
23
+ before_save :generate_uuid
24
+ before_save :save_archived_attributes
25
+ before_destroy :destroy_archived_attributes
26
+ end
27
+
28
+ archived_attribute_definitions[attribute] = options
29
+
30
+ self.__send__(:include, InstanceMethods)
31
+
32
+ define_method attribute do
33
+ archive_stash_for(attribute).value
34
+ end
35
+
36
+ define_method "#{attribute}=" do |value|
37
+ archive_stash_for(attribute).value = value
38
+ end
39
+ end
40
+
41
+ # Returns the attachment definitions defined by each call to
42
+ # has_attached_file.
43
+ def archived_attribute_definitions
44
+ read_inheritable_attribute(:archived_attribute_definitions)
45
+ end
46
+
47
+ end
48
+
49
+ module InstanceMethods
50
+ def archive_stash_for(model)
51
+ @_archived_attribute_stashes ||= {}
52
+ @_archived_attribute_stashes[model] ||= ArchivedAttribute.new(
53
+ model, self, self.class.archived_attribute_definitions[model]
54
+ )
55
+ end
56
+
57
+ def each_archived_stash
58
+ self.class.archived_attribute_definitions.each do |name, definition|
59
+ yield(name, archive_stash_for(name))
60
+ end
61
+ end
62
+
63
+ def save_archived_attributes
64
+ each_archived_stash do |name, stash|
65
+ stash.__send__(:save)
66
+ end
67
+ end
68
+
69
+ def destroy_archived_attributes
70
+ each_archived_stash do |name, stash|
71
+ stash.__send__(:destroy)
72
+ end
73
+ end
74
+
75
+ def generate_uuid
76
+ self.uuid = UUID.new.generate if self.new_record?
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,120 @@
1
+ require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
2
+
3
+ describe ArchivedAttributes::ArchivedAttribute do
4
+ before do
5
+ options = { :storage => 'filesystem' }
6
+ stub_model = stub(:uuid => '43')
7
+ @aa = ArchivedAttributes::ArchivedAttribute.new(:glorp, stub_model, options)
8
+ end
9
+
10
+ describe "#dirty?" do
11
+ it "should return false when a value has not been set" do
12
+ @aa.should_not be_dirty
13
+ end
14
+
15
+ it "should return when the value has been set" do
16
+ @aa.value = 'stuff'
17
+ @aa.should be_dirty
18
+ end
19
+ end
20
+
21
+ describe "#marshal?" do
22
+ it "should return false if configuration option is nil" do
23
+ @aa.expects(:options).returns({:marshal => nil})
24
+ @aa.__send__(:marshal?).should be_false
25
+ end
26
+
27
+ it "should return value from configuration if configuration option is not nil" do
28
+ @aa.expects(:options).returns({:marshal => false}).times(2)
29
+ @aa.__send__(:marshal?).should be_false
30
+ end
31
+ end
32
+
33
+ describe "#compress?" do
34
+ it "should return false if configuration option is nil" do
35
+ @aa.expects(:options).returns({:compress => nil})
36
+ @aa.__send__(:compress?).should be_false
37
+ end
38
+
39
+ it "should return value from configuration if configuration option is not nil" do
40
+ @aa.expects(:options).returns({:compress => false}).times(2)
41
+ @aa.__send__(:compress?).should be_false
42
+ end
43
+ end
44
+
45
+ describe "#destroy" do
46
+ it "should call destroy on the backend object" do
47
+ backend = mock('backend', :destroy => true)
48
+ @aa.instance_variable_set(:'@backend', backend)
49
+ @aa.destroy
50
+ end
51
+ end
52
+
53
+ describe "when marshal is on" do
54
+ before do
55
+ @content = 'mary had a little lamb'
56
+ stub_backend = stub('backend', :load => Marshal.dump(@content))
57
+ @aa.stubs(:options).
58
+ returns({ :storage => 'filesystem', :marshal => true })
59
+ @aa.__send__(:instance_variable_set, :'@backend', stub_backend)
60
+ end
61
+
62
+ it "should call Marshal.load to restore value" do
63
+ Marshal.expects(:load)
64
+ @aa.value
65
+ end
66
+
67
+ it "should call Marshal.dump to save value" do
68
+ Marshal.expects(:dump)
69
+ @aa.value = 'foo'
70
+ end
71
+
72
+ it "should retrieve same content string stored in Marshalled form" do
73
+ @aa.value.should == @content
74
+ end
75
+ end
76
+
77
+ describe "when gzip is on" do
78
+ before do
79
+ @content = "The band formed in 1988 in Oxford"
80
+ stub_backend = stub('backend', :load => Zlib::Deflate.deflate(@content))
81
+ @aa.stubs(:options).
82
+ returns({ :storage => 'filesystem', :compress => true })
83
+ @aa.__send__(:instance_variable_set, :'@backend', stub_backend)
84
+ end
85
+
86
+ it "should call Zlib::Inflate.inflate to restore value" do
87
+ Zlib::Inflate.expects(:inflate)
88
+ @aa.value
89
+ end
90
+
91
+ it "should call Zlib::Deflate.deflate to save value" do
92
+ Zlib::Deflate.expects(:deflate)
93
+ @aa.value = 'foo'
94
+ end
95
+
96
+ it "should retrieve same content string stored in gzip form" do
97
+ @aa.value.should == @content
98
+ end
99
+
100
+ it "should not raise an error with nil content" do
101
+ lambda {
102
+ @aa.value = nil
103
+ }.should_not raise_error
104
+ end
105
+ end
106
+
107
+ describe "when compress and marshal are on" do
108
+ before do
109
+ @content = "The band formed in 1988 in Oxford"
110
+ stub_backend = stub('backend', :load => Zlib::Deflate.deflate(Marshal.dump(@content)))
111
+ @aa.stubs(:options).
112
+ returns({ :storage => 'filesystem', :compress => true, :marshal => true })
113
+ @aa.__send__(:instance_variable_set, :'@backend', stub_backend)
114
+ end
115
+
116
+ it "should retrieve the same content given" do
117
+ @aa.value.should == @content
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,82 @@
1
+ require File.join(File.dirname(__FILE__), %w[ .. .. spec_helper ])
2
+
3
+ require 'tmpdir'
4
+
5
+ describe ArchivedAttributes::Backends::Filesystem do
6
+
7
+ before do
8
+ @unique_path_part = 'archived_attributes_test'
9
+ @path = File.join(Dir.tmpdir, @unique_path_part)
10
+
11
+
12
+ @instance = stub('http_retrieval',
13
+ :uuid => '63d3a120-caca-012b-d468-002332d4f91e',
14
+ :name => :foo
15
+ )
16
+
17
+ aa = ArchivedAttributes::ArchivedAttribute.new(:content, @instance,
18
+ :filesystem => { :archive_root => @path } )
19
+
20
+ @fs = ArchivedAttributes::Backends::Filesystem.new(aa)
21
+ end
22
+
23
+ it "should write to the correct path" do
24
+ @fs.__send__(:filepath).should ==
25
+ File.expand_path(File.join(@path, 'content', @instance.uuid))
26
+ end
27
+
28
+ describe "#save" do
29
+ before do
30
+ if File.exist?(@path)
31
+ err = <<-EOS
32
+ Test directory #{@path} already exists. Please remove it and run the
33
+ test suite again.
34
+ EOS
35
+ raise RuntimeError, err
36
+ else
37
+ @remove_path = true
38
+ FileUtils.mkdir(@path)
39
+ end
40
+ end
41
+
42
+ it "should call methods to create path and save file to disk" do
43
+ @fs.save('test')
44
+ File.exist?(@fs.filename).should be_true
45
+ end
46
+
47
+ after(:all) do
48
+ FileUtils.rm_rf(@path) if @remove_path
49
+ end
50
+
51
+ end
52
+
53
+ describe "#destroy" do
54
+ before do
55
+ if File.exist?(@path)
56
+ err = <<-EOS
57
+ Test directory #{@path} already exists. Please remove it and run the
58
+ test suite again.
59
+ EOS
60
+ raise RuntimeError, err
61
+ else
62
+ @remove_path = true
63
+ FileUtils.mkdir(@path)
64
+ end
65
+ end
66
+
67
+ it "should call methods to remove path and file" do
68
+ @fs.save('test')
69
+ File.exist?(@fs.filename).should be_true
70
+
71
+ @fs.destroy
72
+ File.exist?(@fs.filename).should be_false
73
+ end
74
+
75
+ after(:all) do
76
+ FileUtils.rm_rf(@path) if @remove_path
77
+ end
78
+
79
+ end
80
+
81
+
82
+ end
@@ -0,0 +1,79 @@
1
+ require File.join(File.dirname(__FILE__), %w[ .. .. spec_helper ])
2
+
3
+ describe ArchivedAttributes::Backends::S3 do
4
+
5
+ before do
6
+ @instance = stub('ar_instance',
7
+ :uuid => '63d3a120-caca-012b-d468-002332d4f91e',
8
+ :table_name => 'glorps'
9
+ )
10
+
11
+ @aa = ArchivedAttributes::ArchivedAttribute.new(:stuff, @instance)
12
+ @s3 = ArchivedAttributes::Backends::S3.new(@aa)
13
+ @config = ArchivedAttributes::GlobalConfiguration.instance
14
+ end
15
+
16
+ describe "#initialize" do
17
+ it "should initialize an s3 object without error" do
18
+ lambda { ArchivedAttributes::Backends::S3.new(@aa) }.should_not raise_error
19
+ end
20
+ end
21
+
22
+ describe "#protocol" do
23
+ it "should be https by default" do
24
+ @s3.__send__(:protocol).should == "https"
25
+ end
26
+
27
+ it "should use http if specified in the configuration object" do
28
+ config = { :protocol => 'http' }
29
+ @s3.instance_variable_set(:"@config", config)
30
+
31
+ @s3.__send__(:protocol).should == "http"
32
+ end
33
+
34
+ end
35
+
36
+ describe "#load" do
37
+ it "should call method to load data from s3" do
38
+ bucket = mock('bucket')
39
+ bucket.expects(:get).once
40
+ aws_s3 = mock('aws_s3')
41
+ aws_s3.expects(:bucket).returns(bucket)
42
+ @s3.expects(:key_name).returns('some-key')
43
+ @s3.expects(:right_aws_s3).returns(aws_s3)
44
+ @s3.load
45
+ end
46
+ end
47
+
48
+ describe "#save" do
49
+ it "should call method to store data in s3" do
50
+ bucket = mock('bucket')
51
+ content = 'hey'
52
+ key = 'fookey'
53
+ @s3.expects(:key_name).returns(key)
54
+ bucket.expects(:put).once
55
+ aws_s3 = mock('aws_s3')
56
+ aws_s3.expects(:bucket).returns(bucket)
57
+ @s3.expects(:right_aws_s3).returns(aws_s3)
58
+ @s3.save(content)
59
+ end
60
+ end
61
+
62
+ describe "#destroy" do
63
+ it "should call method to delete key" do
64
+ key = mock('key', :delete => true)
65
+ bucket = mock('bucket', :key => key)
66
+ aws_s3 = mock('aws_s3')
67
+ aws_s3.expects(:bucket).returns(bucket)
68
+ @s3.expects(:right_aws_s3).returns(aws_s3)
69
+ @s3.expects(:key_name).returns('foo-key')
70
+ @s3.destroy
71
+ end
72
+ end
73
+
74
+ describe "#bucket_name" do
75
+ it "should be based on the attribute class and model" do
76
+ @s3.__send__(:bucket_name).should == @config[:s3]['bucket']
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,72 @@
1
+ require File.join(File.dirname(__FILE__), %w[ .. spec_helper ])
2
+
3
+ describe ArchivedAttributes::GlobalConfiguration do
4
+ before do
5
+ @conf = ArchivedAttributes::GlobalConfiguration.instance
6
+ end
7
+
8
+ describe "defaults" do
9
+ it "should set default marshal value to false" do
10
+ ArchivedAttributes::GlobalConfiguration::DEFAULTS[:marshal].should == false
11
+ end
12
+
13
+ it "should set gzip value to false" do
14
+ ArchivedAttributes::GlobalConfiguration::DEFAULTS[:marshal].should == false
15
+ end
16
+ end
17
+
18
+ it "should read default access key from the configuration file" do
19
+ @conf[:s3]['access_key'].should == 'your access key'
20
+ end
21
+
22
+ it "should the default secret key from configuration" do
23
+ @conf[:s3]['secret_key'].should == 'your secret key'
24
+ end
25
+
26
+ it "should read the default bucket from the configuration file" do
27
+ @conf[:s3]['bucket'].should == 'test_archived_attributes'
28
+ end
29
+
30
+ describe "#to_s" do
31
+ it "should return a string" do
32
+ @conf.to_s.should be_an_instance_of(String)
33
+ end
34
+ end
35
+
36
+ describe "hash cloning" do
37
+ it "should be able to alter a Hash without affecting the original object" do
38
+ conf = @conf.to_hash
39
+ previous = @conf[:storage]
40
+ conf[:storage] = 'foo'
41
+ @conf[:storage].should == previous
42
+ end
43
+
44
+ it "should not affect deeply nested attributes when values are changed" do
45
+ conf = @conf.to_hash
46
+ previous = @conf[:s3][:protocol]
47
+ conf[:s3][:protocol] = 'puddle'
48
+ @conf[:s3][:protocol].should == previous
49
+ end
50
+ end
51
+
52
+ describe "#to_hash" do
53
+ it "should return an instance of Hash" do
54
+ @conf.to_hash.should be_an_instance_of(HashWithIndifferentAccess)
55
+ end
56
+ end
57
+
58
+ describe "when an option is not specified in the yaml config file" do
59
+ it "should have a section for s3 options in hash" do
60
+ @conf[:s3].should_not be_nil
61
+ end
62
+
63
+ it "should default to https for protocol" do
64
+ @conf[:s3][:protocol].should == 'https'
65
+ end
66
+
67
+ it "should set default storage attribute to :filesystem" do
68
+ @conf[:storage].should == 'filesystem'
69
+ end
70
+ end
71
+
72
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsl-archived_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Justin Leitgeb
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-25 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: right_aws
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">"
21
+ - !ruby/object:Gem::Version
22
+ version: 0.0.0
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: assaf-uuid
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">"
30
+ - !ruby/object:Gem::Version
31
+ version: 0.0.0
32
+ version:
33
+ description: ArchivedAttributes allows for data to be saved to a backend other than the rdbms
34
+ email: justin@phq.org
35
+ executables: []
36
+
37
+ extensions: []
38
+
39
+ extra_rdoc_files: []
40
+
41
+ files:
42
+ - Rakefile
43
+ - archived_attributes.gemspec
44
+ - init.rb
45
+ - config/archived_attributes.yml
46
+ - lib/archived_attributes.rb
47
+ - lib/archived_attributes/archived_attribute.rb
48
+ - lib/archived_attributes/global_configuration.rb
49
+ - lib/archived_attributes/backends/s3.rb
50
+ - lib/archived_attributes/backends/filesystem.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/jsl/archived_attributes
53
+ post_install_message:
54
+ rdoc_options: []
55
+
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.2.0
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: Rails plugin to save content to a pluggable back-end
77
+ test_files:
78
+ - spec/archived_attributes/global_configuration_spec.rb
79
+ - spec/archived_attributes/archived_attribute_spec.rb
80
+ - spec/archived_attributes/backends/filesystem_spec.rb
81
+ - spec/archived_attributes/backends/s3_spec.rb