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.
Files changed (67) hide show
  1. data/.gitignore +6 -0
  2. data/.rspec +2 -1
  3. data/.travis.yml +23 -0
  4. data/Gemfile +3 -13
  5. data/README.md +59 -20
  6. data/Rakefile +20 -14
  7. data/bin/ci +2 -0
  8. data/bin/spec +2 -0
  9. data/lib/to_factory/collation.rb +34 -0
  10. data/lib/to_factory/config.rb +18 -0
  11. data/lib/to_factory/definition_group.rb +47 -0
  12. data/lib/to_factory/file_sync.rb +48 -0
  13. data/lib/to_factory/file_writer.rb +39 -0
  14. data/lib/to_factory/finders/factory.rb +17 -0
  15. data/lib/to_factory/finders/model.rb +47 -0
  16. data/lib/to_factory/generation/attribute.rb +52 -0
  17. data/lib/to_factory/generation/factory.rb +74 -0
  18. data/lib/to_factory/parsing/file.rb +38 -0
  19. data/lib/to_factory/parsing/new_syntax.rb +9 -0
  20. data/lib/to_factory/parsing/old_syntax.rb +9 -0
  21. data/lib/to_factory/parsing/syntax.rb +86 -0
  22. data/lib/to_factory/version.rb +1 -1
  23. data/lib/to_factory.rb +55 -1
  24. data/spec/db/migrate/{201108201012010100_create_users.rb → 1_create_users.rb} +0 -0
  25. data/spec/db/migrate/2_create_projects.rb +13 -0
  26. data/spec/db/migrate/3_create_not_namespaced.rb +11 -0
  27. data/spec/db/migrate/4_add_birthday_to_users.rb +9 -0
  28. data/spec/example_factories/new_syntax/admin.rb +6 -0
  29. data/spec/example_factories/new_syntax/admin_with_header.rb +8 -0
  30. data/spec/example_factories/new_syntax/project_with_header.rb +7 -0
  31. data/spec/example_factories/new_syntax/user.rb +6 -0
  32. data/spec/example_factories/new_syntax/user_admin.rb +13 -0
  33. data/spec/example_factories/new_syntax/user_admin_with_header.rb +15 -0
  34. data/spec/example_factories/new_syntax/user_with_header.rb +8 -0
  35. data/spec/example_factories/old_syntax/admin.rb +6 -0
  36. data/spec/example_factories/old_syntax/project_with_header.rb +5 -0
  37. data/spec/example_factories/old_syntax/user.rb +6 -0
  38. data/spec/example_factories/old_syntax/user_admin.rb +13 -0
  39. data/spec/example_factories/old_syntax/user_admin_with_header.rb +13 -0
  40. data/spec/example_factories/old_syntax/user_with_header.rb +6 -0
  41. data/spec/integration/config_spec.rb +19 -0
  42. data/spec/integration/file_sync_spec.rb +77 -0
  43. data/spec/integration/file_writer_spec.rb +16 -0
  44. data/spec/integration/generate_class_method_spec.rb +107 -0
  45. data/spec/integration/lint_spec.rb +16 -0
  46. data/spec/spec_helper.rb +90 -14
  47. data/spec/support/match_sexp.rb +24 -0
  48. data/spec/support/models/not_active_record.rb +2 -0
  49. data/spec/support/models/project.rb +3 -0
  50. data/spec/support/models/user.rb +3 -0
  51. data/spec/support/terse_expect_syntax.rb +23 -0
  52. data/spec/unit/collation_spec.rb +35 -0
  53. data/spec/unit/definition_group_spec.rb +19 -0
  54. data/spec/unit/file_writer_spec.rb +28 -0
  55. data/spec/unit/finders/factory_spec.rb +27 -0
  56. data/spec/unit/finders/model_spec.rb +28 -0
  57. data/spec/unit/generator_spec.rb +71 -0
  58. data/spec/unit/parsing/file_spec.rb +83 -0
  59. data/tmp/.keep +0 -0
  60. data/to_factory.gemspec +49 -22
  61. metadata +225 -25
  62. data/.rvmrc +0 -1
  63. data/Gemfile.lock +0 -113
  64. data/lib/to_factory/generator.rb +0 -115
  65. data/spec/config/database.yml +0 -2
  66. data/spec/db/test.sqlite +0 -0
  67. data/spec/generator_spec.rb +0 -166
@@ -0,0 +1,24 @@
1
+ RSpec::Matchers.define :match_sexp do |expected|
2
+ match do |actual|
3
+ parser = RubyParser.new
4
+
5
+ begin
6
+ parser.process(expected) == parser.process(actual)
7
+ rescue Exception => e
8
+ @raised = e
9
+ false
10
+ end
11
+
12
+ end
13
+
14
+ failure_message do |actual|
15
+ message = "expected \n#{actual}\n\nto match expected sexp of\n\n#{expected}"
16
+
17
+ if @raised
18
+ message << "\nbut raised\n"
19
+ message << @raised.message
20
+ else
21
+ message
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,2 @@
1
+ class ToFactory::NotActiveRecord
2
+ end
@@ -0,0 +1,3 @@
1
+ class ToFactory::Project < ActiveRecord::Base
2
+ self.table_name = "projects"
3
+ end
@@ -0,0 +1,3 @@
1
+ class ToFactory::User < ActiveRecord::Base
2
+ self.table_name = "users"
3
+ end
@@ -0,0 +1,23 @@
1
+ module TerseExpectSyntax
2
+ class Returner
3
+ def initialize(to_call)
4
+ @to_call=to_call
5
+ end
6
+ def r(*args)
7
+ @to_call.call(*args)
8
+ end
9
+ end
10
+
11
+ #x( @a, :b, "c").r d
12
+ #becomes
13
+ #expect(@a).to_receive(:b).with("c").and_return d
14
+ def x(target, expected_method, *received_args)
15
+ receiver = expect(target).to receive(expected_method)
16
+ if received_args.any?
17
+ receiver = receiver.with(*received_args)
18
+ end
19
+
20
+
21
+ Returner.new(lambda {|*return_args| receiver.and_return(*return_args) })
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ describe ToFactory::Collation do
2
+ def perform
3
+ ToFactory::Collation.merge(a, b)
4
+ end
5
+
6
+ context "matching keys" do
7
+ let(:a) { {:A => {:a => 1}} }
8
+ let(:b) { {:B => {:a => 2}} }
9
+
10
+ it do
11
+ expect(lambda{perform}).to raise_error ToFactory::AlreadyExists
12
+ end
13
+ end
14
+
15
+ context "non matching keys" do
16
+ let(:a) { {:A => {:a => 1}} }
17
+ let(:b) { {:B => {:b => 2}} }
18
+
19
+ it do
20
+ result = {:A => {:a => 1}, :B => {:b => 2}}.with_indifferent_access
21
+ expect(perform).to eq result
22
+ end
23
+ end
24
+
25
+ context "merging" do
26
+ let(:a) { {:A => {:a => 1}} }
27
+ let(:b) { {:A => {:b => 2}} }
28
+
29
+ it do
30
+ result = {:A => {:a => 1, :b => 2}}.with_indifferent_access
31
+ expect(perform).to eq result
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,19 @@
1
+ describe ToFactory::DefinitionGroup do
2
+ let(:user) { create_user! }
3
+ let(:admin) { create_admin! }
4
+ let(:user_definition) { File.read "./spec/example_factories/#{version}_syntax/user.rb"}
5
+ let(:admin_definition) { File.read "./spec/example_factories/#{version}_syntax/admin.rb"}
6
+ let(:group) { ToFactory::DefinitionGroup.new }
7
+
8
+ it do
9
+ result = group.perform([[:"to_factory/user", user], [:admin, admin]])
10
+
11
+ expect(result.keys[0]).to eq ToFactory::User
12
+ expect(result.values[0][:"to_factory/user"]).to match_sexp user_definition
13
+ expect(result.values[0][:admin]).to match_sexp admin_definition
14
+ end
15
+
16
+ it "#calculate_name" do
17
+ expect(group.calculate_name(ToFactory::Project)).to eq "to_factory/project"
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ describe ToFactory::FileWriter do
2
+ let(:fw) { ToFactory::FileWriter.new }
3
+
4
+ describe "#write" do
5
+ def user_file
6
+ File.read("tmp/factories/to_factory/user.rb")
7
+ end
8
+
9
+ def project_file
10
+ File.read("tmp/factories/to_factory/project.rb")
11
+ end
12
+
13
+ it "adds factories for all models" do
14
+ fw.write({ToFactory::User =>{:user => "factory a"},
15
+ ToFactory::Project => {:project =>"factory b"}
16
+ })
17
+
18
+ if ToFactory.new_syntax?
19
+ expect(user_file).to match /FactoryGirl.define do/
20
+ end
21
+ expect(user_file).to include "factory a"
22
+ expect(project_file).to include "factory b"
23
+ end
24
+ end
25
+
26
+
27
+
28
+ end
@@ -0,0 +1,27 @@
1
+ describe ToFactory::Finders::Factory do
2
+ describe "#call" do
3
+ before do
4
+ FileUtils.mkdir_p "./tmp/factories/to_factory"
5
+ FileUtils.cp "./spec/example_factories/#{version}_syntax/user_admin_with_header.rb",
6
+ "./tmp/factories/to_factory/user.rb"
7
+ end
8
+
9
+ let(:user_file_contents) { File.read "./spec/example_factories/#{version}_syntax/user.rb"}
10
+ let(:admin_file_contents){ File.read "./spec/example_factories/#{version}_syntax/admin.rb" }
11
+
12
+ it "reads all the factories" do
13
+ finder = ToFactory::Finders::Factory.new
14
+
15
+ result = finder.call
16
+ result = result[ToFactory::User]
17
+
18
+ expect(result[:"to_factory/user"]).
19
+ to match_sexp user_file_contents
20
+
21
+ expect(result[:admin]).
22
+ to match_sexp admin_file_contents
23
+ end
24
+ end
25
+
26
+ end
27
+
@@ -0,0 +1,28 @@
1
+ describe ToFactory::Finders::Model do
2
+ before do
3
+ ToFactory.models = path
4
+ end
5
+
6
+ let(:finder) { ToFactory::Finders::Model.new }
7
+
8
+ describe "#call" do
9
+ let!(:user) { ToFactory::User.create! :name => "a user"}
10
+ let!(:project) { ToFactory::Project.create! :name => "a project"}
11
+
12
+ context "no match"do
13
+ let(:path) { "./tmp/doesnt_exist" }
14
+ it do
15
+ expect(finder.call).to eq []
16
+ end
17
+ end
18
+ context "with a match" do
19
+ let(:path) { "./spec/support/models" }
20
+ it do
21
+ expect(finder.call).to match_array [user, project]
22
+ end
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+
@@ -0,0 +1,71 @@
1
+ describe ToFactory::Generation::Factory do
2
+ before(:each) do
3
+ ToFactory::User.destroy_all
4
+ ActiveRecord::Base.connection.execute "delete from sqlite_sequence where name = 'users'"
5
+ end
6
+
7
+ let(:birthday) do
8
+ Time.find_zone("UTC").parse("2014-07-08T15:30Z")
9
+ end
10
+
11
+ let!(:user) { create_user! }
12
+
13
+ let(:generator) { ToFactory::Generation::Factory.new user, :"to_factory/user" }
14
+
15
+ describe ".new" do
16
+ it "requires an activerecord instance" do
17
+ expect(lambda{ToFactory::Generation::Factory.new "", ""}).to raise_error ToFactory::MissingActiveRecordInstanceException
18
+ end
19
+ end
20
+
21
+ describe "#header" do
22
+ it do
23
+ if ToFactory.new_syntax?
24
+ expect(generator.header{}).to match_sexp <<-eof.strip_heredoc
25
+ factory(:"to_factory/user") do
26
+ end
27
+ eof
28
+ else
29
+ expect(generator.header{}).to match_sexp <<-eof.strip_heredoc
30
+ Factory.define(:"to_factory/user") do |o|
31
+ end
32
+ eof
33
+ end
34
+ end
35
+ end
36
+
37
+ describe "#factory_attribute" do
38
+ it do
39
+ if ToFactory.new_syntax?
40
+ expect(generator.factory_attribute(:name, nil)) .to eq ' name nil'
41
+ expect(generator.factory_attribute(:name, "Jeff")).to eq ' name "Jeff"'
42
+ expect(generator.factory_attribute(:id, 8)) .to eq ' id 8'
43
+
44
+ else
45
+ expect(generator.factory_attribute(:name, nil)) .to eq ' o.name nil'
46
+ expect(generator.factory_attribute(:name, "Jeff")).to eq ' o.name "Jeff"'
47
+ expect(generator.factory_attribute(:id, 8)) .to eq ' o.id 8'
48
+ end
49
+ end
50
+ it "generates usable datetime strings" do
51
+ output = generator.factory_attribute(:birthday, birthday)
52
+ if ToFactory.new_syntax?
53
+ expect(output).to eq ' birthday "2014-07-08T15:30Z"'
54
+ else
55
+ expect(output).to eq ' o.birthday "2014-07-08T15:30Z"'
56
+ end
57
+ end
58
+ end
59
+
60
+ describe "#ToFactory" do
61
+ let(:expected) do
62
+ File.read "./spec/example_factories/#{version}_syntax/user.rb"
63
+ end
64
+
65
+ it do
66
+ expect(generator.to_factory).to match_sexp expected
67
+ result = ToFactory(user).values.first.values.first
68
+ expect(result).to match_sexp expected
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,83 @@
1
+ describe ToFactory::Parsing::File do
2
+ let(:user_contents) { File.read "spec/example_factories/#{version}_syntax/user.rb" }
3
+ let(:admin_contents) { File.read "spec/example_factories/#{version}_syntax/admin.rb"}
4
+
5
+ let(:parser) { ToFactory::Parsing::File.from_file(filename) }
6
+
7
+ describe "#multiple_factories? and #header?" do
8
+ context "new syntax" do
9
+ tests = if ToFactory.new_syntax?
10
+
11
+ #file, multiple, header
12
+ [
13
+ ["user", false, false],
14
+ ["user_with_header", false, true],
15
+ ["user_admin", true, false],
16
+ ["user_admin_with_header", true, true]
17
+ ]
18
+ else
19
+ [
20
+ ["user", false, false],
21
+ ["user_admin", true, false],
22
+ ]
23
+ end
24
+
25
+ tests.each do |file, multiple, header|
26
+ context "with #{header ? 'header' : 'no header'} and #{multiple ? 'multiple factories' : 'one factory'}" do
27
+ context "file: #{file}" do
28
+ let(:filename) { "spec/example_factories/#{version}_syntax/#{file}.rb"}
29
+
30
+ it { expect(parser.multiple_factories?).to eq multiple }
31
+ it { expect(parser.header?).to eq header }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#parse" do
39
+ context "file: user" do
40
+ let(:filename) { "spec/example_factories/#{version}_syntax/#{'user'}.rb"}
41
+
42
+ it do
43
+ result = parser.parse[ToFactory::User]
44
+
45
+ expect(result[:"to_factory/user" ]).to match_sexp user_contents
46
+ end
47
+ end
48
+
49
+ context "file: user_with_header" do
50
+ let(:filename) { "spec/example_factories/#{version}_syntax/#{'user_with_header'}.rb"}
51
+
52
+ it do
53
+ result = parser.parse[ToFactory::User]
54
+
55
+ expect(result[:"to_factory/user" ]).to match_sexp user_contents
56
+ end
57
+ end
58
+
59
+ context "file: user_admin" do
60
+ let(:filename) { "spec/example_factories/#{version}_syntax/#{'user_admin'}.rb"}
61
+
62
+ it do
63
+ result = parser.parse
64
+
65
+ expect(result.keys).to match_array [ToFactory::User]
66
+ users = result[ToFactory::User]
67
+
68
+ expect(users[:"to_factory/user" ]).to match_sexp user_contents
69
+ expect(users[:admin]).to match_sexp admin_contents
70
+ end
71
+ end
72
+
73
+ context "file: user_admin_with_header" do
74
+ let(:filename) { "spec/example_factories/#{version}_syntax/#{'user_admin_with_header'}.rb"}
75
+
76
+ it do
77
+ result = parser.parse[ToFactory::User]
78
+
79
+ expect(result[:"to_factory/user" ]).to match_sexp user_contents
80
+ end
81
+ end
82
+ end
83
+ end
data/tmp/.keep ADDED
File without changes
data/to_factory.gemspec CHANGED
@@ -1,23 +1,50 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "to_factory/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "to_factory"
7
- s.version = ToFactory::VERSION
8
- s.authors = ["Mark Burns"]
9
- s.email = ["markthedeveloper@gmail.com"]
10
- s.homepage = ""
11
- s.summary = %q{Turn ActiveRecord instances into factories}
12
- s.add_dependency('factory_girl_rails')
13
- s.add_dependency('rails', '~>3.0')
14
-
15
- s.description = %q{This gem gives the object.to_factory method to give a formatted string version of an ActiveRecord object that can be used by factory_girl}
16
-
17
- s.rubyforge_project = "to_factory"
18
-
19
- s.files = `git ls-files`.split("\n")
20
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
- s.require_paths = ["lib"]
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'to_factory/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "to_factory"
8
+ spec.version = ToFactory::VERSION
9
+ spec.authors = ["Mark Burns"]
10
+ spec.email = ["markthedeveloper@gmail.com"]
11
+ spec.summary = %q{Turn ActiveRecord instances into factories}
12
+ spec.description = %q{ActiveRecord::Base#to_factory method to create factory_girl definitions from real data}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}){ |f| File.basename(f) }.reject{|f| f== "spec" || f =="ci" }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "sqlite3" , "~> 1.3.6"
22
+
23
+ if RUBY_VERSION =~ /^1\.8/
24
+ spec.add_development_dependency "ruby-debug"
25
+ spec.add_development_dependency "database_cleaner", "~> 0.3"
26
+ else
27
+ spec.add_development_dependency "database_cleaner", "~> 1.4.0"
28
+ end
29
+
30
+ if RUBY_VERSION =~ /^2\.\d/
31
+ spec.add_development_dependency "pry-byebug"
32
+ end
33
+
34
+ old_active_record = RUBY_VERSION =~ /^1\.8|^1.9\.[1|2]/
35
+
36
+ spec.add_dependency "ruby2ruby"
37
+ spec.add_dependency "deep_merge"
38
+
39
+ if old_active_record
40
+ spec.add_dependency 'activerecord', ">2.0", "< 4.0"
41
+ spec.add_dependency 'i18n', "< 0.7"
42
+ spec.add_development_dependency "factory_girl", "< 2.0"
43
+ else
44
+ spec.add_dependency 'activerecord', ">3.0"
45
+ spec.add_development_dependency "factory_girl", "~> 4.5"
46
+ end
47
+
48
+ spec.add_development_dependency "rspec", "~> 3.0"
49
+ spec.add_development_dependency "rake", "~> 10.0"
23
50
  end