0.0
No commit activity in last 3 years
No release in over 3 years
This contains a bunch of shared, utility code that has no external dependencies apart from Ruby stdlib.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

>= 0
>= 0
 Project Readme

Golly-Utils Build Status

golly-utils is a collection of Ruby utility code with specific focus or application other than simply providing value when reused in multiple unrelated projects.

Features (highlights)

This is a subset of the available functionality. Browse the Yardoc or code for more.

Callbacks

GollyUtils::Callbacks -- Simple event-and-listener style callbacks with a few bells-and-whistles.

class Engine
  include GollyUtils::Callbacks
  define_callback :on_save
end

class HappyEngine < Engine
  on_save{ puts 'Saving!!'}
  on_save(priority: -1){ puts 'FIRST!' }
  on_save(priority:  1){ puts 'Last.' }
end

HappyEngine.new.run_callback :on_save     # => FIRST!
                                          # => Saving!!
                                          # => Last.

Declarative Attributes

attr_declarative -- Declarative attributes that avoid typos in subclasses, have default values, and more.

class Plugin
  attr_declarative :name, :author
  attr_declarative version: 10
  attr_declarative :hobby, required: true
end

class BluePlugin < Plugin
  name 'The Blue Plugin'
end

p = BluePlugin.new
puts p.name              # => The Blue Plugin
puts p.author            # => nil
puts p.version           # => 10
puts p.hobby             # => RuntimeError: Attribute 'hobby' required by Plugin but not set in BluePlugin.

Ruby Extension

  • Object.deep_dup with collection-aware implementations for Array and Hash.

  • Array to Hash conversion

    ['m','abc'].to_hash_keyed_by{ |v| v.length }   # => {1 => 'm', 3 => 'abc}
    [2,5].to_hash_with_values{ |k| 'xo' * k }      # => {2 => 'xoxo', 5 => 'xoxoxoxoxo'}
  • Enumerable.frequency_map

    %w[big house big car].frequency_map  # => {"big"=>2, "car"=>1, "house"=>1}
  • Kernel.at_exit_preserving_exit_status

  • Object.superclasses

    Fixnum.superclasses  # <= [Fixnum, Integer, Numeric, Object, BasicObject]
  • StandardError.to_pretty_s

  • GollyUtils::EnvHelpers

    ENV['debug'] = '1'     # can also be: y, yes, t, true, on, enabled
    ENV.on?('debug')       # <= true
    ENV.enabled?('debug')  # <= true
  • GollyUtils::Singleton -- Extends Ruby's Singleton module.

    class Stam1na
      include GollyUtils::Singleton
      def band_rating; puts 'AWESOME!!' end
    end
    
    # No need to call .instance all the time
    Stam1na.band_rating           #=> AWESOME!!
    Stam1na.instance.band_rating  #=> AWESOME!!
    
    # Provides a helper to define itself as an attribute in other classes
    # and use the singleton instance as the default.
    class ElseWhere
      Stam1na.def_accessor self
    end

Testing

  • RSpec Matchers

    # Array testing
    %w[a a b].should     equal_array %w[a a b]
    %w[b a b].should_not equal_array %w[a a b]
    %w[a b c d e f g h].should equal_array %w[B C d e f g h]
        # Failure/Error: expected that arrays would match.
        #   Missing elements: ["B", "C"]
        #   Unexpected elements: ["a", "b", "c"]
    
    # File system testing
    'lib'       .should     exist_as_a_dir
    'Gemfile'   .should_not exist_as_a_file
    '/tmp/stuff'.should     exist_as_a_file
        # Failure/Error: expected that '/tmp/stuff' would be an existing file.
        #   Files found in /tmp: .X0-lock  .s.PGSQL.5432.lock  .xfsm-ICE-TVOQMW
    
    
    # File content testing
    'version.txt'.should be_file_with_contents "2\n"
    'Gemfile'    .should be_file_with_contents(/['"]rspec['"]/).and(/['"]golly-utils['"]/)
    'Gemfile'    .should be_file_with_contents(/gemspec/).and_not(/rubygems/)
    'version.txt'.should be_file_with_contents("2").when_normalised_with(&:chomp)
    'stuff.txt'  .should be_file_with_contents(/ABC/)
                           .and(/DEF/)
                           .and(/123\n/)
                           .when_normalised_with(&:upcase)
                           .and(&:chomp)
  • Testing in clean-slate, empty directories

    # Test some code from an empty temp directory
    def test_stuff
      inside_empty_dir {
        puts Dir.pwd      # => /tmp/abcdef123567
      }
    end
    
    # RSpec declarations
    describe 'Demo' do
      run_each_in_empty_dir   # Each test/example will be run in its own empty temp dir
      run_all_in_empty_dir    # Each test/example will be run in the same empty temp dir
    end
  • Polling

    within(5).seconds{ 'Gemfile'.should exist_as_a_file }
  • Dynamic Fixtures

    # Provides globally-shared, cached, lazily-loaded fixtures that are generated once on-demand,
    # and copied when access is required.
    describe 'My Git Utility' do
      include GollyUtils::Testing::DynamicFixtures
    
      def_fixture :git do                             # Dynamic fixture definition.
        system 'git init'                             # Expensive to create.
        File.write 'test.txt', 'hello'                # Only runs once.
        system 'git add -A && git commit -m x'
      end
    
      run_each_in_dynamic_fixture :git                # RSpec helper for fixture usage.
    
      it("detects deleted files") {                   # Runs in a copy of the fixture.
        File.delete 'test.txt'                        # Free to modify its fixture copy.
        subject.deleted_files.should == %w[test.txt]  # Other tests isolated from these these changes.
      }
    
      it("detects new files") {                       # Runs in a clean copy of the fixture.
        File.create 'new.txt'                         # Generated quickly by copying cache.
        subject.new_files.should == %w[new.txt]       # Unaffected by other tests' fixture modification.
      }
    
    end

Validation

  • Object.validate_type!

    3     .validate_type nil, Numeric
    nil   .validate_type nil, Numeric
    'What'.validate_type nil, Numeric # <= raises TypeValidationError
    tracer.validate_type! 'the tracer flag', true, false  # Validate boolean with nice err msg
  • Symbol.validate_lvar_type! -- Validates local variables without you having to specify the variable value or name in error messages.

    def save_person(name, eyes)
      :name.validate_lvar_type!{ String }
      :eyes.validate_lvar_type!{ [nil,Fixnum] }
  • Hash.validate_keys

  • Hash.validate_option_keys

 

 


Legal

Copyright © 2012 David Barri.

This program is licenced under the LGPL (Lesser General Public License). For details see LICENCE-LGPL.txt or http://www.gnu.org/licenses/lgpl-3.0.txt.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.