drafter 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +127 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/drafter.gemspec +93 -0
- data/lib/drafter/creation.rb +57 -0
- data/lib/drafter/draft.rb +92 -0
- data/lib/drafter/draft_upload.rb +27 -0
- data/lib/drafter/draft_uploader.rb +8 -0
- data/lib/drafter/draftable.rb +25 -0
- data/lib/drafter.rb +29 -0
- data/test/drafter/test_creation.rb +140 -0
- data/test/drafter/test_draft.rb +104 -0
- data/test/drafter/test_draft_upload.rb +31 -0
- data/test/drafter/test_draftable.rb +17 -0
- data/test/fixtures/bar.txt +1 -0
- data/test/fixtures/foo.txt +1 -0
- data/test/helper.rb +58 -0
- data/test/support/data.rb +2 -0
- data/test/support/models.rb +17 -0
- data/test/support/schema.rb +27 -0
- data/test/support/uploader.rb +8 -0
- data/test/test_drafter.rb +5 -0
- data/test/watchr.rb +5 -0
- metadata +187 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
gem "activerecord"
|
6
|
+
gem "sqlite3"
|
7
|
+
gem "debugger"
|
8
|
+
|
9
|
+
# Add dependencies to develop your gem here.
|
10
|
+
# Include everything needed to run rake, tests, features, etc.
|
11
|
+
group :development do
|
12
|
+
gem "minitest", ">= 0"
|
13
|
+
gem "bundler", "~> 1.0.0"
|
14
|
+
gem "jeweler", "~> 1.6.4"
|
15
|
+
gem "rcov", ">= 0"
|
16
|
+
gem 'turn'
|
17
|
+
gem 'carrierwave'
|
18
|
+
gem "minitest-rails-shoulda"
|
19
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (3.2.8)
|
5
|
+
actionpack (= 3.2.8)
|
6
|
+
mail (~> 2.4.4)
|
7
|
+
actionpack (3.2.8)
|
8
|
+
activemodel (= 3.2.8)
|
9
|
+
activesupport (= 3.2.8)
|
10
|
+
builder (~> 3.0.0)
|
11
|
+
erubis (~> 2.7.0)
|
12
|
+
journey (~> 1.0.4)
|
13
|
+
rack (~> 1.4.0)
|
14
|
+
rack-cache (~> 1.2)
|
15
|
+
rack-test (~> 0.6.1)
|
16
|
+
sprockets (~> 2.1.3)
|
17
|
+
activemodel (3.2.8)
|
18
|
+
activesupport (= 3.2.8)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
activerecord (3.2.8)
|
21
|
+
activemodel (= 3.2.8)
|
22
|
+
activesupport (= 3.2.8)
|
23
|
+
arel (~> 3.0.2)
|
24
|
+
tzinfo (~> 0.3.29)
|
25
|
+
activeresource (3.2.8)
|
26
|
+
activemodel (= 3.2.8)
|
27
|
+
activesupport (= 3.2.8)
|
28
|
+
activesupport (3.2.8)
|
29
|
+
i18n (~> 0.6)
|
30
|
+
multi_json (~> 1.0)
|
31
|
+
ansi (1.4.2)
|
32
|
+
arel (3.0.2)
|
33
|
+
builder (3.0.0)
|
34
|
+
carrierwave (0.6.2)
|
35
|
+
activemodel (>= 3.2.0)
|
36
|
+
activesupport (>= 3.2.0)
|
37
|
+
columnize (0.3.6)
|
38
|
+
debugger (1.1.1)
|
39
|
+
columnize (>= 0.3.1)
|
40
|
+
debugger-linecache (~> 1.1)
|
41
|
+
debugger-ruby_core_source (~> 1.1)
|
42
|
+
debugger-linecache (1.1.1)
|
43
|
+
debugger-ruby_core_source (>= 1.1.1)
|
44
|
+
debugger-ruby_core_source (1.1.2)
|
45
|
+
erubis (2.7.0)
|
46
|
+
git (1.2.5)
|
47
|
+
hike (1.2.1)
|
48
|
+
i18n (0.6.0)
|
49
|
+
jeweler (1.6.4)
|
50
|
+
bundler (~> 1.0)
|
51
|
+
git (>= 1.2.5)
|
52
|
+
rake
|
53
|
+
journey (1.0.4)
|
54
|
+
json (1.7.4)
|
55
|
+
mail (2.4.4)
|
56
|
+
i18n (>= 0.4.0)
|
57
|
+
mime-types (~> 1.16)
|
58
|
+
treetop (~> 1.4.8)
|
59
|
+
mime-types (1.19)
|
60
|
+
minitest (3.2.0)
|
61
|
+
minitest-matchers (1.1.3)
|
62
|
+
minitest (>= 2.5.0)
|
63
|
+
minitest-rails (0.1.3)
|
64
|
+
minitest (~> 3.0)
|
65
|
+
rails (~> 3.0)
|
66
|
+
minitest-rails-shoulda (0.1.0)
|
67
|
+
minitest-matchers (~> 1.1.3)
|
68
|
+
minitest-rails (~> 0.1.0)
|
69
|
+
shoulda-matchers (~> 1.2.0)
|
70
|
+
multi_json (1.3.6)
|
71
|
+
polyglot (0.3.3)
|
72
|
+
rack (1.4.1)
|
73
|
+
rack-cache (1.2)
|
74
|
+
rack (>= 0.4)
|
75
|
+
rack-ssl (1.3.2)
|
76
|
+
rack
|
77
|
+
rack-test (0.6.1)
|
78
|
+
rack (>= 1.0)
|
79
|
+
rails (3.2.8)
|
80
|
+
actionmailer (= 3.2.8)
|
81
|
+
actionpack (= 3.2.8)
|
82
|
+
activerecord (= 3.2.8)
|
83
|
+
activeresource (= 3.2.8)
|
84
|
+
activesupport (= 3.2.8)
|
85
|
+
bundler (~> 1.0)
|
86
|
+
railties (= 3.2.8)
|
87
|
+
railties (3.2.8)
|
88
|
+
actionpack (= 3.2.8)
|
89
|
+
activesupport (= 3.2.8)
|
90
|
+
rack-ssl (~> 1.3.2)
|
91
|
+
rake (>= 0.8.7)
|
92
|
+
rdoc (~> 3.4)
|
93
|
+
thor (>= 0.14.6, < 2.0)
|
94
|
+
rake (0.9.2.2)
|
95
|
+
rcov (0.9.11)
|
96
|
+
rdoc (3.12)
|
97
|
+
json (~> 1.4)
|
98
|
+
shoulda-matchers (1.2.0)
|
99
|
+
activesupport (>= 3.0.0)
|
100
|
+
sprockets (2.1.3)
|
101
|
+
hike (~> 1.2)
|
102
|
+
rack (~> 1.0)
|
103
|
+
tilt (~> 1.1, != 1.3.0)
|
104
|
+
sqlite3 (1.3.6)
|
105
|
+
thor (0.16.0)
|
106
|
+
tilt (1.3.3)
|
107
|
+
treetop (1.4.10)
|
108
|
+
polyglot
|
109
|
+
polyglot (>= 0.3.1)
|
110
|
+
turn (0.9.5)
|
111
|
+
ansi
|
112
|
+
tzinfo (0.3.33)
|
113
|
+
|
114
|
+
PLATFORMS
|
115
|
+
ruby
|
116
|
+
|
117
|
+
DEPENDENCIES
|
118
|
+
activerecord
|
119
|
+
bundler (~> 1.0.0)
|
120
|
+
carrierwave
|
121
|
+
debugger
|
122
|
+
jeweler (~> 1.6.4)
|
123
|
+
minitest
|
124
|
+
minitest-rails-shoulda
|
125
|
+
rcov
|
126
|
+
sqlite3
|
127
|
+
turn
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 futurechimp
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= drafter
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to drafter
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
+
* Fork the project
|
10
|
+
* Start a feature/bugfix branch
|
11
|
+
* Commit and push until you are happy with your contribution
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2012 futurechimp. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "drafter"
|
18
|
+
gem.homepage = "http://github.com/futurechimp/drafter"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Simple}
|
21
|
+
gem.description = %Q{A}
|
22
|
+
gem.email = "dave.hrycyszyn@headlondon.com"
|
23
|
+
gem.authors = ["futurechimp"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.libs << 'lib' << 'test'
|
31
|
+
test.pattern = 'test/**/test_*.rb'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
Rcov::RcovTask.new do |test|
|
37
|
+
test.libs << 'test'
|
38
|
+
test.pattern = 'test/**/test_*.rb'
|
39
|
+
test.verbose = true
|
40
|
+
test.rcov_opts << '--exclude "gems/*"'
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "drafter #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/drafter.gemspec
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "drafter"
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["futurechimp"]
|
12
|
+
s.date = "2012-08-17"
|
13
|
+
s.description = "A"
|
14
|
+
s.email = "dave.hrycyszyn@headlondon.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"drafter.gemspec",
|
28
|
+
"lib/drafter.rb",
|
29
|
+
"lib/drafter/creation.rb",
|
30
|
+
"lib/drafter/draft.rb",
|
31
|
+
"lib/drafter/draft_upload.rb",
|
32
|
+
"lib/drafter/draft_uploader.rb",
|
33
|
+
"lib/drafter/draftable.rb",
|
34
|
+
"test/drafter/test_creation.rb",
|
35
|
+
"test/drafter/test_draft.rb",
|
36
|
+
"test/drafter/test_draft_upload.rb",
|
37
|
+
"test/drafter/test_draftable.rb",
|
38
|
+
"test/fixtures/bar.txt",
|
39
|
+
"test/fixtures/foo.txt",
|
40
|
+
"test/helper.rb",
|
41
|
+
"test/support/data.rb",
|
42
|
+
"test/support/models.rb",
|
43
|
+
"test/support/schema.rb",
|
44
|
+
"test/support/uploader.rb",
|
45
|
+
"test/test_drafter.rb",
|
46
|
+
"test/watchr.rb"
|
47
|
+
]
|
48
|
+
s.homepage = "http://github.com/futurechimp/drafter"
|
49
|
+
s.licenses = ["MIT"]
|
50
|
+
s.require_paths = ["lib"]
|
51
|
+
s.rubygems_version = "1.8.17"
|
52
|
+
s.summary = "Simple"
|
53
|
+
|
54
|
+
if s.respond_to? :specification_version then
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
58
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
59
|
+
s.add_runtime_dependency(%q<sqlite3>, [">= 0"])
|
60
|
+
s.add_runtime_dependency(%q<debugger>, [">= 0"])
|
61
|
+
s.add_development_dependency(%q<minitest>, [">= 0"])
|
62
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
63
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
64
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
65
|
+
s.add_development_dependency(%q<turn>, [">= 0"])
|
66
|
+
s.add_development_dependency(%q<carrierwave>, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<minitest-rails-shoulda>, [">= 0"])
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
70
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
71
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
72
|
+
s.add_dependency(%q<minitest>, [">= 0"])
|
73
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
74
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
75
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
76
|
+
s.add_dependency(%q<turn>, [">= 0"])
|
77
|
+
s.add_dependency(%q<carrierwave>, [">= 0"])
|
78
|
+
s.add_dependency(%q<minitest-rails-shoulda>, [">= 0"])
|
79
|
+
end
|
80
|
+
else
|
81
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
82
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
83
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
84
|
+
s.add_dependency(%q<minitest>, [">= 0"])
|
85
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
86
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
87
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
88
|
+
s.add_dependency(%q<turn>, [">= 0"])
|
89
|
+
s.add_dependency(%q<carrierwave>, [">= 0"])
|
90
|
+
s.add_dependency(%q<minitest-rails-shoulda>, [">= 0"])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Drafter
|
2
|
+
|
3
|
+
# Takes care of associating and creating Draft objects for the draftable
|
4
|
+
# class.
|
5
|
+
module Creation
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
# Set up the association to the Draft object.
|
9
|
+
included do
|
10
|
+
has_one :draft, :as => :draftable
|
11
|
+
end
|
12
|
+
|
13
|
+
# Build and save the draft when told to do so.
|
14
|
+
def save_draft
|
15
|
+
if self.valid?
|
16
|
+
attrs = self.attributes
|
17
|
+
uploads = build_draft_uploads(attrs)
|
18
|
+
self.build_draft(:data => attrs)
|
19
|
+
self.draft.save!
|
20
|
+
self.draft.draft_uploads << uploads
|
21
|
+
self.draft
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Loop through and create DraftUpload objects for any Carrierwave
|
28
|
+
# uploaders mounted on this draftable object.
|
29
|
+
#
|
30
|
+
# @param [Hash] attrs the attributes to loop through
|
31
|
+
# @return [Array<DraftUpload>] an array of unsaved DraftUpload objects.
|
32
|
+
def build_draft_uploads(attrs)
|
33
|
+
draft_uploads = []
|
34
|
+
attrs.keys.each do |key|
|
35
|
+
if self.send(key).is_a?(CarrierWave::Uploader::Base)
|
36
|
+
draft_uploads << build_draft_upload(key)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
draft_uploads
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get a reference to the CarrierWave uploader mounted on the
|
43
|
+
# current draftable object, grab the file in it, and shove
|
44
|
+
# that file into a new DraftUpload.
|
45
|
+
#
|
46
|
+
# @param [String] key the attribute where the CarrierWave uploader
|
47
|
+
# is mounted.
|
48
|
+
# @return [DraftUpload] containing the file in the uploader.
|
49
|
+
def build_draft_upload(key)
|
50
|
+
cw_uploader = self.send(key)
|
51
|
+
file = File.new(cw_uploader.file.path) if cw_uploader.file
|
52
|
+
draft_upload = DraftUpload.new(
|
53
|
+
:file_data => file, :draftable_mount_column => key)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# A model to store serialized draft data. Drafts attach themselves
|
2
|
+
# polymorphically to any other ActiveRecord class, loop through the
|
3
|
+
# target draftable classes's attributes, and store them as a Hash
|
4
|
+
# in the :data text field in the database.
|
5
|
+
#
|
6
|
+
# Drafts can also keep track of the target draftable's CarrierWave uploads,
|
7
|
+
# if any exist.
|
8
|
+
#
|
9
|
+
class Draft < ActiveRecord::Base
|
10
|
+
|
11
|
+
# Validations
|
12
|
+
#
|
13
|
+
validates_presence_of :data
|
14
|
+
|
15
|
+
# Associations
|
16
|
+
#
|
17
|
+
has_many :draft_uploads
|
18
|
+
belongs_to :draftable, :polymorphic => true
|
19
|
+
|
20
|
+
|
21
|
+
# Store serialized data for the associated draftable as a Hash of
|
22
|
+
# attributes.
|
23
|
+
#
|
24
|
+
serialize :data, Hash
|
25
|
+
|
26
|
+
# Approve a draft, setting the attributes of the draftable object to
|
27
|
+
# contain the draft content, saving the draftable, and destroying the draft.
|
28
|
+
#
|
29
|
+
def approve!
|
30
|
+
draftable = build_draftable
|
31
|
+
draftable.save!
|
32
|
+
self.destroy
|
33
|
+
draftable
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set things up so we can use dot notation to access draft data, e.g.
|
37
|
+
# we can do either @foo.draft.data["title"] or (more neatly) we can
|
38
|
+
# do @foo.draft.title
|
39
|
+
#
|
40
|
+
def method_missing(meth, *args, &block)
|
41
|
+
if self.data.keys.include?(meth.to_s)
|
42
|
+
self.data[meth.to_s]
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Find the existing draftable, or build a new one, and set it up.
|
52
|
+
#
|
53
|
+
# @return the existing draftable object, or a new one of the proper
|
54
|
+
# type, with attributes and files hanging off it.
|
55
|
+
def build_draftable
|
56
|
+
dr = draftable.nil? ? self.draftable_type.constantize.new : draftable
|
57
|
+
restore_attrs_on(dr)
|
58
|
+
restore_files_on(dr)
|
59
|
+
dr
|
60
|
+
end
|
61
|
+
|
62
|
+
# Whack the draft data onto the real object.
|
63
|
+
#
|
64
|
+
# @param [Draftable] dr a new or existing draftable to restore from the
|
65
|
+
# draft attributes.
|
66
|
+
# @return [Draftable] the draftable object populated with the draft attrs.
|
67
|
+
def restore_attrs_on(dr)
|
68
|
+
draftable_columns.each do |key|
|
69
|
+
dr.raw_write_attribute key, self.data[key]
|
70
|
+
end
|
71
|
+
dr
|
72
|
+
end
|
73
|
+
|
74
|
+
# Attach draft files to the real object.
|
75
|
+
#
|
76
|
+
# @param [Draftable] dr a new or existing draftable.
|
77
|
+
# @return [Draftable] the draftable object where CarrierWave uploads
|
78
|
+
# on the object have been replaced with their draft equivalents.
|
79
|
+
def restore_files_on(dr)
|
80
|
+
draft_uploads.each do |draft_upload|
|
81
|
+
dr.send(draft_upload.draftable_mount_column + "=", draft_upload.file_data)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# We don't want to copy all the draft's columns into the draftable
|
86
|
+
# objects attributes.
|
87
|
+
#
|
88
|
+
# @return [Array] the draft's columns minus :id, :created_at, :updated_at
|
89
|
+
def draftable_columns
|
90
|
+
self.data.keys - ['id', 'created_at', 'updated_at']
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Some of the objects we want to keep drafts of will have attached uploads,
|
2
|
+
# which are stored using CarrierWave. The simplest thing which can work, I
|
3
|
+
# think, is to grab the uploaded data from the draftable object, and store it
|
4
|
+
# in its own class, making a note of the original mount column that the file
|
5
|
+
# was destined for.
|
6
|
+
#
|
7
|
+
# The original :file_data is saved in this model, without any processing
|
8
|
+
# or modification. When the draft is approved, the Draft will push the
|
9
|
+
# :file_data onto the :draftable_mount_column of the draftable object.
|
10
|
+
#
|
11
|
+
class DraftUpload < ActiveRecord::Base
|
12
|
+
|
13
|
+
# Associations
|
14
|
+
#
|
15
|
+
belongs_to :draft
|
16
|
+
|
17
|
+
# Validations
|
18
|
+
#
|
19
|
+
validates_presence_of :draft
|
20
|
+
validates_presence_of :draftable_mount_column
|
21
|
+
validates_presence_of :file_data
|
22
|
+
|
23
|
+
# Macros
|
24
|
+
#
|
25
|
+
mount_uploader :file_data, DraftUploader
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Drafter
|
2
|
+
# Adds a flag to determine whether a model class is draftable.
|
3
|
+
module Draftable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Overrides the +draftable+ method to first define the +draftable?+ class method before
|
7
|
+
# deferring to the original +draftable+.
|
8
|
+
module ClassMethods
|
9
|
+
def draftable(*args)
|
10
|
+
class << self
|
11
|
+
def draftable?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# For all ActiveRecord::Base models that do not call the +draftable+ method, the +draftable?+
|
18
|
+
# method will return false.
|
19
|
+
def draftable?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/drafter.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/dependencies/autoload'
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
require 'lib/drafter/draft_uploader'
|
7
|
+
|
8
|
+
module Drafter
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
extend ActiveSupport::Autoload
|
11
|
+
|
12
|
+
autoload :Creation
|
13
|
+
autoload :Draft
|
14
|
+
autoload :Draftable
|
15
|
+
autoload :DraftUpload
|
16
|
+
|
17
|
+
class << self
|
18
|
+
delegate :config, :configure, :to => Draft
|
19
|
+
delegate :config, :configure, :to => DraftUpload
|
20
|
+
end
|
21
|
+
|
22
|
+
included do
|
23
|
+
include Creation
|
24
|
+
include Draftable
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
ActiveRecord::Base.class_eval{ include Drafter }
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCreation < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
describe "Saving a draft of" do
|
6
|
+
describe "a new draftable article" do
|
7
|
+
before do
|
8
|
+
@article_count = Article.count
|
9
|
+
@draft_count = Draft.count
|
10
|
+
@draft_upload_count = DraftUpload.count
|
11
|
+
@article = Article.new(
|
12
|
+
:text => "original text",
|
13
|
+
:upload => file_upload
|
14
|
+
)
|
15
|
+
@draft = @article.save_draft
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not create a new draftable" do
|
19
|
+
assert_equal(@article_count, Article.count)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create a saved draft object" do
|
23
|
+
assert_equal(@draft_count + 1, Draft.count)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return the @draft object" do
|
27
|
+
assert_equal(Draft, @draft.class)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should save the contents of the :text attribute" do
|
31
|
+
assert_equal "original text", @draft.data["text"]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should create a DraftUpload object" do
|
35
|
+
assert_equal(@draft_upload_count + 1, DraftUpload.count)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should add the draft_upload to the Draft's array of them" do
|
39
|
+
assert_equal(1, @draft.draft_uploads.length)
|
40
|
+
assert_equal(DraftUpload.last, @draft.draft_uploads.first)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "an existing draftable article" do
|
45
|
+
before do
|
46
|
+
@draft_count = Draft.count
|
47
|
+
@draft_upload_count = DraftUpload.count
|
48
|
+
@article = Article.create!(:text => "original text")
|
49
|
+
@article.text = "draft text"
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "with a file upload" do
|
53
|
+
before do
|
54
|
+
@article.upload = file_upload
|
55
|
+
@draft = @article.save_draft
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "the article" do
|
59
|
+
it "should still have text of 'original text'" do
|
60
|
+
assert_equal("original text", @article.reload.text)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should have a draft attached" do
|
64
|
+
assert_equal(Draft, @article.draft.class)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should create a new draft" do
|
68
|
+
assert_equal(@draft_count + 1, Draft.count)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "the article's draft" do
|
73
|
+
it "has a serialized :text attribute with content 'draft text'" do
|
74
|
+
assert_equal('draft text', @article.draft.data["text"])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should create a DraftUpload object" do
|
78
|
+
assert_equal(@draft_upload_count + 1, DraftUpload.count)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should add the draft_upload to the Draft's array of them" do
|
82
|
+
assert_equal(1, @draft.draft_uploads.length)
|
83
|
+
assert_equal(DraftUpload.last, @draft.draft_uploads.first)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
describe "without a file upload" do
|
90
|
+
before do
|
91
|
+
@draft = @article.save_draft
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "the article" do
|
95
|
+
it "should still have text of 'original text'" do
|
96
|
+
assert_equal("original text", @article.reload.text)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have a draft attached" do
|
100
|
+
assert_equal(Draft, @article.draft.class)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should create a new draft" do
|
104
|
+
assert_equal(@draft_count + 1, Draft.count)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "the article's draft" do
|
109
|
+
it "has a serialized :text attribute with content 'draft text'" do
|
110
|
+
assert_equal('draft text', @article.draft.data["text"])
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "an invalid article" do
|
117
|
+
before do
|
118
|
+
@draft_count = Draft.count
|
119
|
+
@draft_upload_count = DraftUpload.count
|
120
|
+
@article = Article.create!(:text => "original text")
|
121
|
+
@article.text = ""
|
122
|
+
@article.upload = file_upload
|
123
|
+
@draft = @article.save_draft
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not create a Draft object" do
|
127
|
+
assert_equal(@draft_count, Draft.count)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should not create a DraftUpload object" do
|
131
|
+
assert_equal(@draft_upload_count, DraftUpload.count)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "sets up validation errors on the @article" do
|
135
|
+
assert_equal(1, @article.errors.count)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDraft < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
describe Draft do
|
6
|
+
subject { @draft = Draft.new }
|
7
|
+
describe "validations" do
|
8
|
+
it { must validate_presence_of(:data) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "associations" do
|
12
|
+
it { must belong_to(:draftable) }
|
13
|
+
it { must have_many(:draft_uploads) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Accessing draft data properties" do
|
18
|
+
before do
|
19
|
+
@draft = Draft.new(:data => {"foo" => "bar"})
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "through the data hash" do
|
23
|
+
it "works" do
|
24
|
+
assert_equal("bar", @draft.data["foo"])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "using dot notation" do
|
29
|
+
it "also works" do
|
30
|
+
assert_equal("bar", @draft.foo)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "Approving a draft" do
|
36
|
+
before do
|
37
|
+
@article = Article.new(
|
38
|
+
:text => "initial text",
|
39
|
+
:upload => file_upload)
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "for an article which hasn't yet been saved" do
|
43
|
+
before do
|
44
|
+
@article_count = Article.count
|
45
|
+
@draft = @article.save_draft
|
46
|
+
@draft_count = Draft.count
|
47
|
+
@article = @draft.approve!
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should create an article" do
|
51
|
+
assert_equal(@article_count + 1, Article.count)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return the saved article" do
|
55
|
+
assert_equal(Article, @article.class)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should properly populate all the attributes" do
|
59
|
+
assert_equal("initial text", @article.text)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should populate all the file uploads" do
|
63
|
+
assert_equal("foo.txt", @article.upload.filename)
|
64
|
+
assert_equal("foo foo foo", File.open(@article.upload.path).read)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should delete the article's draft" do
|
68
|
+
assert_equal(@draft_count - 1, Draft.count)
|
69
|
+
refute @article.draft
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "for an article which already exists" do
|
74
|
+
before do
|
75
|
+
@article.save
|
76
|
+
@article_count = Article.count
|
77
|
+
@article.text = "some draft text"
|
78
|
+
@article.upload = file_upload("bar.txt")
|
79
|
+
@draft = @article.save_draft
|
80
|
+
@draft_count = Draft.count
|
81
|
+
@draft.approve!
|
82
|
+
end
|
83
|
+
|
84
|
+
it "shouldn't do anything mental, like creating a new object" do
|
85
|
+
assert_equal(@article_count, Article.count)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should properly populate all the attributes" do
|
89
|
+
assert_equal("some draft text", @article.text)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should populate all the file uploads" do
|
93
|
+
assert_equal("bar.txt", @article.upload.filename)
|
94
|
+
assert_equal("bar bar bar", File.open(@article.upload.path).read)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should delete the article's draft" do
|
98
|
+
assert_equal(@draft_count - 1, Draft.count)
|
99
|
+
refute @article.reload.draft
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDraftUpload < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
describe DraftUpload do
|
6
|
+
subject { DraftUpload.new }
|
7
|
+
|
8
|
+
describe "validations" do
|
9
|
+
it { must validate_presence_of :file_data }
|
10
|
+
it { must validate_presence_of :draft }
|
11
|
+
it { must validate_presence_of :draftable_mount_column }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "associations" do
|
15
|
+
it { must belong_to :draft }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "uploading files" do
|
19
|
+
it "works" do
|
20
|
+
draft_upload = DraftUpload.new(
|
21
|
+
:file_data => file_upload,
|
22
|
+
:draft => Draft.create(:data => {:foo => :bar}),
|
23
|
+
:draftable_mount_column => :photo
|
24
|
+
)
|
25
|
+
assert draft_upload.save!
|
26
|
+
assert File.exist?(draft_upload.reload.file_data.path)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDraftable < MiniTest::Unit::TestCase
|
4
|
+
|
5
|
+
describe "A draftable ActiveRecord class" do
|
6
|
+
it "should know it's draftable" do
|
7
|
+
assert Article.draftable?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "A non-draftable ActiveRecord class" do
|
12
|
+
it "should know it's not draftable" do
|
13
|
+
refute Comment.draftable?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
bar bar bar
|
@@ -0,0 +1 @@
|
|
1
|
+
foo foo foo
|
data/test/helper.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'minitest/spec'
|
11
|
+
require 'debugger'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
14
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
15
|
+
|
16
|
+
require 'active_record'
|
17
|
+
require 'carrierwave'
|
18
|
+
require 'carrierwave/orm/activerecord'
|
19
|
+
require 'drafter'
|
20
|
+
require 'turn'
|
21
|
+
require 'minitest/matchers'
|
22
|
+
require "shoulda/matchers/active_record"
|
23
|
+
require "shoulda/matchers/active_model"
|
24
|
+
|
25
|
+
# Establish a connection to our test database
|
26
|
+
ActiveRecord::Base.establish_connection(
|
27
|
+
:adapter => "sqlite3",
|
28
|
+
:database => File.dirname(__FILE__) + "/drafter.sqlite3")
|
29
|
+
|
30
|
+
load File.dirname(__FILE__) + '/support/schema.rb'
|
31
|
+
load File.dirname(__FILE__) + '/support/uploader.rb'
|
32
|
+
load File.dirname(__FILE__) + '/support/models.rb'
|
33
|
+
load File.dirname(__FILE__) + '/support/data.rb'
|
34
|
+
|
35
|
+
class MiniTest::Unit::TestCase
|
36
|
+
|
37
|
+
# Pull in shoulda matchers for minitest.
|
38
|
+
#
|
39
|
+
# You need to have the minitest-matchers gem and the minitest-rails-shoulda gem
|
40
|
+
# for this to work.
|
41
|
+
include Shoulda::Matchers::ActiveRecord
|
42
|
+
extend Shoulda::Matchers::ActiveRecord
|
43
|
+
include Shoulda::Matchers::ActiveModel
|
44
|
+
extend Shoulda::Matchers::ActiveModel
|
45
|
+
|
46
|
+
def file_upload(name="foo.txt")
|
47
|
+
File.new(File.dirname(__FILE__) + "/fixtures/#{name}")
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
MiniTest::Unit.autorun
|
53
|
+
|
54
|
+
Turn.config do |c|
|
55
|
+
c.format = :outline
|
56
|
+
c.trace = false
|
57
|
+
c.natural = true
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Define models we can test with
|
2
|
+
|
3
|
+
# A draftable article class
|
4
|
+
class Article < ActiveRecord::Base
|
5
|
+
|
6
|
+
validates_presence_of :text
|
7
|
+
|
8
|
+
draftable
|
9
|
+
|
10
|
+
mount_uploader :upload, Uploader
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
# A non-draftable comment class
|
16
|
+
class Comment < ActiveRecord::Base
|
17
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Load up a database schema and force schema creation
|
2
|
+
ActiveRecord::Schema.define do
|
3
|
+
self.verbose = false
|
4
|
+
|
5
|
+
create_table :articles, :force => true do |t|
|
6
|
+
t.string :text
|
7
|
+
t.string :upload
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
create_table :drafts, :force => true do |t|
|
12
|
+
t.text :data
|
13
|
+
t.references :draftable, :polymorphic => true
|
14
|
+
end
|
15
|
+
|
16
|
+
change_table :drafts do |t|
|
17
|
+
t.index [:draftable_id, :draftable_type]
|
18
|
+
t.index :data
|
19
|
+
end
|
20
|
+
|
21
|
+
create_table :draft_uploads, :force => true do |t|
|
22
|
+
t.references :draft
|
23
|
+
t.string :draftable_mount_column
|
24
|
+
t.string :file_data
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/test/watchr.rb
ADDED
metadata
ADDED
@@ -0,0 +1,187 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: drafter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- futurechimp
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-17 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: &2160790860 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2160790860
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: sqlite3
|
27
|
+
requirement: &2160778900 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2160778900
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: debugger
|
38
|
+
requirement: &2160777900 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2160777900
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: minitest
|
49
|
+
requirement: &2160776580 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2160776580
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: bundler
|
60
|
+
requirement: &2160774900 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.0.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2160774900
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: jeweler
|
71
|
+
requirement: &2160773980 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.6.4
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2160773980
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rcov
|
82
|
+
requirement: &2160773220 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2160773220
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: turn
|
93
|
+
requirement: &2160772480 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *2160772480
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: carrierwave
|
104
|
+
requirement: &2160771780 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *2160771780
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: minitest-rails-shoulda
|
115
|
+
requirement: &2160771260 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *2160771260
|
124
|
+
description: A
|
125
|
+
email: dave.hrycyszyn@headlondon.com
|
126
|
+
executables: []
|
127
|
+
extensions: []
|
128
|
+
extra_rdoc_files:
|
129
|
+
- LICENSE.txt
|
130
|
+
- README.rdoc
|
131
|
+
files:
|
132
|
+
- .document
|
133
|
+
- Gemfile
|
134
|
+
- Gemfile.lock
|
135
|
+
- LICENSE.txt
|
136
|
+
- README.rdoc
|
137
|
+
- Rakefile
|
138
|
+
- VERSION
|
139
|
+
- drafter.gemspec
|
140
|
+
- lib/drafter.rb
|
141
|
+
- lib/drafter/creation.rb
|
142
|
+
- lib/drafter/draft.rb
|
143
|
+
- lib/drafter/draft_upload.rb
|
144
|
+
- lib/drafter/draft_uploader.rb
|
145
|
+
- lib/drafter/draftable.rb
|
146
|
+
- test/drafter/test_creation.rb
|
147
|
+
- test/drafter/test_draft.rb
|
148
|
+
- test/drafter/test_draft_upload.rb
|
149
|
+
- test/drafter/test_draftable.rb
|
150
|
+
- test/fixtures/bar.txt
|
151
|
+
- test/fixtures/foo.txt
|
152
|
+
- test/helper.rb
|
153
|
+
- test/support/data.rb
|
154
|
+
- test/support/models.rb
|
155
|
+
- test/support/schema.rb
|
156
|
+
- test/support/uploader.rb
|
157
|
+
- test/test_drafter.rb
|
158
|
+
- test/watchr.rb
|
159
|
+
homepage: http://github.com/futurechimp/drafter
|
160
|
+
licenses:
|
161
|
+
- MIT
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options: []
|
164
|
+
require_paths:
|
165
|
+
- lib
|
166
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ! '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
segments:
|
173
|
+
- 0
|
174
|
+
hash: 3420985019024950732
|
175
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
+
none: false
|
177
|
+
requirements:
|
178
|
+
- - ! '>='
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
requirements: []
|
182
|
+
rubyforge_project:
|
183
|
+
rubygems_version: 1.8.17
|
184
|
+
signing_key:
|
185
|
+
specification_version: 3
|
186
|
+
summary: Simple
|
187
|
+
test_files: []
|