fun_with_gems 0.0.3 → 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 (62) hide show
  1. checksums.yaml +5 -13
  2. data/.document +5 -0
  3. data/CHANGELOG.markdown +21 -0
  4. data/Gemfile +6 -11
  5. data/README.rdoc +125 -1
  6. data/ROADMAP.md +6 -0
  7. data/Rakefile +8 -7
  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 +31 -10
  15. data/lib/fun_with/gems/gem_api.rb +74 -52
  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 +26 -13
  19. data/lib/fun_with/gems/rakefile.rb +109 -1
  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 +13 -17
  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 -43
  56. data/lib/fun_with/gems/test_results.rb +0 -38
  57. data/lib/fun_with/gems/test_suite_runner.rb +0 -26
  58. data/lib/fun_with/gems/validator.rb +0 -50
  59. data/test/test_gem/lib/fun_with/llamas/llama.rb +0 -9
  60. data/test/test_gem/lib/fun_with/llamas/trainer.rb +0 -9
  61. /data/test/{test_gem → data/test_gems/fun_with_llamas}/VERSION +0 -0
  62. /data/test/{test_gem → data/test_gems/fun_with_llamas}/lib/fun_with_llamas.rb +0 -0
@@ -9,84 +9,106 @@ 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
28
- extend_constant_with_gem_api
37
+ set_gem_root unless @opts[:set_root] == false
38
+ set_gem_version unless @opts[:set_version] == false
29
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
+
30
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 )
31
64
  end
32
65
 
33
66
  protected
34
- def set_gem_const( gem_const )
35
- # Create new modules for this fun, fun gem, if necessary.
36
- if gem_const.is_a?( String )
37
- #create the module
38
- const = Object
39
- full_const_name = ""
40
- gem_const.split("::").each do |module_name|
41
- full_const_name << "::" unless full_const_name.fwf_blank?
42
- full_const_name << module_name
43
-
44
- if eval( "defined?(#{full_const_name})")
45
- const = eval( full_const_name )
46
- else
47
- const = const.const_set( module_name, Module.new )
48
- end
49
- end
50
-
51
- @gem_const = eval( gem_const )
52
- else
53
- @gem_const = gem_const
54
- end
67
+ def build_gem_const( gem_const )
68
+ ConstantBuilder.build_constant( gem_const )
55
69
  end
56
70
 
57
71
  def set_gem_root
58
- return if @opts[:set_root] == false
59
-
60
- # Hence, the "make_gem_fun()" directive should be called in the lib/gem_name.rb file.
61
- main_lib_file = @opts[:main_lib_file] || @caller_file
62
- root = @opts[:root] || main_lib_file.fwf_filepath.expand.dirname.up
63
-
64
- Files::RootPath.rootify( @gem_const, root )
72
+ RootSetter.set_root( @gem_const, @caller_file, @opts )
65
73
  end
66
-
74
+
67
75
  def set_gem_version
68
- return if @opts[:set_version] == false
69
- if @opts[:version]
70
- VersionStrings.versionize( @gem_const, @opts[:version] )
71
- else
72
- VersionStrings.versionize( @gem_const )
73
- end
76
+ Versionizer.versionize( @gem_const, @opts[:version] )
74
77
  end
75
78
 
76
79
  def require_libs
77
- unless @opts[:require] == false
78
- @opts[:require] ||= @gem_const.root( "lib" ).glob(:all, :recursive => false) - [ @caller_file ]
79
- @opts[:require] = [ @opts[:require] ] unless @opts[:require].is_a?(Array)
80
-
81
- @opts[:require].each do |req_dir|
82
- req_dir.fwf_filepath.expand.requir
83
- end
84
- end
80
+ opts = just_options( @opts, :require, :main_lib_file ).merge( :caller => @caller_file )
81
+ LibraryRequirer.require( @gem_const, opts )
85
82
  end
86
83
 
87
84
  def extend_constant_with_gem_api
88
- if defined?( @gem_const::GemAPI )
89
- @gem_const.extend( @gem_const::GemAPI )
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 )
111
+ end
90
112
  end
91
113
  end
92
114
  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
@@ -26,8 +26,7 @@ module FunWith
26
26
  end
27
27
 
28
28
  def run_bundler_setup
29
- jeweler_requirements
30
- rake_requirements
29
+ all_requirements
31
30
 
32
31
  begin
33
32
  Bundler.setup(:default, :development)
@@ -39,14 +38,14 @@ module FunWith
39
38
  end
40
39
 
41
40
  def specification &block
42
- Jeweler::Tasks.new do |gem|
41
+ Juwelier::Tasks.new do |gem|
43
42
  yield gem
44
43
  end
45
44
  end
46
45
 
47
46
  def setup_gem_boilerplate
48
47
  run_in_rakefile do
49
- Jeweler::RubygemsDotOrgTasks.new
48
+ Juwelier::RubygemsDotOrgTasks.new
50
49
 
51
50
  Rake::TestTask.new(:test) do |test|
52
51
  test.libs << 'lib' << 'test'
@@ -73,14 +72,14 @@ module FunWith
73
72
  end
74
73
  end
75
74
 
76
- def jeweler_requirements
77
- require 'rake'
78
- require 'jeweler'
79
- end
80
-
81
- def rake_requirements
82
- require 'rdoc/task'
83
- require 'rake/testtask'
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
84
83
  end
85
84
 
86
85
  def run_in_rakefile &block
@@ -89,9 +88,23 @@ module FunWith
89
88
  elsif ! block_given?
90
89
  raise ArgumentError.new("Block must be given")
91
90
  else
92
- @rake_main.instance_eval &block
91
+ @rake_main.instance_eval( &block )
93
92
  end
94
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
95
108
  end
96
109
  end
97
110
  end
@@ -1,6 +1,114 @@
1
1
  module FunWith
2
2
  module Gems
3
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
4
112
  end
5
113
  end
6
- 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
+
@@ -0,0 +1,28 @@
1
+ module FunWith
2
+ module Gems
3
+ module Testing
4
+ class TestSuiteRunner
5
+ attr_accessor :gem_const
6
+
7
+ def initialize fwgem
8
+ self.gem_const = fwgem
9
+ end
10
+
11
+ def passes_tests?
12
+ result = self.run_tests
13
+ result.passed?
14
+ end
15
+
16
+ def run_tests
17
+ filepath = self.gem_const.root
18
+
19
+ results = TestResults.new( self.gem_const )
20
+
21
+ puts "running tests on #{self.gem_const} from #{filepath}"
22
+ results.output = `cd #{filepath} && rake test`
23
+ results
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end