fun_with_gems 0.0.2 → 0.0.8

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 (61) hide show
  1. checksums.yaml +5 -13
  2. data/.document +5 -0
  3. data/CHANGELOG.markdown +29 -0
  4. data/Gemfile +6 -11
  5. data/README.rdoc +125 -1
  6. data/ROADMAP.md +6 -0
  7. data/Rakefile +15 -46
  8. data/VERSION +1 -1
  9. data/lib/fun_with/gems/api_extender.rb +46 -0
  10. data/lib/fun_with/gems/configuration_installer.rb +86 -0
  11. data/lib/fun_with/gems/constant_builder.rb +36 -0
  12. data/lib/fun_with/gems/core_extender.rb +65 -0
  13. data/lib/fun_with/gems/core_extensions/module.rb +9 -3
  14. data/lib/fun_with/gems/fun_gem_api.rb +62 -3
  15. data/lib/fun_with/gems/gem_api.rb +78 -47
  16. data/lib/fun_with/gems/inclusionizer.rb +34 -0
  17. data/lib/fun_with/gems/library_requirer.rb +54 -0
  18. data/lib/fun_with/gems/rake_class_methods.rb +111 -0
  19. data/lib/fun_with/gems/rakefile.rb +114 -0
  20. data/lib/fun_with/gems/root_setter.rb +19 -0
  21. data/lib/fun_with/gems/test_case_extender.rb +27 -0
  22. data/lib/fun_with/gems/testing/assertions.rb +22 -0
  23. data/lib/fun_with/gems/testing/gem_to_test_methods.rb +37 -0
  24. data/lib/fun_with/gems/testing/test_case_extensions.rb +39 -0
  25. data/lib/fun_with/gems/testing/test_results.rb +40 -0
  26. data/lib/fun_with/gems/testing/test_setup.rb +22 -0
  27. data/lib/fun_with/gems/testing/test_suite_runner.rb +28 -0
  28. data/lib/fun_with/gems/testing/validator.rb +52 -0
  29. data/lib/fun_with/gems/versionizer.rb +41 -0
  30. data/lib/fun_with_gems.rb +15 -14
  31. data/lib/tasks/fun_with/gems/publish.rake +8 -0
  32. data/lib/tasks/fun_with/gems/validate.rake +28 -0
  33. data/tasks/empty/empty.rake +6 -0
  34. data/tasks/empty/environment.rake +7 -0
  35. data/test/assertions.rb +15 -0
  36. data/test/data/test_gems/array_inherits_enumerable/VERSION +1 -0
  37. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable/core_extensions/comparable.rb +9 -0
  38. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable/core_extensions/enumerable.rb +10 -0
  39. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable/core_extensions/numeric.rb +22 -0
  40. data/test/data/test_gems/array_inherits_enumerable/lib/array_inherits_enumerable.rb +1 -0
  41. data/test/data/test_gems/fun_with_llamas/lib/fun_with/llamas/gem_api.rb +10 -0
  42. data/test/data/test_gems/fun_with_llamas/lib/fun_with/llamas/llama.rb +40 -0
  43. data/test/data/test_gems/fun_with_llamas/lib/fun_with/llamas/trainer.rb +15 -0
  44. data/test/data/test_gems/integer_magic/VERSION +1 -0
  45. data/test/data/test_gems/integer_magic/config/gem_config.rb +4 -0
  46. data/test/data/test_gems/integer_magic/lib/integer_magic/core_extensions/integer.rb +28 -0
  47. data/test/data/test_gems/integer_magic/lib/integer_magic/core_extensions/numeric.rb +13 -0
  48. data/test/data/test_gems/integer_magic/lib/integer_magic.rb +1 -0
  49. data/test/helper.rb +9 -38
  50. data/test/test_core_extensions.rb +10 -0
  51. data/test/test_fun_with_gems.rb +9 -16
  52. data/test/test_library_requirer.rb +13 -0
  53. data/test/test_the_test_case.rb +24 -0
  54. data/test/test_the_test_gems.rb +152 -0
  55. metadata +123 -40
  56. data/lib/fun_with/gems/mechanic.rb +0 -27
  57. data/lib/fun_with/gems/validator.rb +0 -69
  58. data/test/test_gem/lib/fun_with/llamas/llama.rb +0 -9
  59. data/test/test_gem/lib/fun_with/llamas/trainer.rb +0 -9
  60. /data/test/{test_gem → data/test_gems/fun_with_llamas}/VERSION +0 -0
  61. /data/test/{test_gem → data/test_gems/fun_with_llamas}/lib/fun_with_llamas.rb +0 -0
@@ -9,74 +9,105 @@ module FunWith
9
9
  #
10
10
  # Configurable options:
11
11
  # While all these things are handled by default, some things can be overridden
12
- # :main_lib_file => use a different filepath to calculate the root
13
- #
14
12
  # :root => or render :main_lib_file moot by declaring a different root.
15
13
  #
16
14
  # :version => Declare a different version string for the gem.
17
15
  #
18
16
  # :require => false (avoids requiring the default lib/fun_with dir.)
19
17
  # :require => filepath or array of filepaths (require these things instead (note: not in addition to))
18
+ # :core_extensions => false (don't autoload Gem::CoreExtension modules)
19
+ # (note that it still checks to see if the module's already been included)
20
+ #
21
+ # :main_lib_file => use a different filepath to calculate the root (defaults to <GEM_ROOT>/)
22
+ # :configuration => nil (tries to load configuration from <GEM_ROOT>/config/gem_config.rb, if such a file exists)
23
+ # (String) --> assumes it's been given a filename
24
+ # (Hash) --> converts to a FunWith::Configurations::Config
25
+ # (Config) --> uses as the configuration
26
+ # :skip --> don't bother installing a configuration
27
+ #
28
+ # If successful, the configuration will be accessible from <GEM_CONST>.config
20
29
  def make_gem_fun( gem_const, opts = {} )
21
30
  @caller_file = caller.first.gsub(/:\d+:.*/,'').fwf_filepath
22
31
  @opts = opts
23
- set_gem_const( gem_const )
32
+
33
+
34
+
35
+ @gem_const = build_gem_const( gem_const )
24
36
  @gem_const.extend( FunGemAPI )
25
- set_gem_root
26
- set_gem_version
27
- require_libs
37
+ set_gem_root unless @opts[:set_root] == false
38
+ set_gem_version unless @opts[:set_version] == false
39
+ @gem_const.gem_verbose = opts[:verbose]
40
+
41
+ # false to skip requiring entirely
42
+ # an array to load both
43
+ require_libs unless @opts[:require] == false
44
+
45
+ extend_constant_with_gem_api unless @opts[:gem_api] == false
46
+
47
+ @gem_const.load_external_tasks # Nothing happens unless 'rake' gem is active
48
+
49
+ include_core_extensions unless @opts[:core_extensions] == false
50
+
51
+ # GemName.config.{configuration_settings} if applicable
52
+ # Only runs if "fun_with_configurations" is required prior to
53
+ # calling files. Really starting to wonder about that. Should fwc
54
+ # stop depending on
55
+ install_gem_configuration unless @opts[:configuration] == :skip
56
+
57
+ extend_test_case
58
+
59
+ @gem_const
60
+ end
61
+
62
+ def inclusionize( base )
63
+ FunWith::Gems::Inclusionizer.inclusionize( base )
28
64
  end
29
65
 
30
66
  protected
31
- def set_gem_const( gem_const )
32
- # Create new modules for this fun, fun gem, if necessary.
33
- if gem_const.is_a?( String )
34
- #create the module
35
- const = Object
36
- full_const_name = ""
37
- gem_const.split("::").each do |module_name|
38
- full_const_name << "::" unless full_const_name.fwf_blank?
39
- full_const_name << module_name
40
-
41
- if eval( "defined?(#{full_const_name})")
42
- const = eval( full_const_name )
43
- else
44
- const = const.const_set( module_name, Module.new )
45
- end
46
- end
47
-
48
- @gem_const = eval( gem_const )
49
- else
50
- @gem_const = gem_const
51
- end
67
+ def build_gem_const( gem_const )
68
+ ConstantBuilder.build_constant( gem_const )
52
69
  end
53
70
 
54
71
  def set_gem_root
55
- return if @opts[:set_root] == false
56
-
57
- # Hence, the "make_gem_fun()" directive should be called in the lib/gem_name.rb file.
58
- main_lib_file = @opts[:main_lib_file] || @caller_file
59
- root = @opts[:root] || main_lib_file.fwf_filepath.expand.dirname.up
60
-
61
- Files::RootPath.rootify( @gem_const, root )
72
+ RootSetter.set_root( @gem_const, @caller_file, @opts )
62
73
  end
63
-
74
+
64
75
  def set_gem_version
65
- return if @opts[:set_version] == false
66
- if @opts[:version]
67
- VersionStrings.versionize( @gem_const, @opts[:version] )
68
- else
69
- VersionStrings.versionize( @gem_const )
70
- end
76
+ Versionizer.versionize( @gem_const, @opts[:version] )
71
77
  end
72
78
 
73
79
  def require_libs
74
- unless @opts[:require] == false
75
- @opts[:require] ||= @gem_const.root( "lib" ).glob(:all, :recursive => false) - [ @caller_file ]
76
- @opts[:require] = [ @opts[:require] ] unless @opts[:require].is_a?(Array)
77
-
78
- @opts[:require].each do |req_dir|
79
- req_dir.fwf_filepath.expand.requir
80
+ opts = just_options( @opts, :require, :main_lib_file ).merge( :caller => @caller_file )
81
+ LibraryRequirer.require( @gem_const, opts )
82
+ end
83
+
84
+ def extend_constant_with_gem_api
85
+ ApiExtender.extend_with_api( @gem_const )
86
+ end
87
+
88
+ # Files in <GEM_ROOT>/lib/core_extensions get included in their corresponding core class?
89
+ def include_core_extensions
90
+ CoreExtender.extend_core( @gem_const )
91
+ end
92
+
93
+ # Install a configuration given as an argument,
94
+ # or install the default config/gem_config.rb if such a file exists
95
+ def install_gem_configuration
96
+ opts = just_options( @opts, :configuration )
97
+ ConfigurationInstaller.install_configuration( @gem_const, opts )
98
+ end
99
+
100
+ # @gem_const::Testing::TestCaseExtensions should already be loaded
101
+ # if it exists. Uses it to extend FunWith::Testing::TestCase
102
+ def extend_test_case
103
+ TestCaseExtender.extend_test_case( @gem_const )
104
+ end
105
+
106
+ protected
107
+ def just_options( opts, *args )
108
+ {}.tap do |return_opts|
109
+ for arg in args
110
+ return_opts[arg] = opts[arg].dup if opts.has_key?( arg )
80
111
  end
81
112
  end
82
113
  end
@@ -0,0 +1,34 @@
1
+ module FunWith
2
+ module Gems
3
+ module Inclusionizer
4
+ def self.inclusionize( base )
5
+ base.send( :include, self )
6
+ end
7
+
8
+ def self.included( base )
9
+ # overwrite the base class's self.included()
10
+ base.send( :extend, self::SelfIncludedMethod )
11
+ end
12
+
13
+ module SelfIncludedMethod
14
+ def included( base )
15
+ __self = self
16
+
17
+ if base.is_a?(Module)
18
+ base.module_eval do
19
+ extend __self::ClassMethods if defined?( __self::ClassMethods )
20
+ include __self::InstanceMethods if defined?( __self::InstanceMethods )
21
+ include __self::Constants if defined?( __self::Constants )
22
+ end
23
+ elsif base.is_a?(Class)
24
+ base.class_eval do
25
+ extend __self::ClassMethods if defined?( __self::ClassMethods )
26
+ include __self::InstanceMethods if defined?( __self::InstanceMethods )
27
+ include __self::Constants if defined?( __self::Constants )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,54 @@
1
+ # Create new modules if necessary.
2
+ module FunWith
3
+ module Gems
4
+ class LibraryRequirer
5
+ def self.require( *args, &block )
6
+ self.new.require( *args, &block )
7
+ end
8
+
9
+ def require( const, opts )
10
+ caller_file = opts[:caller] || guess_caller_file_name( const )
11
+ files_to_require = const.root( "lib" ).glob(:all, :recursive => false) - [ caller_file ]
12
+ files_to_require.flatten!
13
+
14
+ for file in files_to_require
15
+ file.requir
16
+ end
17
+ end
18
+
19
+ def guess_caller_file( const )
20
+ if const.respond_to?(:root)
21
+ const_name = constant_name_to_filename( const.name )
22
+ "lib/" + const_name
23
+ else
24
+ false
25
+ end
26
+ end
27
+
28
+ # We're guessing. It doesn't have to be perfect, but perfect 99% of the time would be nice
29
+ def constant_name_to_filename( cname )
30
+ cname.split("::").map{ |chunk|
31
+ buffer = []
32
+ chunk.length.times do |i|
33
+ char = chunk[i]
34
+ next_char = chunk[i+1] || :eof
35
+
36
+ cap_letter = char == char.upcase
37
+ next_cap_letter = next_char == next_char.upcase
38
+
39
+ if cap_letter && ! next_cap_letter && i > 0
40
+ buffer << "_"
41
+ end
42
+
43
+ buffer << char
44
+ end
45
+
46
+ # chunk.gsub( /(.)([A-Z])/ ){ $1 + "_" + $2 }.downcase
47
+ buffer.join("").downcase
48
+
49
+ }.join("/") + ".rb"
50
+
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,111 @@
1
+ module FunWith
2
+ module Gems
3
+ module RakeClassMethods
4
+ attr_accessor :gem
5
+
6
+ def setup this_gem, rake_main
7
+ set_gem this_gem
8
+ set_rake_main rake_main
9
+ run_bundler_setup
10
+
11
+ # Internal tasks are set up in the Rakefile.
12
+ # External tasks (visible to the gems that depend on your fungem) are setup during the normal gem setup, if the 'rake' gem is present.
13
+ get_gem.load_internal_tasks
14
+ end
15
+
16
+ def set_gem g
17
+ @gem = g
18
+ end
19
+
20
+ def get_gem
21
+ @gem
22
+ end
23
+
24
+ def set_rake_main m
25
+ @rake_main = m
26
+ end
27
+
28
+ def run_bundler_setup
29
+ all_requirements
30
+
31
+ begin
32
+ Bundler.setup(:default, :development)
33
+ rescue Bundler::BundlerError => e
34
+ $stderr.puts e.message
35
+ $stderr.puts "Run `bundle install` to install missing gems"
36
+ exit e.status_code
37
+ end
38
+ end
39
+
40
+ def specification &block
41
+ Juwelier::Tasks.new do |gem|
42
+ yield gem
43
+ end
44
+ end
45
+
46
+ def setup_gem_boilerplate
47
+ run_in_rakefile do
48
+ Juwelier::RubygemsDotOrgTasks.new
49
+
50
+ Rake::TestTask.new(:test) do |test|
51
+ test.libs << 'lib' << 'test'
52
+ test.pattern = 'test/**/test_*.rb'
53
+ test.verbose = true
54
+ end
55
+
56
+ desc "Code coverage detail"
57
+ task :simplecov do
58
+ ENV['COVERAGE'] = "true"
59
+ Rake::Task['test'].execute
60
+ end
61
+
62
+ task :default => :test
63
+
64
+ Rake::RDocTask.new do |rdoc|
65
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
66
+
67
+ rdoc.rdoc_dir = 'rdoc'
68
+ rdoc.title = "fun_with_gems #{version}"
69
+ rdoc.rdoc_files.include('README*')
70
+ rdoc.rdoc_files.include('lib/**/*.rb')
71
+ end
72
+ end
73
+ end
74
+
75
+ def all_requirements
76
+ run_in_rakefile do
77
+ require 'rake'
78
+ require 'juwelier'
79
+ require 'rdoc/task'
80
+ require 'rake/testtask'
81
+ require 'bundler'
82
+ end
83
+ end
84
+
85
+ def run_in_rakefile &block
86
+ if @rake_main.nil?
87
+ raise "Did you forget the line FunWith::Gems::Rakefile.set_rake_main by any chance?"
88
+ elsif ! block_given?
89
+ raise ArgumentError.new("Block must be given")
90
+ else
91
+ @rake_main.instance_eval( &block )
92
+ end
93
+ end
94
+
95
+ def gem_files( *args, &block )
96
+ Dir.glob( File.join( ".", "lib", "**", "*.rb" ) ) +
97
+ Dir.glob( File.join( ".", "test", "**", "*.*" ) ) +
98
+ [ "Gemfile",
99
+ "Rakefile",
100
+ "LICENSE.txt",
101
+ "README.rdoc",
102
+ "VERSION"
103
+ ]
104
+
105
+
106
+
107
+ end
108
+ end
109
+ end
110
+ end
111
+
@@ -0,0 +1,114 @@
1
+ module FunWith
2
+ module Gems
3
+ module Rakefile
4
+ attr_accessor :gem
5
+
6
+ def rakefile_setup this_gem # , rake_main
7
+ self.gem = this_gem
8
+
9
+ # set_rake_main rake_main
10
+ run_bundler_setup
11
+
12
+ # Internal tasks are set up in the Rakefile.
13
+ # External tasks (visible to the gems that depend on your fungem) are setup during the normal gem setup, if the 'rake' gem is present.
14
+ self.gem.load_internal_tasks
15
+ end
16
+
17
+ # def set_rake_main m
18
+ # @rake_main = m
19
+ # end
20
+
21
+ def run_bundler_setup
22
+ all_requirements
23
+
24
+ begin
25
+ Bundler.setup(:default, :development)
26
+ rescue Bundler::BundlerError => e
27
+ $stderr.puts e.message
28
+ $stderr.puts "Run `bundle install` to install missing gems"
29
+ exit e.status_code
30
+ end
31
+ end
32
+
33
+ def gem_specification &block
34
+ Juwelier::Tasks.new do |gem|
35
+ yield gem
36
+ end
37
+ end
38
+
39
+
40
+ def setup_gem_boilerplate
41
+ # run_in_rakefile do
42
+ Juwelier::RubygemsDotOrgTasks.new
43
+
44
+ Rake::TestTask.new(:test) do |test|
45
+ test.libs << 'lib' << 'test'
46
+ test.pattern = 'test/**/test_*.rb'
47
+ test.verbose = true
48
+ end
49
+
50
+ desc "Code coverage detail"
51
+ task :simplecov do
52
+ ENV['COVERAGE'] = "true"
53
+ Rake::Task['test'].execute
54
+ end
55
+
56
+ task :default => :test
57
+
58
+ Rake::RDocTask.new do |rdoc|
59
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
60
+
61
+ rdoc.rdoc_dir = 'rdoc'
62
+ rdoc.title = "fun_with_gems #{version}"
63
+ rdoc.rdoc_files.include('README*')
64
+ rdoc.rdoc_files.include('lib/**/*.rb')
65
+ end
66
+ # end
67
+ end
68
+
69
+ def all_requirements
70
+ # run_in_rakefile do
71
+ require 'rake'
72
+ require 'juwelier'
73
+
74
+ begin
75
+ require 'rdoc/task'
76
+ rescue ArgumentError
77
+ # warn( "what's up with this error when loading RDoc?" )
78
+ require 'rdoc'
79
+ require 'rdoc/task'
80
+ end
81
+
82
+ require 'rake/testtask'
83
+ require 'bundler'
84
+ end
85
+
86
+
87
+ def add_specification_files( gem_specification, *args )
88
+ root = "".fwf_filepath
89
+
90
+ for arg in args
91
+ case arg
92
+ when :default
93
+ files = []
94
+ files += root.join( :bin ).glob
95
+ files += root.join( :config ).glob
96
+ files += root.join( :examples ).glob
97
+ files += [ "Gemfile", "Rakefile", "VERSION" ]
98
+ files += root.join( :lib ).glob( :all, :ext => :rb )
99
+ files += root.join( :lib ).glob( :all, :ext => :rake )
100
+ files += root.join( :test ).glob
101
+ files += root.entries.select{|p| p.path =~ /^LICENSE\./ }
102
+ files += root.entries.select{|p| p.path =~ /^CHANGELOG\./ }
103
+ files += root.entries.select{|p| p.path =~ /^README\./ }
104
+ files += root.entries.select{|p| p.path =~ /^CODE_OF_CONDUCT\./ }
105
+
106
+ gem_specification.files += files.flatten.compact
107
+ else
108
+ gem_specification.files += root.glob( arg )
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,19 @@
1
+ module FunWith
2
+ module Gems
3
+ class RootSetter
4
+ def self.set_root( *args, &block )
5
+ self.new.set_root( *args, &block )
6
+ end
7
+
8
+ def set_root( gem_const, caller_file, opts = {} )
9
+ # Hence, the "make_gem_fun()" directive should be called in the lib/gem_name.rb file.
10
+ main_lib_file = opts[:main_lib_file] || caller_file
11
+ root = opts.fetch(:root){ main_lib_file.fwf_filepath.expand.dirname.up }
12
+
13
+ Files::RootPath.rootify( gem_const, root )
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+
@@ -0,0 +1,27 @@
1
+ module FunWith
2
+ module Gems
3
+ # If the gem has a ::Testing::TestCaseExtensions module, (<GEM_ROOT>/lib/<GEM_NAME>/testing/test_case_extensions.rb)
4
+ # include the module in FunWith::Testing::TestCase
5
+ #
6
+ # Best practice: reserve the TestCaseExtensions module for methods that you want to be available to any gem that
7
+ # includes the gem being extended.
8
+ class TestCaseExtender
9
+ def self.extend_test_case( *args, &block )
10
+ self.new.extend_test_case( *args, &block )
11
+ end
12
+
13
+ # If the caller doesn't specify a class to be extended,
14
+ # assumes the target is FunWith::Testing::TestCase
15
+ def extend_test_case( gem_const, test_case_class = nil )
16
+ if test_case_class.nil?
17
+ return false unless defined?( FunWith::Testing::TestCase )
18
+ test_case_class = FunWith::Testing::TestCase
19
+ end
20
+
21
+ if defined?( gem_const::Testing::TestCaseExtensions )
22
+ test_case_class.extend( gem_const::Testing::TestCaseExtensions )
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module FunWith
2
+ module Gems
3
+ module Testing
4
+ module Assertions
5
+ # Puts a gem through its paces
6
+ def assert_gem_is_fine( gem )
7
+ flunk
8
+ end
9
+
10
+ def assert_fun_gem( gem )
11
+ assert_kind_of( Module, gem )
12
+ assert_respond_to gem, :is_fun_gem?
13
+ assert gem.is_fun_gem?
14
+ end
15
+
16
+ def assert_version( gem, version )
17
+
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ module FunWith
2
+ module Gems
3
+ module Testing
4
+ module GemToTestMethods
5
+ # TODO: should use Inclusionizer?
6
+ def self.included( klass )
7
+ klass.extend( ClassMethods )
8
+ klass.extend( Constants )
9
+ klass.send( :include, InstanceMethods )
10
+ end
11
+
12
+
13
+ module ClassMethods
14
+ # What FunWith::Gems - derived gem is being tested? check as far up the class tree as needed.
15
+ def gem_to_test
16
+ @gem_to_test ||= nil
17
+ rval = @gem_to_test
18
+ rval = self.superclass.gem_to_test if !rval && self.superclass.respond_to?( :gem_to_test )
19
+ rval
20
+ end
21
+
22
+ attr_writer :gem_to_test
23
+ end
24
+
25
+ module InstanceMethods
26
+ def gem_to_test
27
+ self.class.gem_to_test
28
+ end
29
+ end
30
+
31
+ module Constants
32
+ GEM_TO_TEST_METHODS_LOADED = true
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ module FunWith
2
+ module Gems
3
+ module Testing
4
+ # Extensions to the FunWith::Testing::TestCase class.
5
+ module TestCaseExtensions
6
+ # config options
7
+ # :factory_bot => true : load FactoryBot factory definitions from the places FactoryBot expects them to live.
8
+ # :include => true : include the namespace of the gem being tested.
9
+ def make_testing_fun( testable_gem, config = {} )
10
+ include GemToTestMethods
11
+ install_basic_assertions # The assertions included by FunWith::Testing
12
+ install_gem_assertions # The assertions included by FunWith::Gems
13
+ install_yet_more_assertions( testable_gem )
14
+
15
+ self.gem_to_test = testable_gem
16
+
17
+ self.add_factorybot_support if config[:factory_bot] == true
18
+ self.send( :include, self.gem_to_test ) if config[:include] == true
19
+ end
20
+
21
+ def install_gem_assertions
22
+ include FunWith::Gems::Testing::Assertions
23
+ end
24
+
25
+ def install_yet_more_assertions( testable_gem )
26
+ if testable_gem.respond_to?( :root )
27
+ f = testable_gem.root( :test, "assertions.rb" )
28
+
29
+ require f if f.file?
30
+ end
31
+
32
+ if defined?( testable_gem::Testing::Assertions )
33
+
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ module FunWith
2
+ module Gems
3
+ module Testing
4
+ class TestResults
5
+ TEST_SUITE_DATA_REGEX = /(?<tests>\d+) (?:tests|runs), (?<assertions>\d+) assertions, (?<failures>\d+) failures, (?<errors>\d+) errors, (?<skips>\d+) skips/
6
+
7
+ attr_accessor :output, :test_results_found, :gem_const, :fail_count
8
+
9
+ def initialize g
10
+ self.gem_const = g
11
+ end
12
+
13
+ def passed?
14
+ self.scan_test_results
15
+ self.test_results_found? && no_failures_or_errors?
16
+ end
17
+
18
+ def test_results_found?
19
+ self.test_results_found
20
+ end
21
+
22
+ def no_failures_or_errors?
23
+ fail_count == 0
24
+ end
25
+
26
+ def scan_test_results
27
+ raise "No output to scan!" if self.output.nil?
28
+
29
+ if m = self.output.match( TEST_SUITE_DATA_REGEX )
30
+ self.test_results_found = true
31
+ self.fail_count = m[:failures].to_i + m[:errors].to_i
32
+ else
33
+ self.fail_count = -1
34
+ self.test_results_found = false
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,22 @@
1
+ module FunWith
2
+ module Gems
3
+ module Testing
4
+ class TestSetup
5
+ def self.setup( gem )
6
+ gem.gem_test_mode = true
7
+ require_test_libs( gem )
8
+ end
9
+
10
+ def self.require_test_libs( gem )
11
+ return false unless gem.respond_to?(:root)
12
+ groot = gem.root
13
+ return false unless groot.is_a?( FunWith::Files::FilePath )
14
+
15
+ test_lib_dir = groot / :test / :lib
16
+ test_lib_dir.requir if test_lib_dir.directory?
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+