to_factory 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rspec +2 -1
- data/.travis.yml +23 -0
- data/Gemfile +3 -13
- data/README.md +59 -20
- data/Rakefile +20 -14
- data/bin/ci +2 -0
- data/bin/spec +2 -0
- data/lib/to_factory/collation.rb +34 -0
- data/lib/to_factory/config.rb +18 -0
- data/lib/to_factory/definition_group.rb +47 -0
- data/lib/to_factory/file_sync.rb +48 -0
- data/lib/to_factory/file_writer.rb +39 -0
- data/lib/to_factory/finders/factory.rb +17 -0
- data/lib/to_factory/finders/model.rb +47 -0
- data/lib/to_factory/generation/attribute.rb +52 -0
- data/lib/to_factory/generation/factory.rb +74 -0
- data/lib/to_factory/parsing/file.rb +38 -0
- data/lib/to_factory/parsing/new_syntax.rb +9 -0
- data/lib/to_factory/parsing/old_syntax.rb +9 -0
- data/lib/to_factory/parsing/syntax.rb +86 -0
- data/lib/to_factory/version.rb +1 -1
- data/lib/to_factory.rb +55 -1
- data/spec/db/migrate/{201108201012010100_create_users.rb → 1_create_users.rb} +0 -0
- data/spec/db/migrate/2_create_projects.rb +13 -0
- data/spec/db/migrate/3_create_not_namespaced.rb +11 -0
- data/spec/db/migrate/4_add_birthday_to_users.rb +9 -0
- data/spec/example_factories/new_syntax/admin.rb +6 -0
- data/spec/example_factories/new_syntax/admin_with_header.rb +8 -0
- data/spec/example_factories/new_syntax/project_with_header.rb +7 -0
- data/spec/example_factories/new_syntax/user.rb +6 -0
- data/spec/example_factories/new_syntax/user_admin.rb +13 -0
- data/spec/example_factories/new_syntax/user_admin_with_header.rb +15 -0
- data/spec/example_factories/new_syntax/user_with_header.rb +8 -0
- data/spec/example_factories/old_syntax/admin.rb +6 -0
- data/spec/example_factories/old_syntax/project_with_header.rb +5 -0
- data/spec/example_factories/old_syntax/user.rb +6 -0
- data/spec/example_factories/old_syntax/user_admin.rb +13 -0
- data/spec/example_factories/old_syntax/user_admin_with_header.rb +13 -0
- data/spec/example_factories/old_syntax/user_with_header.rb +6 -0
- data/spec/integration/config_spec.rb +19 -0
- data/spec/integration/file_sync_spec.rb +77 -0
- data/spec/integration/file_writer_spec.rb +16 -0
- data/spec/integration/generate_class_method_spec.rb +107 -0
- data/spec/integration/lint_spec.rb +16 -0
- data/spec/spec_helper.rb +90 -14
- data/spec/support/match_sexp.rb +24 -0
- data/spec/support/models/not_active_record.rb +2 -0
- data/spec/support/models/project.rb +3 -0
- data/spec/support/models/user.rb +3 -0
- data/spec/support/terse_expect_syntax.rb +23 -0
- data/spec/unit/collation_spec.rb +35 -0
- data/spec/unit/definition_group_spec.rb +19 -0
- data/spec/unit/file_writer_spec.rb +28 -0
- data/spec/unit/finders/factory_spec.rb +27 -0
- data/spec/unit/finders/model_spec.rb +28 -0
- data/spec/unit/generator_spec.rb +71 -0
- data/spec/unit/parsing/file_spec.rb +83 -0
- data/tmp/.keep +0 -0
- data/to_factory.gemspec +49 -22
- metadata +225 -25
- data/.rvmrc +0 -1
- data/Gemfile.lock +0 -113
- data/lib/to_factory/generator.rb +0 -115
- data/spec/config/database.yml +0 -2
- data/spec/db/test.sqlite +0 -0
- data/spec/generator_spec.rb +0 -166
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
--
|
1
|
+
--color
|
2
|
+
--require spec_helper
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -1,16 +1,6 @@
|
|
1
|
-
source "
|
2
|
-
source "http://gems.github.com"
|
1
|
+
source "https://rubygems.org"
|
3
2
|
|
4
|
-
|
5
|
-
gem
|
6
|
-
gem 'rspec'
|
7
|
-
gem 'wirble'
|
8
|
-
gem 'spork'
|
9
|
-
gem 'activesupport', "~>3.0"
|
10
|
-
gem 'sqlite3'
|
11
|
-
gem 'ruby-debug'
|
12
|
-
gem 'activerecord'
|
3
|
+
if RUBY_VERSION != "1.8.7"
|
4
|
+
gem "codeclimate-test-reporter", :group => :test, :require => nil
|
13
5
|
end
|
14
|
-
|
15
|
-
# Specify your gem's dependencies in to_factory.gemspec
|
16
6
|
gemspec
|
data/README.md
CHANGED
@@ -1,41 +1,80 @@
|
|
1
1
|
ToFactory
|
2
2
|
=========
|
3
|
-
This is a little convenience gem for the scenario where
|
4
|
-
you find yourself writing factories for a pre-existing project.
|
5
3
|
|
6
|
-
|
7
|
-
|
4
|
+
[![Build Status](https://travis-ci.org/markburns/to_factory.svg)](https://travis-ci.org/markburns/to_factory)
|
5
|
+
[![Dependency Status](http://img.shields.io/gemnasium/markburns/to_factory.svg)](https://gemnasium.com/markburns/to_factory)
|
6
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/markburns/to_factory.svg)](https://codeclimate.com/github/markburns/to_factory)
|
7
|
+
[![Test Coverage](https://codeclimate.com/github/markburns/to_factory/badges/coverage.svg)](https://codeclimate.com/github/markburns/to_factory)
|
8
|
+
[![Gem Version](http://img.shields.io/gem/v/to_factory.svg)](https://rubygems.org/gems/to_factory)
|
9
|
+
[![License](http://img.shields.io/:license-mit-blue.svg)](http://markburns.mit-license.org)
|
10
|
+
[![Badges](http://img.shields.io/:badges-6/6-ff6799.svg)](https://github.com/badges/badgerbadgerbadger)
|
8
11
|
|
9
|
-
|
10
|
-
|
12
|
+
Easily add factories with valid data for an existing project.
|
13
|
+
|
14
|
+
If you find yourself working on a project without tests/factories or only using fixtures,
|
15
|
+
then use this gem to quickly generate a factory from an existing object.
|
16
|
+
|
17
|
+
Tested against Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.x
|
18
|
+
|
19
|
+
Reads and writes both new `FactoryGirl`, syntax or older `Factory.define` syntax
|
11
20
|
|
12
|
-
|
21
|
+
#Installation
|
22
|
+
___________
|
13
23
|
|
14
24
|
```ruby
|
15
25
|
|
16
26
|
#Gemfile
|
17
|
-
|
27
|
+
#add to whichever environments you want to generate data from
|
28
|
+
group :test, :development do
|
18
29
|
gem 'to_factory'
|
19
30
|
end
|
20
31
|
```
|
21
32
|
|
33
|
+
#Usage
|
22
34
|
|
23
|
-
```
|
24
|
-
|
25
|
-
|
35
|
+
```ruby
|
36
|
+
#Generate all factories
|
37
|
+
ToFactory()
|
26
38
|
|
27
|
-
|
28
|
-
|
39
|
+
#outputs the first record of each ActiveRecord::Base subclass in the models folder
|
40
|
+
#to spec/factories
|
29
41
|
|
30
|
-
|
31
|
-
#
|
42
|
+
#Choose input/output directories
|
43
|
+
ToFactory.models = "models/this/subfolder/only" #default "./app/models"
|
44
|
+
ToFactory.factories = "spec/support/factories" #default "./spec/factories"
|
45
|
+
ToFactory()
|
32
46
|
|
33
|
-
|
47
|
+
#Exclude classes
|
48
|
+
ToFactory(exclude: [User, Project])
|
34
49
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
50
|
+
#Use Adhoc instances from the console
|
51
|
+
ToFactory User.last
|
52
|
+
|
53
|
+
#writes to spec/factories/user.rb
|
54
|
+
FactoryGirl.define
|
55
|
+
factory(:user) do |u|
|
56
|
+
email "test@example.com"
|
57
|
+
name "Mike"
|
58
|
+
end
|
39
59
|
end
|
40
60
|
|
61
|
+
#doesn't overwrite existing factories
|
62
|
+
ToFactory User.last
|
63
|
+
#Exception =>
|
64
|
+
#ToFactory::AlreadyExists: an item for each of the following keys :user already exists
|
65
|
+
|
66
|
+
#Choose specific name
|
67
|
+
ToFactory :admin => User.last
|
68
|
+
#appends to spec/factories/user.rb
|
69
|
+
|
41
70
|
```
|
71
|
+
|
72
|
+
#Other useful projects
|
73
|
+
|
74
|
+
If you are adding specs to an existing project you may want to look at:
|
75
|
+
|
76
|
+
* [rspec-kickstarter](https://github.com/seratch/rspec-kickstarter) (auto generate specs)
|
77
|
+
* [rspec-kickstarter-vintage](https://github.com/ifad/rspec-kickstarter-vintage) (for Ruby 1.8/Rspec 1.x)
|
78
|
+
* [hash_syntax](https://github.com/michaeledgar/hash_syntax) (convert 1.8 syntax to 1.9 and vice-versa)
|
79
|
+
* [transpec](https://github.com/yujinakayama/transpec) (convert old rspec syntax to new expect syntax)
|
80
|
+
|
data/Rakefile
CHANGED
@@ -1,18 +1,24 @@
|
|
1
|
-
require
|
2
|
-
require 'logger'
|
3
|
-
require 'active_record'
|
4
|
-
require 'yaml'
|
1
|
+
require "bundler/gem_tasks"
|
5
2
|
|
6
|
-
namespace :
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
namespace :spec do
|
4
|
+
desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x"
|
5
|
+
task :migrate_db do
|
6
|
+
require 'logger'
|
7
|
+
require 'active_record'
|
8
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => "spec/db/test.sqlite3")
|
9
|
+
ActiveRecord::Base.logger = Logger.new(File.open('tmp/database.log', 'a'))
|
10
|
+
ActiveRecord::Migrator.migrate('spec/db/migrate')
|
11
|
+
end
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
begin
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
RSpec::Core::RakeTask.new do |t|
|
17
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
18
|
+
t.pattern = 'spec/**/*_spec.rb'
|
17
19
|
end
|
20
|
+
task :default => :spec
|
21
|
+
rescue LoadError
|
22
|
+
|
18
23
|
end
|
24
|
+
|
data/bin/ci
ADDED
data/bin/spec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module ToFactory
|
2
|
+
AlreadyExists = Class.new ArgumentError
|
3
|
+
|
4
|
+
class Collation
|
5
|
+
def self.merge(a, b)
|
6
|
+
c = new
|
7
|
+
|
8
|
+
c.merge_without_collisions(a.with_indifferent_access, b.with_indifferent_access)
|
9
|
+
end
|
10
|
+
|
11
|
+
def merge_without_collisions(a,b)
|
12
|
+
nested_detect_collisions!(a, b)
|
13
|
+
|
14
|
+
a.deep_merge(b)
|
15
|
+
end
|
16
|
+
|
17
|
+
def nested_detect_collisions!(a,b)
|
18
|
+
a.each do |a_klass, _|
|
19
|
+
b.each do |b_klass, _|
|
20
|
+
detect_collisions!(a[a_klass] || {}, b[b_klass] || {})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def detect_collisions!(a, b)
|
26
|
+
overlapping = a.keys & b.keys
|
27
|
+
raise_already_exists!(overlapping) if overlapping.any?
|
28
|
+
end
|
29
|
+
|
30
|
+
def raise_already_exists!(keys)
|
31
|
+
raise ToFactory::AlreadyExists.new "an item for each of the following keys #{keys} already exists"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ToFactory
|
2
|
+
class << self
|
3
|
+
attr_accessor :factories, :models
|
4
|
+
|
5
|
+
def reset_config!
|
6
|
+
@factories = nil
|
7
|
+
@models = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def factories
|
11
|
+
@factories ||= "./spec/factories"
|
12
|
+
end
|
13
|
+
|
14
|
+
def models
|
15
|
+
@models ||= "./app/models"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ToFactory
|
2
|
+
class DefinitionGroup
|
3
|
+
def self.perform(instances)
|
4
|
+
new.perform(instances)
|
5
|
+
end
|
6
|
+
|
7
|
+
def perform(instances)
|
8
|
+
instances.inject({}) do |result, record|
|
9
|
+
klass, name, definition = define_factory(record)
|
10
|
+
result[klass] ||= {}
|
11
|
+
result[klass][name] = definition
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def define_factory(record)
|
17
|
+
name, item, parent_klass = extract_details(record)
|
18
|
+
|
19
|
+
definition = ToFactory::Generation::Factory.new(item, name).to_factory(parent_klass)
|
20
|
+
|
21
|
+
[item.class, name, definition]
|
22
|
+
end
|
23
|
+
|
24
|
+
def calculate_name(klass)
|
25
|
+
klass.name.to_s.underscore
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def extract_details(record)
|
31
|
+
if record.is_a?(ActiveRecord::Base)
|
32
|
+
name = calculate_name record.class
|
33
|
+
|
34
|
+
[name, record, nil]
|
35
|
+
elsif record.is_a?(Array)
|
36
|
+
name, item = record
|
37
|
+
parent_klass_name = calculate_name(item.class)
|
38
|
+
parent_klass_name = nil if parent_klass_name.to_s == name.to_s
|
39
|
+
[name, item, parent_klass_name]
|
40
|
+
else
|
41
|
+
raise NotImplemented
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ToFactory
|
2
|
+
class FileSync
|
3
|
+
def initialize(m = ToFactory::Finders::Model.new,
|
4
|
+
fw = ToFactory::FileWriter.new,
|
5
|
+
ff = ToFactory::Finders::Factory.new)
|
6
|
+
@model_finder = wrap_model(m)
|
7
|
+
@file_writer = fw
|
8
|
+
@factory_finder = ff
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform(exclusions=[])
|
12
|
+
definitions = Collation.merge(new_definitions(exclusions), pre_existing)
|
13
|
+
|
14
|
+
@file_writer.write(definitions)
|
15
|
+
end
|
16
|
+
|
17
|
+
def new_definitions(exclusions=[])
|
18
|
+
return {} if exclusions == [:all]
|
19
|
+
|
20
|
+
instances = @model_finder.call(exclusions)
|
21
|
+
|
22
|
+
DefinitionGroup.perform(instances)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def pre_existing
|
28
|
+
@factory_finder.call
|
29
|
+
end
|
30
|
+
|
31
|
+
def wrap_model(m)
|
32
|
+
if m.respond_to?(:call)
|
33
|
+
m
|
34
|
+
else
|
35
|
+
lambda{|exclusions|
|
36
|
+
exclusions ||= []
|
37
|
+
records = if m.is_a?(ActiveRecord::Base)
|
38
|
+
Array m
|
39
|
+
else
|
40
|
+
m
|
41
|
+
end
|
42
|
+
|
43
|
+
records.reject{|o,_| exclusions.include?(o.class)}
|
44
|
+
}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ToFactory
|
2
|
+
class FileWriter
|
3
|
+
def initialize
|
4
|
+
FileUtils.mkdir_p(ToFactory.factories)
|
5
|
+
end
|
6
|
+
|
7
|
+
def write(definitions)
|
8
|
+
definitions.each do |klass, factories|
|
9
|
+
name = klass.name.underscore.gsub /^"|"$/, ""
|
10
|
+
mkdir(name) if name.to_s["/"]
|
11
|
+
|
12
|
+
File.open(File.join(ToFactory.factories, "#{name}.rb"), "w") do |f|
|
13
|
+
f << wrap_factories(factories.values)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def wrap_factories(factories)
|
21
|
+
if ToFactory.new_syntax?
|
22
|
+
modern_header(factories)
|
23
|
+
else
|
24
|
+
factories.join("\n\n")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def modern_header(factories)
|
29
|
+
out = "FactoryGirl.define do\n"
|
30
|
+
out << factories.join("\n")
|
31
|
+
out << "\nend\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
def mkdir(name)
|
35
|
+
dir = name.to_s.split("/")[0..-2]
|
36
|
+
FileUtils.mkdir_p File.join(ToFactory.factories, dir)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ToFactory
|
2
|
+
module Finders
|
3
|
+
class Factory
|
4
|
+
def call
|
5
|
+
all_factories = {}
|
6
|
+
|
7
|
+
Dir.glob(File.join(ToFactory.factories, "**/*.rb")).each do |f|
|
8
|
+
factories = ToFactory::Parsing::File.parse(f)
|
9
|
+
|
10
|
+
all_factories = Collation.merge(all_factories, factories)
|
11
|
+
end
|
12
|
+
|
13
|
+
all_factories
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ToFactory
|
2
|
+
module Finders
|
3
|
+
class Model
|
4
|
+
def call(exclusions=[])
|
5
|
+
instances = []
|
6
|
+
|
7
|
+
Dir.glob("#{ToFactory.models}/**/*.rb").each do |file|
|
8
|
+
File.readlines(file).each do |f|
|
9
|
+
if match = f.match(/class (.*) ?</)
|
10
|
+
klass = rescuing_require file, match
|
11
|
+
break if exclusions.include?(klass)
|
12
|
+
instance = get_active_record_instance(klass)
|
13
|
+
instances << instance if instance
|
14
|
+
break
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
instances
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def rescuing_require(file, match)
|
25
|
+
require file
|
26
|
+
klass = eval(match[1])
|
27
|
+
klass
|
28
|
+
|
29
|
+
rescue Exception => e
|
30
|
+
warn "Failed to eval #{file}"
|
31
|
+
warn e.message
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_active_record_instance(klass)
|
35
|
+
if klass && klass.ancestors.include?(ActiveRecord::Base)
|
36
|
+
begin
|
37
|
+
klass.first
|
38
|
+
rescue
|
39
|
+
klass.find(:first)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
rescue Exception => e
|
43
|
+
warn "Failed to get record from #{klass} #{e.message}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module ToFactory
|
2
|
+
module Generation
|
3
|
+
class Attribute
|
4
|
+
def initialize(attribute, value)
|
5
|
+
@attribute = attribute
|
6
|
+
@value = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
attribute = "#{@attribute} #{inspect_value(@value)}"
|
11
|
+
|
12
|
+
if ToFactory.new_syntax?
|
13
|
+
" #{attribute}"
|
14
|
+
else
|
15
|
+
" o.#{attribute}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def <=>(other)
|
20
|
+
@attribute <=> other
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
to_s == other.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def inspect_value(value)
|
30
|
+
case value
|
31
|
+
when Time, DateTime
|
32
|
+
time = in_utc(value).strftime("%Y-%m-%dT%H:%M%Z").inspect
|
33
|
+
time.gsub(/UTC"$/, "Z\"").gsub(/GMT"$/, "Z\"")
|
34
|
+
when BigDecimal
|
35
|
+
value.to_f.inspect
|
36
|
+
when Hash
|
37
|
+
hash = value.inject({}){|result, (k, v)| result[k] = inspect_value(v); result}
|
38
|
+
when Array
|
39
|
+
value.map{|v| inspect_value(v)}
|
40
|
+
else
|
41
|
+
value.inspect
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def in_utc(time)
|
46
|
+
time.utc
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ToFactory
|
2
|
+
module Generation
|
3
|
+
|
4
|
+
class Factory
|
5
|
+
def initialize(object, name)
|
6
|
+
unless object.is_a? ActiveRecord::Base
|
7
|
+
message = "Generation::Factory requires initializing with an ActiveRecord::Base instance"
|
8
|
+
message << "\n but received #{object.inspect}"
|
9
|
+
raise ToFactory::MissingActiveRecordInstanceException.new(message)
|
10
|
+
end
|
11
|
+
|
12
|
+
@name = add_quotes name
|
13
|
+
@attributes = object.attributes
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_factory(parent_name=nil)
|
17
|
+
header(parent_name) do
|
18
|
+
to_skip = [:id, :created_at, :updated_at]
|
19
|
+
attributes = @attributes.delete_if{|key, _| to_skip.include? key.to_sym}
|
20
|
+
|
21
|
+
attributes.map do |attr, value|
|
22
|
+
factory_attribute(attr, value)
|
23
|
+
end.sort.join("\n") << "\n"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def header(parent_name=nil, &block)
|
28
|
+
if ToFactory.new_syntax?
|
29
|
+
modern_header parent_name, &block
|
30
|
+
else
|
31
|
+
header_factory_girl_1 parent_name, &block
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def modern_header(parent_name=nil, &block)
|
36
|
+
generic_header(parent_name, "factory", "", &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def header_factory_girl_1(parent_name=nil, &block)
|
40
|
+
generic_header(parent_name, "Factory.define", "|o|", &block)
|
41
|
+
end
|
42
|
+
|
43
|
+
def factory_attribute(attr, value)
|
44
|
+
Attribute.new(attr, value).to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def generic_header(parent_name, factory_start, block_arg, &block)
|
50
|
+
out = " #{factory_start}(:#{@name}#{parent_clause(parent_name)}) do#{block_arg}\n"
|
51
|
+
out << yield.to_s
|
52
|
+
out << " end\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
def parent_clause(name)
|
56
|
+
name ? ", :parent => :#{add_quotes name}" : ""
|
57
|
+
end
|
58
|
+
|
59
|
+
def add_quotes(name)
|
60
|
+
name = name.to_s
|
61
|
+
|
62
|
+
if name["/"]
|
63
|
+
if name[/^".*"$/]
|
64
|
+
name
|
65
|
+
else
|
66
|
+
"\"#{name}\""
|
67
|
+
end
|
68
|
+
else
|
69
|
+
name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'ruby2ruby'
|
2
|
+
require 'ruby_parser'
|
3
|
+
require 'to_factory/parsing/syntax'
|
4
|
+
require 'to_factory/parsing/new_syntax'
|
5
|
+
require 'to_factory/parsing/old_syntax'
|
6
|
+
|
7
|
+
module ToFactory
|
8
|
+
module Parsing
|
9
|
+
class File
|
10
|
+
delegate :multiple_factories?, :header?, :parse, :to => :parser
|
11
|
+
|
12
|
+
def self.parse(filename)
|
13
|
+
from_file(filename).parse
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_file(filename)
|
17
|
+
contents = ::File.read filename rescue nil
|
18
|
+
raise ArgumentError.new "Invalid file #{filename}" if contents.to_s.length == 0
|
19
|
+
|
20
|
+
new(contents)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(contents)
|
24
|
+
@contents = contents
|
25
|
+
end
|
26
|
+
|
27
|
+
def parser
|
28
|
+
@parser ||= parser_klass.new(@contents)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def parser_klass
|
34
|
+
ToFactory.new_syntax? ? NewSyntax : OldSyntax
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|