letter_press 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in letter_press.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 "Anders Törnqvist"
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # LetterPress
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'letter_press'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install letter_press
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new(:spec) do |t|
6
+ t.libs.push "lib"
7
+ t.libs.push "spec"
8
+ t.test_files = FileList['spec/**/*_spec.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :test => :spec
13
+ task :default => :test
14
+
15
+ desc "open console (require 'letter_press')"
16
+ task :c do
17
+ system "irb -I lib -r letter_press"
18
+ end
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/letter_press/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Anders Törnqvist"]
6
+ gem.email = ["anders.tornqvist@gmail.com"]
7
+ gem.description = %q{A model factory}
8
+ gem.summary = %q{A model factory. Say no to fixtures.}
9
+ gem.homepage = "https://github.com/unders/letter_press"
10
+
11
+ gem.files = Dir.glob("{bin,lib,spec}/**/*") + %w[.gemtest
12
+ Gemfile
13
+ LICENSE
14
+ README.md
15
+ Rakefile
16
+ letter_press.gemspec]
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.name = "letter_press"
20
+ gem.require_paths = ["lib"]
21
+ gem.version = LetterPress::VERSION
22
+
23
+ gem.add_development_dependency "activerecord", "~> 3.1"
24
+ gem.add_development_dependency "railties", "~> 3.1"
25
+ gem.add_development_dependency "sqlite3", "~> 1.3.4"
26
+
27
+ gem.add_development_dependency "minitest", ["~> 2.12"]
28
+ gem.add_development_dependency "minitest-colorize", ["~> 0.0.4"]
29
+ end
@@ -0,0 +1,24 @@
1
+ module LetterPress
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ class_option :test_framework, :type => :string, :aliases => "-t",
7
+ :desc => "Test framework to use LetterPress with"
8
+
9
+ def blueprints_file
10
+ if rspec?
11
+ copy_file "blueprint.rb", "spec/blueprint.rb"
12
+ else
13
+ copy_file "blueprint.rb", "test/blueprint.rb"
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def rspec?
20
+ options[:test_framework].to_sym == :rspec
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # endcoding: utf-8
2
+ module LetterPress
3
+ # Add your blueprints here.
4
+ #
5
+ # e.g.
6
+ # class User < Blueprint(ProxyMethods)
7
+ # default do
8
+ # name { "Anders" }
9
+ # admin { false }
10
+ # end
11
+ #
12
+ # define(:admin) do
13
+ # admin { true }
14
+ # end
15
+ # end
16
+ #
17
+ # class Post < Blueprint(ProxyMethods)
18
+ # default do
19
+ # title { "Post #{sn}" }
20
+ # body { "Lorem ipsum...#" }
21
+ # end
22
+ # end
23
+ end
@@ -0,0 +1,29 @@
1
+ module LetterPress
2
+ module Generators
3
+ class ModelGenerator < Rails::Generators::NamedBase
4
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
5
+
6
+ def create_blueprint
7
+ file_name = if File.exists?(File.join(Rails.root, 'test', 'blueprint.rb'))
8
+ "test/blueprint.rb"
9
+ elsif File.exists?(File.join(Rails.root, 'spec', 'blueprint.rb'))
10
+ "spec/blueprint.rb"
11
+ else
12
+ raise "Cannot find the blueprint file"
13
+ end
14
+ gsub_file(file_name, /.end\s*\Z/mx) { |match| "#{code}\n#{match}" }
15
+ end
16
+
17
+ private
18
+
19
+ def code
20
+ %Q{\n
21
+ class #{class_name} < Blueprint(ProxyMethods)
22
+ default do
23
+ #{attributes.map { |a| "#{a.name} { #{a.default.inspect} }" }.join("\n ")}
24
+ end
25
+ end}
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ require "letter_press/version"
3
+ require "letter_press/blueprint"
4
+
5
+ module LetterPress
6
+ def self.Blueprint(jayz_module)
7
+ Class.new(Blueprint) do
8
+ include jayz_module
9
+ end
10
+ end
11
+
12
+ def make(*args)
13
+ name.split('::').inject(LetterPress) do |klass_level, name|
14
+ klass_level.const_get(name)
15
+ end.make(*args)
16
+ end
17
+
18
+ module ProxyMethods
19
+ def new
20
+ if @object.valid?
21
+ @object
22
+ else
23
+ fail ActiveRecord::RecordInvalid.new(@object)
24
+ end
25
+ end
26
+
27
+ def new!
28
+ @object
29
+ end
30
+
31
+ def save
32
+ @object.tap { |record| record.save! }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,81 @@
1
+ require 'letter_press/serial_number'
2
+ require 'letter_press/ghost'
3
+
4
+ module LetterPress
5
+ class Blueprint; end
6
+
7
+ class << Blueprint
8
+ def make(*args)
9
+ new(*args)
10
+ end
11
+
12
+ def default(options={}, &block)
13
+ if block_given?
14
+ ghosts[:default] = Ghost.new(serial_number).instance_eval(&block)
15
+ else
16
+ hash = options.merge({})
17
+ default = ghosts[:default]
18
+ (default.keys - options.keys).each do |key|
19
+ hash[key] = default.send(key)
20
+ end
21
+ hash
22
+ end
23
+ end
24
+
25
+ def define(method, &block)
26
+ ghosts[method] = Ghost.new(serial_number).instance_eval(&block)
27
+ self.class.send(:define_method, method) do |options={}|
28
+ hash = options.merge({})
29
+ blueprint = ghosts[method]
30
+ blueprint_keys = blueprint.keys
31
+ (blueprint_keys - options.keys).each do |key|
32
+ hash[key] = blueprint.send(key)
33
+ end
34
+
35
+ default = ghosts.fetch(:default, {})
36
+ (default.keys - blueprint_keys).each do |key|
37
+ hash[key] = default.send(key)
38
+ end
39
+
40
+ hash
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def ghosts
47
+ @ghosts ||={}
48
+ end
49
+
50
+ def serial_number
51
+ @serial_number ||= SerialNumber.new
52
+ end
53
+ end
54
+
55
+ class Blueprint
56
+ def initialize(*args)
57
+ symbol = args.first.is_a?(Symbol) ? args.first : :default
58
+ options = args.last.is_a?(Hash) ? args.pop : {}
59
+ klass_names = self.class.name.sub('LetterPress::', '').split('::')
60
+ @object = klass_names.inject(Kernel) do |klass_level, name|
61
+ klass_level.const_get(name)
62
+ end.new
63
+
64
+ self.class.send(symbol, options).each do |key, value|
65
+ @object.send("#{key}=", value)
66
+ end
67
+ end
68
+
69
+ def new
70
+ @object
71
+ end
72
+
73
+ def method_missing(method, *args, &block)
74
+ @object.send(method, *args, &block)
75
+ end
76
+
77
+ def respond_to_missing?(method, *)
78
+ @object.respond_to?(method)
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,27 @@
1
+ module LetterPress
2
+ class Ghost
3
+ def initialize(serial_number)
4
+ @serial_number = serial_number
5
+ end
6
+
7
+ def sn
8
+ @serial_number.next
9
+ end
10
+
11
+ def keys
12
+ @keys ||= []
13
+ end
14
+
15
+ def method_missing(method, *args, &block)
16
+ if block_given?
17
+ keys << method
18
+ m = Module.new do
19
+ define_method(method, &block)
20
+ end
21
+ extend m
22
+ else
23
+ super
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ require 'letter_press'
2
+ require 'letter_press/railtie'
3
+
4
+ ActiveRecord::Base.extend(LetterPress)
@@ -0,0 +1,14 @@
1
+ module LetterPress
2
+ class Railtie < Rails::Railtie
3
+ config.after_initialize do
4
+ blueprints = [ File.join(Rails.root, 'test', 'blueprint'),
5
+ File.join(Rails.root, 'spec', 'blueprint')]
6
+ blueprints.each do |path|
7
+ if File.exists?("#{path}.rb")
8
+ load("#{path}.rb")
9
+ break
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module LetterPress
2
+ class SerialNumber
3
+ def next
4
+ @next ||=0
5
+ @next += 1
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,3 @@
1
+ module LetterPress
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,181 @@
1
+ # encoding: utf-8
2
+ require 'minitest_helper'
3
+
4
+ module LetterPress
5
+ module Admin
6
+ class User < Blueprint; end
7
+ end
8
+ class User < Blueprint; end
9
+ class Comment < Blueprint; end
10
+ end
11
+
12
+ class User
13
+ extend LetterPress
14
+ attr_accessor :name
15
+ def self.counter; @counter; end
16
+ def self.counter=(c); @counter = c; end
17
+ def initialize; self.class.counter = 0; end
18
+ def save; self.class.counter += 1; end
19
+ end
20
+
21
+ class Comment
22
+ extend LetterPress
23
+ attr_accessor :user
24
+ attr_accessor :body
25
+ end
26
+
27
+ module Admin
28
+ class User
29
+ extend LetterPress
30
+ attr_accessor :name
31
+ end
32
+ end
33
+
34
+ describe LetterPress::Blueprint do
35
+ describe ".make" do
36
+ it "creates an instance" do
37
+ LetterPress::User.make.must_be_instance_of(LetterPress::User)
38
+ end
39
+ end
40
+
41
+ describe ".default" do
42
+ before do
43
+ LetterPress::User.default do
44
+ name { "User 1" }
45
+ end
46
+ end
47
+
48
+ describe "when called with a block" do
49
+ it "saves the block" do
50
+ LetterPress::User.default.must_equal :name => 'User 1'
51
+ end
52
+ end
53
+
54
+ describe "when called without a block" do
55
+ it "returns a hash" do
56
+ LetterPress::User.default.must_equal :name => 'User 1'
57
+ end
58
+ end
59
+ end
60
+
61
+ describe ".define" do
62
+ before do
63
+ LetterPress::Comment.define(:admin) do
64
+ user { LetterPress::User.make(:name => 'Anders Admin').new }
65
+ end
66
+ end
67
+
68
+ describe "when called with a block" do
69
+ it "creates a class method specified by the symbol name" do
70
+ LetterPress::Comment.admin[:user].name.must_equal 'Anders Admin'
71
+ end
72
+
73
+ it "saves the block" do
74
+ LetterPress::Comment.admin[:user].name.must_equal 'Anders Admin'
75
+ end
76
+ end
77
+
78
+ describe "when called without a block" do
79
+ it "returns a hash" do
80
+ LetterPress::Comment.admin[:user].name.must_equal 'Anders Admin'
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "when the default block values is used" do
86
+ before do
87
+ LetterPress::Comment.default do
88
+ user { User.make(:name => 'Anders Default').new }
89
+ body { 'I am defined in default' }
90
+ end
91
+ LetterPress::Comment.define(:spam) do
92
+ user { User.make(:name => 'Anders Spam').new }
93
+ end
94
+ end
95
+
96
+ describe "when .define(:spam) has not defined the method in its block" do
97
+ it "returns the body defined in the default block" do
98
+ LetterPress::Comment.spam[:body].must_equal 'I am defined in default'
99
+ end
100
+ end
101
+ describe "when .define(:spam) has defined the method in its block" do
102
+ it "returns the value from the spam block" do
103
+ LetterPress::Comment.spam[:user].name.must_equal 'Anders Spam'
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "serial number interpolation with sn method" do
109
+ before do
110
+ LetterPress::User.default do
111
+ name { "User #{sn}" }
112
+ end
113
+ LetterPress::User.define(:admin) do
114
+ name { "Admin #{sn}" }
115
+ end
116
+ end
117
+
118
+ it "returns the next number for each hash" do
119
+ LetterPress::User.admin[:name].must_equal "Admin 1"
120
+ LetterPress::User.default[:name].must_equal "User 2"
121
+ LetterPress::User.default[:name].must_equal "User 3"
122
+ LetterPress::User.admin[:name].must_equal "Admin 4"
123
+ end
124
+ end
125
+
126
+ describe "#new" do
127
+ before do
128
+ LetterPress::User.default do
129
+ name { 'Anders' }
130
+ end
131
+ end
132
+ it "returns the correct object" do
133
+ LetterPress::User.make.new.must_be_instance_of(User)
134
+ end
135
+
136
+ it "populates the returned object with the defined values" do
137
+ LetterPress::User.make.new.name.must_equal 'Anders'
138
+ end
139
+ end
140
+
141
+ describe "when a message is sent to the instance" do
142
+ before do
143
+ LetterPress::User.default do
144
+ name { 'Anders' }
145
+ end
146
+ end
147
+ it "delegates that message" do
148
+ LetterPress::User.make.save.must_equal 1
149
+ end
150
+ end
151
+
152
+ describe "blocks are not executed when defined" do
153
+ before do
154
+ LetterPress::User.default do
155
+ name { 'Anders' }
156
+ end
157
+ LetterPress::Comment.default do
158
+ user { User.make.save }
159
+ end
160
+ end
161
+
162
+ it "executes the defined block when its method is called" do
163
+ LetterPress::Comment.default
164
+ User.counter.must_equal 1
165
+ end
166
+ end
167
+
168
+ describe "can handle classes within a module namespace" do
169
+ before do
170
+ LetterPress::Admin::User.default do
171
+ name { "Anders is admin" }
172
+ end
173
+ end
174
+
175
+ it "returns the correct object populated with the default values" do
176
+ user = Admin::User.make.new
177
+ user.must_be_instance_of(Admin::User)
178
+ user.name.must_equal "Anders is admin"
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,43 @@
1
+ require 'minitest_helper'
2
+
3
+ describe LetterPress::Ghost do
4
+ before do
5
+ def Object.next; 1; end
6
+ @ghost = LetterPress::Ghost.new(Object)
7
+ end
8
+
9
+ describe "#keys" do
10
+ it "returns a collection of all messages sent to the object" do
11
+ @ghost.title { 'block' }
12
+ @ghost.body { 'block' }
13
+ @ghost.keys.must_equal [:title, :body]
14
+ end
15
+ end
16
+
17
+ describe "#sn" do
18
+ it "returns a serial number" do
19
+ @ghost.sn.must_equal 1
20
+ end
21
+ end
22
+
23
+ describe "a message with a block is sent to the object" do
24
+ it "creates a method that returns the content of the block" do
25
+ @ghost.title { 'I am a block' }
26
+ @ghost.title.must_equal 'I am a block'
27
+ end
28
+
29
+ it "doesn't execute the code inside the block until the method is called" do
30
+ def Object.counter; @counter ||= 0; @counter +=1; end
31
+ @ghost.title { Object.counter }
32
+ @ghost.title.must_equal 1
33
+ @ghost.title.must_equal 2
34
+ end
35
+ end
36
+
37
+ describe "a message is sent with a block containing a string with \#{sn}" do
38
+ it "interporlates the sn number" do
39
+ @ghost.town { "I am ghost town number-#{sn}" }
40
+ @ghost.town.must_equal "I am ghost town number-1"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,208 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rails/railtie'
4
+ require 'active_record'
5
+ require 'letter_press/rails'
6
+ require 'minitest_helper'
7
+
8
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3",
9
+ :database => ":memory:")
10
+
11
+ ActiveRecord::Schema.define do
12
+ create_table :posts do |t|
13
+ t.string :title
14
+ t.text :body
15
+ t.integer :author_id
16
+ end
17
+ create_table :authors do |t|
18
+ t.string :name
19
+ end
20
+ create_table :author_users do |t|
21
+ t.string :name
22
+ end
23
+ create_table :bars do |t|
24
+ t.string :name
25
+ end
26
+ end
27
+
28
+ class Post < ActiveRecord::Base
29
+ belongs_to :author
30
+ validates_presence_of :title
31
+ validates_presence_of :author_id
32
+ validates_uniqueness_of :title
33
+ end
34
+
35
+ class Author < ActiveRecord::Base
36
+ validates_presence_of :name
37
+ class User < ActiveRecord::Base
38
+ validates_presence_of :name
39
+ end
40
+ end
41
+
42
+ module Foo
43
+ class Bar < ActiveRecord::Base
44
+ validates_presence_of :name
45
+ end
46
+ end
47
+
48
+ # blueprint.rb
49
+ module LetterPress
50
+ class Author < Blueprint(ProxyMethods)
51
+ default do
52
+ name { "Anders" }
53
+ end
54
+
55
+ class User < LetterPress::Blueprint(ProxyMethods)
56
+ default do
57
+ name { "Anders is the user" }
58
+ end
59
+ end
60
+ end
61
+
62
+ class Post < Blueprint(ProxyMethods)
63
+ default do
64
+ title { "Post #{sn}" }
65
+ body { "Lorem ipsum..." }
66
+ author { Author.make.save }
67
+ end
68
+ end
69
+
70
+ module Foo
71
+ class Bar < LetterPress::Blueprint(ProxyMethods)
72
+ default do
73
+ name { 'I am Foo::Bar' }
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ describe "ProxyMethods" do
80
+ describe ".make" do
81
+ it "returns a proxy object" do
82
+ Post.make.must_be_instance_of(LetterPress::Post)
83
+ end
84
+ end
85
+
86
+ describe "#new" do
87
+ describe "a valid object" do
88
+ before { @post = Post.make.new }
89
+ it "returns a populated record" do
90
+ @post.must_be_instance_of(Post)
91
+ @post.body.must_equal "Lorem ipsum..."
92
+ end
93
+
94
+ it "does not persist the record" do
95
+ Post.count.must_equal 0
96
+ end
97
+ end
98
+
99
+ describe "an invalid object" do
100
+ it "raises an exception" do
101
+ lambda {
102
+ Post.make(:author => nil).new
103
+ }.must_raise(ActiveRecord::RecordInvalid)
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "#new!" do
109
+ describe "a valid object" do
110
+ before { @post2 = Post.make.new! }
111
+ it "returns a populated record" do
112
+ @post2.must_be_instance_of(Post)
113
+ @post2.body.must_equal "Lorem ipsum..."
114
+ end
115
+
116
+ it "does not persist the record" do
117
+ Post.count.must_equal 0
118
+ end
119
+ end
120
+
121
+ describe "an invalid object" do
122
+ it "returns a populated object" do
123
+ Post.make(:author => nil).new!.body.must_equal "Lorem ipsum..."
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "#save" do
129
+ before { @post3 = Post.make.save }
130
+
131
+ describe "a valid object" do
132
+ it "persists and returns a populated record" do
133
+ @post3.must_be_instance_of(Post)
134
+ @post3.body.must_equal "Lorem ipsum..."
135
+ Post.count.must_equal 1
136
+ end
137
+ end
138
+
139
+ describe "an invalid object" do
140
+ it "raises an exception" do
141
+ lambda {
142
+ Post.make(:author => nil).save
143
+ }.must_raise(ActiveRecord::RecordInvalid)
144
+ end
145
+ end
146
+ end
147
+
148
+ describe 'makes fields uniq with #{sn}' do
149
+ before do
150
+ user = Author.make.save
151
+ @post_count = Post.count
152
+ @post1 = Post.make(:author => user).save
153
+ @post2 = Post.make(:author => user).save
154
+ @post3 = Post.make(:author => user).save
155
+ @post4 = Post.make(:author => user).save
156
+ end
157
+
158
+ it "creates object that has uniq fields" do
159
+ @post1.valid?.must_equal true
160
+ @post2.valid?.must_equal true
161
+ @post3.valid?.must_equal true
162
+ @post4.valid?.must_equal true
163
+ Post.count.must_equal (@post_count + 4)
164
+ end
165
+
166
+ after do
167
+ Post.delete_all
168
+ end
169
+ end
170
+
171
+ describe "can handle classes namespaced by other classes" do
172
+ before do
173
+ @user = Author::User.make.save
174
+ end
175
+
176
+ it "returns a populated record" do
177
+ @user.must_be_instance_of(Author::User)
178
+ @user.name.must_equal "Anders is the user"
179
+ end
180
+
181
+ it "creates a author user record" do
182
+ Author::User.count.must_equal 1
183
+ end
184
+
185
+ after do
186
+ Author::User.delete_all
187
+ end
188
+ end
189
+
190
+ describe "handles classes namespace by an module" do
191
+ before do
192
+ @bar = Foo::Bar.make.save
193
+ end
194
+
195
+ it "returns a populated record" do
196
+ @bar.must_be_instance_of(Foo::Bar)
197
+ @bar.name.must_equal "I am Foo::Bar"
198
+ end
199
+
200
+ it "creates a bar record" do
201
+ Foo::Bar.count.must_equal 1
202
+ end
203
+
204
+ after do
205
+ Foo::Bar.delete_all
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,21 @@
1
+ require 'minitest_helper'
2
+ describe LetterPress::SerialNumber do
3
+ before do
4
+ @serial_number = LetterPress::SerialNumber.new
5
+ end
6
+
7
+ describe "#next" do
8
+ describe "when called the first time" do
9
+ it "returns 1" do
10
+ @serial_number.next.must_equal 1
11
+ end
12
+ end
13
+
14
+ describe "when called the second time" do
15
+ it "returns the consecutive number" do
16
+ number = @serial_number.next
17
+ @serial_number.next.must_equal (number + 1)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+ require 'minitest_helper'
3
+
4
+ module LetterPress
5
+ class Blog < Blueprint
6
+ default do
7
+ writer { Writer.make.save }
8
+ body { "I am a default post body" }
9
+ end
10
+
11
+ define(:video) do
12
+ writer { Writer.make(:name => 'Anders defined in Blog.video').save }
13
+ url { 'http://www.youtube.com/watch?v=g5950v0kTJg' }
14
+ end
15
+ end
16
+
17
+ class Writer < Blueprint
18
+ default do
19
+ name { 'Anders Törnqvist' }
20
+ end
21
+ end
22
+ end
23
+
24
+ class Blog
25
+ extend LetterPress
26
+ attr_accessor :writer
27
+ attr_accessor :body
28
+ attr_accessor :url
29
+ def save; 'save in post called'; end
30
+ def save!; self; end
31
+ end
32
+
33
+ class Writer
34
+ extend LetterPress
35
+ attr_accessor :name
36
+ def save; self; end
37
+ end
38
+
39
+ describe LetterPress do
40
+ describe "when extending a class with the LetterPress module" do
41
+ it "adds a .make method" do
42
+ Blog.make.must_be_instance_of(LetterPress::Blog)
43
+ end
44
+
45
+ describe ".make" do
46
+ it "creates a blueprint proxy object" do
47
+ Blog.make.must_be_instance_of(LetterPress::Blog)
48
+ end
49
+ end
50
+
51
+ describe "blueprint proxy object" do
52
+ it "delegate all messages" do
53
+ Blog.make.save.must_equal 'save in post called'
54
+ end
55
+ end
56
+
57
+ describe "before it delegates a message" do
58
+ it "populates the receiver with values from the blueprint" do
59
+ Blog.make.save!.body.must_equal 'I am a default post body'
60
+ end
61
+ end
62
+
63
+ describe ".make message with a symbol argument" do
64
+ before { @video = Blog.make(:video).save! }
65
+ it "populates the receiver with values defined in the video block" do
66
+ @video.url.must_equal 'http://www.youtube.com/watch?v=g5950v0kTJg'
67
+ end
68
+
69
+ it %q{populates the receiver with values from the default block if not
70
+ defined in video block} do
71
+ @video.body.must_equal 'I am a default post body'
72
+ end
73
+
74
+ describe "inside a blueprint block" do
75
+ it "can create other objects" do
76
+ @video.writer.name.must_equal 'Anders defined in Blog.video'
77
+ end
78
+ end
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,7 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest-colorize'
3
+ require "letter_press"
4
+
5
+ Kernel.instance_eval do
6
+ alias_method :context, :describe
7
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: letter_press
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Anders Törnqvist
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.1'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: railties
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.1'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.1'
46
+ - !ruby/object:Gem::Dependency
47
+ name: sqlite3
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.3.4
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.4
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '2.12'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '2.12'
78
+ - !ruby/object:Gem::Dependency
79
+ name: minitest-colorize
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.0.4
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.0.4
94
+ description: A model factory
95
+ email:
96
+ - anders.tornqvist@gmail.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - lib/generators/letter_press/install/install_generator.rb
102
+ - lib/generators/letter_press/install/templates/blueprint.rb
103
+ - lib/generators/letter_press/model/model_generator.rb
104
+ - lib/letter_press/blueprint.rb
105
+ - lib/letter_press/ghost.rb
106
+ - lib/letter_press/rails.rb
107
+ - lib/letter_press/railtie.rb
108
+ - lib/letter_press/serial_number.rb
109
+ - lib/letter_press/version.rb
110
+ - lib/letter_press.rb
111
+ - spec/letter_press/blueprint_spec.rb
112
+ - spec/letter_press/ghost_spec.rb
113
+ - spec/letter_press/rails_spec.rb
114
+ - spec/letter_press/serial_number_spec.rb
115
+ - spec/letter_press_spec.rb
116
+ - spec/minitest_helper.rb
117
+ - .gemtest
118
+ - Gemfile
119
+ - LICENSE
120
+ - README.md
121
+ - Rakefile
122
+ - letter_press.gemspec
123
+ homepage: https://github.com/unders/letter_press
124
+ licenses: []
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project:
143
+ rubygems_version: 1.8.21
144
+ signing_key:
145
+ specification_version: 3
146
+ summary: A model factory. Say no to fixtures.
147
+ test_files:
148
+ - spec/letter_press/blueprint_spec.rb
149
+ - spec/letter_press/ghost_spec.rb
150
+ - spec/letter_press/rails_spec.rb
151
+ - spec/letter_press/serial_number_spec.rb
152
+ - spec/letter_press_spec.rb
153
+ - spec/minitest_helper.rb