letter_press 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/.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