to_factory 0.0.3 → 0.1.0
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/.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
|
+
[](https://travis-ci.org/markburns/to_factory)
|
5
|
+
[](https://gemnasium.com/markburns/to_factory)
|
6
|
+
[](https://codeclimate.com/github/markburns/to_factory)
|
7
|
+
[](https://codeclimate.com/github/markburns/to_factory)
|
8
|
+
[](https://rubygems.org/gems/to_factory)
|
9
|
+
[](http://markburns.mit-license.org)
|
10
|
+
[](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
|