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