slither-ruby19 0.99.3
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.
- data/History.txt +16 -0
 - data/README.rdoc +100 -0
 - data/Rakefile +37 -0
 - data/TODO +13 -0
 - data/lib/slither.rb +7 -0
 - data/lib/slither/column.rb +126 -0
 - data/lib/slither/definition.rb +33 -0
 - data/lib/slither/generator.rb +26 -0
 - data/lib/slither/parser.rb +53 -0
 - data/lib/slither/section.rb +76 -0
 - data/lib/slither/slither.rb +49 -0
 - data/slither.gemspec +0 -0
 - data/spec/column_spec.rb +224 -0
 - data/spec/definition_spec.rb +85 -0
 - data/spec/generator_spec.rb +42 -0
 - data/spec/parser_spec.rb +74 -0
 - data/spec/section_spec.rb +146 -0
 - data/spec/slither_spec.rb +84 -0
 - data/spec/spec_helper.rb +4 -0
 - metadata +104 -0
 
    
        data/History.txt
    ADDED
    
    | 
         @@ -0,0 +1,16 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
              
         
     | 
| 
      
 2 
     | 
    
         
            +
            == 0.99.2 / 2009-04-28
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            * Added better support for float formatting
         
     | 
| 
      
 5 
     | 
    
         
            +
            * Added the money_with_implied_decimal type
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
            == 0.99.1 / 2009-04-22
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Make the missing method build a column  i.e. body.record_type 1
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Prevent duplicate column names
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Better error messages
         
     | 
| 
      
 12 
     | 
    
         
            +
            * Implement custom padding (spaces (default), zero)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            == 0.99.0 / 2009-04-14
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            * Initial Release
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            == slither
         
     | 
| 
      
 2 
     | 
    
         
            +
                by Ryan Wood
         
     | 
| 
      
 3 
     | 
    
         
            +
                http://ryanwood.com
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            == DESCRIPTION:
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            A simple, clean DSL for describing, writing, and parsing fixed-width text files.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            == FEATURES:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            * Easy DSL syntax
         
     | 
| 
      
 12 
     | 
    
         
            +
            * Can parse and format fixed width files
         
     | 
| 
      
 13 
     | 
    
         
            +
            * Templated sections for reuse
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            == SYNOPSIS:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              # Create a Slither::Defintion to describe a file format
         
     | 
| 
      
 18 
     | 
    
         
            +
              Slither.define :simple do |d|
         
     | 
| 
      
 19 
     | 
    
         
            +
              
         
     | 
| 
      
 20 
     | 
    
         
            +
                # This is a template section that can be reused in other sections
         
     | 
| 
      
 21 
     | 
    
         
            +
                d.template :boundary do |t|
         
     | 
| 
      
 22 
     | 
    
         
            +
                  t.column :record_type, 4  
         
     | 
| 
      
 23 
     | 
    
         
            +
                  t.column :company_id, 12      
         
     | 
| 
      
 24 
     | 
    
         
            +
                end 
         
     | 
| 
      
 25 
     | 
    
         
            +
               
         
     | 
| 
      
 26 
     | 
    
         
            +
                # Create a header section
         
     | 
| 
      
 27 
     | 
    
         
            +
                d.header, :align => :left do |header|      
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # The trap tells Slither which lines should fall into this section
         
     | 
| 
      
 29 
     | 
    
         
            +
                  header.trap { |line| line[0,4] == 'HEAD' }
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # Use the boundary template for the columns
         
     | 
| 
      
 31 
     | 
    
         
            +
                  header.template :boundary
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              
         
     | 
| 
      
 34 
     | 
    
         
            +
                d.body do |body|
         
     | 
| 
      
 35 
     | 
    
         
            +
                  body.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
         
     | 
| 
      
 36 
     | 
    
         
            +
                  body.column :id, 10, :type => :integer
         
     | 
| 
      
 37 
     | 
    
         
            +
                  body.column :name, 10, :align => :left
         
     | 
| 
      
 38 
     | 
    
         
            +
                  body.spacer 3
         
     | 
| 
      
 39 
     | 
    
         
            +
                  body.column :state, 2
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    
         
     | 
| 
      
 42 
     | 
    
         
            +
                d.footer do |footer|
         
     | 
| 
      
 43 
     | 
    
         
            +
                  footer.trap { |line| line[0,4] == 'FOOT' }
         
     | 
| 
      
 44 
     | 
    
         
            +
                  footer.template :boundary
         
     | 
| 
      
 45 
     | 
    
         
            +
                  footer.column :record_count, 10
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              
         
     | 
| 
      
 49 
     | 
    
         
            +
            Supported types are: string, integer, date, float, money, and money_with_implied_decimal.
         
     | 
| 
      
 50 
     | 
    
         
            +
              
         
     | 
| 
      
 51 
     | 
    
         
            +
            Then either feed it a nested struct with data values to create the file in the defined format:
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              test_data = {
         
     | 
| 
      
 54 
     | 
    
         
            +
                :body => [
         
     | 
| 
      
 55 
     | 
    
         
            +
                  { :id => 12, :name => "Ryan", :state => 'SC' },
         
     | 
| 
      
 56 
     | 
    
         
            +
                  { :id => 23, :name => "Joe", :state => 'VA' },
         
     | 
| 
      
 57 
     | 
    
         
            +
                  { :id => 42, :name => "Tommy", :state => 'FL' },
         
     | 
| 
      
 58 
     | 
    
         
            +
                ], 
         
     | 
| 
      
 59 
     | 
    
         
            +
                :header => { :record_type => 'HEAD', :company_id => 'ABC'  }, 
         
     | 
| 
      
 60 
     | 
    
         
            +
                :footer => { :record_type => 'FOOT', :company_id => 'ABC'  }
         
     | 
| 
      
 61 
     | 
    
         
            +
              }
         
     | 
| 
      
 62 
     | 
    
         
            +
              
         
     | 
| 
      
 63 
     | 
    
         
            +
              # Generates the file as a string
         
     | 
| 
      
 64 
     | 
    
         
            +
              puts Slither.generate(:simple, test_data)
         
     | 
| 
      
 65 
     | 
    
         
            +
              
         
     | 
| 
      
 66 
     | 
    
         
            +
              # Writes the file
         
     | 
| 
      
 67 
     | 
    
         
            +
              Slither.write('outfile.txt', :simple, test_data)
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            or parse files already in that format into a nested hash:
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              parsed_data = Slither.parse('infile.txt', :test).inspect
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            == INSTALL:
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            sudo gem install slither
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            == LICENSE:
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            (The MIT License)
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            Copyright (c) 2008
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 84 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 85 
     | 
    
         
            +
            'Software'), to deal in the Software without restriction, including
         
     | 
| 
      
 86 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 87 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 88 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 89 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 92 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 95 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 96 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
         
     | 
| 
      
 97 
     | 
    
         
            +
            IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
         
     | 
| 
      
 98 
     | 
    
         
            +
            CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
         
     | 
| 
      
 99 
     | 
    
         
            +
            TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
         
     | 
| 
      
 100 
     | 
    
         
            +
            SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'spec/rake/spectask'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            desc "Run all examples with RCov"
         
     | 
| 
      
 5 
     | 
    
         
            +
            Spec::Rake::SpecTask.new('rcov') do |t|
         
     | 
| 
      
 6 
     | 
    
         
            +
              t.spec_files = FileList['spec/*.rb']
         
     | 
| 
      
 7 
     | 
    
         
            +
              t.rcov = true
         
     | 
| 
      
 8 
     | 
    
         
            +
              t.rcov_opts = ['--exclude', 'spec']
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            begin
         
     | 
| 
      
 12 
     | 
    
         
            +
              require 'bones'
         
     | 
| 
      
 13 
     | 
    
         
            +
              Bones.setup
         
     | 
| 
      
 14 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 15 
     | 
    
         
            +
              load 'tasks/setup.rb'
         
     | 
| 
      
 16 
     | 
    
         
            +
            end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            ensure_in_path 'lib'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require 'bones'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            task :default => 'spec:run'
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            PROJ.name = 'slither'
         
     | 
| 
      
 24 
     | 
    
         
            +
            PROJ.authors = 'Ryan Wood'
         
     | 
| 
      
 25 
     | 
    
         
            +
            PROJ.email = 'ryan.wood@gmail.com'
         
     | 
| 
      
 26 
     | 
    
         
            +
            PROJ.url = 'http://github.com/ryanwood/slither'
         
     | 
| 
      
 27 
     | 
    
         
            +
            PROJ.version = '0.99.3'
         
     | 
| 
      
 28 
     | 
    
         
            +
            PROJ.exclude = %w(\.git .gitignore ^tasks \.eprj ^pkg)
         
     | 
| 
      
 29 
     | 
    
         
            +
            PROJ.readme_file = 'README.rdoc'
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            #PROJ.rubyforge.name = 'codeforpeople'
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            PROJ.rdoc.exclude << '^data'
         
     | 
| 
      
 34 
     | 
    
         
            +
            PROJ.notes.exclude = %w(^README\.rdoc$ ^data ^pkg)
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            # PROJ.svn.path = 'bones'
         
     | 
| 
      
 37 
     | 
    
         
            +
            # PROJ.spec.opts << '--color'
         
     | 
    
        data/TODO
    ADDED
    
    | 
         @@ -0,0 +1,13 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            == 0.99.2
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Add :limit option on sections
         
     | 
| 
      
 4 
     | 
    
         
            +
            * Add :validation option for columns
         
     | 
| 
      
 5 
     | 
    
         
            +
            * Add a validate_file() method to parse a file and run all validation tests (implies validation implemented)
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            == 1.0.0
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Better Documentation
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            == 1.x
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            * Alternate Section Flow (other than linear), i.e. repeatable sections (think batch)
         
     | 
    
        data/lib/slither.rb
    ADDED
    
    
| 
         @@ -0,0 +1,126 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'date'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class Slither
         
     | 
| 
      
 4 
     | 
    
         
            +
              class ParserError < RuntimeError; end
         
     | 
| 
      
 5 
     | 
    
         
            +
              
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Column
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :name, :length, :alignment, :type, :padding, :precision, :options
         
     | 
| 
      
 8 
     | 
    
         
            +
                
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(name, length, options = {})
         
     | 
| 
      
 10 
     | 
    
         
            +
                  assert_valid_options(options)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @length = length
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @options = options
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @alignment = options[:align] || :right
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @type = options[:type] || :string
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @padding = options[:padding] || :space
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @truncate = options[:truncate] || false
         
     | 
| 
      
 18 
     | 
    
         
            +
                  # Only used with floats, this determines the decimal places
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @precision = options[:precision] 
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
                
         
     | 
| 
      
 22 
     | 
    
         
            +
                def unpacker
         
     | 
| 
      
 23 
     | 
    
         
            +
                  "A#{@length}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
                   
         
     | 
| 
      
 26 
     | 
    
         
            +
                def parse(value)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  case @type
         
     | 
| 
      
 28 
     | 
    
         
            +
                    when :integer
         
     | 
| 
      
 29 
     | 
    
         
            +
                      value.to_i
         
     | 
| 
      
 30 
     | 
    
         
            +
                    when :float, :money
         
     | 
| 
      
 31 
     | 
    
         
            +
                      value.to_f
         
     | 
| 
      
 32 
     | 
    
         
            +
                    when :money_with_implied_decimal
         
     | 
| 
      
 33 
     | 
    
         
            +
                      value.to_f / 100
         
     | 
| 
      
 34 
     | 
    
         
            +
                    when :date
         
     | 
| 
      
 35 
     | 
    
         
            +
                      if @options[:format]
         
     | 
| 
      
 36 
     | 
    
         
            +
                        Date.strptime(value, @options[:format])
         
     | 
| 
      
 37 
     | 
    
         
            +
                      else
         
     | 
| 
      
 38 
     | 
    
         
            +
                        Date.strptime(value)
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    else value.strip
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 43 
     | 
    
         
            +
                  raise ParserError, "The value '#{value}' could not be converted to type #{@type}: #{$!}"
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
                
         
     | 
| 
      
 46 
     | 
    
         
            +
                def format(value)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  pad(formatter % to_s(value))
         
     | 
| 
      
 48 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 49 
     | 
    
         
            +
                  puts "Could not format column '#{@name}' as a '#{@type}' with formatter '#{formatter}' and value of '#{value}' (formatted: '#{to_s(value)}'). #{$!}"
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                   
         
     | 
| 
      
 52 
     | 
    
         
            +
                private
         
     | 
| 
      
 53 
     | 
    
         
            +
                
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def formatter
         
     | 
| 
      
 55 
     | 
    
         
            +
                    "%#{aligner}#{sizer}s"
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                      
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def aligner
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @alignment == :left ? '-' : ''
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  
         
     | 
| 
      
 62 
     | 
    
         
            +
                  def sizer
         
     | 
| 
      
 63 
     | 
    
         
            +
                    (@type == :float && @precision) ? @precision : @length
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                  
         
     | 
| 
      
 66 
     | 
    
         
            +
                  # Manually apply padding. sprintf only allows padding on numeric fields.
         
     | 
| 
      
 67 
     | 
    
         
            +
                  def pad(value)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  	return value unless @padding == :zero
         
     | 
| 
      
 69 
     | 
    
         
            +
                  	matcher = @alignment == :right ? /^ +/ : / +$/
         
     | 
| 
      
 70 
     | 
    
         
            +
                  	space = value.match(matcher)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  	return value unless space
         
     | 
| 
      
 72 
     | 
    
         
            +
                  	value.gsub(space[0], '0' * space[0].size)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                  
         
     | 
| 
      
 75 
     | 
    
         
            +
                  def to_s(value)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    result = case @type
         
     | 
| 
      
 77 
     | 
    
         
            +
                      when :date            
         
     | 
| 
      
 78 
     | 
    
         
            +
                        # If it's a DBI::Timestamp object, see if we can convert it to a Time object
         
     | 
| 
      
 79 
     | 
    
         
            +
                        unless value.respond_to?(:strftime)
         
     | 
| 
      
 80 
     | 
    
         
            +
                          value = value.to_time if value.respond_to?(:to_time)
         
     | 
| 
      
 81 
     | 
    
         
            +
                        end
         
     | 
| 
      
 82 
     | 
    
         
            +
                        if value.respond_to?(:strftime)        
         
     | 
| 
      
 83 
     | 
    
         
            +
                          if @options[:format]
         
     | 
| 
      
 84 
     | 
    
         
            +
                            value.strftime(@options[:format])
         
     | 
| 
      
 85 
     | 
    
         
            +
                          else
         
     | 
| 
      
 86 
     | 
    
         
            +
                            value.strftime
         
     | 
| 
      
 87 
     | 
    
         
            +
                          end
         
     | 
| 
      
 88 
     | 
    
         
            +
                        else
         
     | 
| 
      
 89 
     | 
    
         
            +
                          value.to_s
         
     | 
| 
      
 90 
     | 
    
         
            +
                        end
         
     | 
| 
      
 91 
     | 
    
         
            +
                      when :float
         
     | 
| 
      
 92 
     | 
    
         
            +
                        @options[:format] ? @options[:format] % value.to_f : value.to_f.to_s
         
     | 
| 
      
 93 
     | 
    
         
            +
                      when :money
         
     | 
| 
      
 94 
     | 
    
         
            +
                        "%.2f" % value.to_f
         
     | 
| 
      
 95 
     | 
    
         
            +
                      when :money_with_implied_decimal
         
     | 
| 
      
 96 
     | 
    
         
            +
                        "%d" % (value.to_f * 100)
         
     | 
| 
      
 97 
     | 
    
         
            +
                      else 
         
     | 
| 
      
 98 
     | 
    
         
            +
                        value.to_s
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
      
 100 
     | 
    
         
            +
                    validate_size result
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                  def assert_valid_options(options)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    unless options[:align].nil? || [:left, :right].include?(options[:align])
         
     | 
| 
      
 105 
     | 
    
         
            +
                      raise ArgumentError, "Option :align only accepts :right (default) or :left"
         
     | 
| 
      
 106 
     | 
    
         
            +
                    end
         
     | 
| 
      
 107 
     | 
    
         
            +
                    unless options[:padding].nil? || [:space, :zero].include?(options[:padding])
         
     | 
| 
      
 108 
     | 
    
         
            +
                      raise ArgumentError, "Option :padding only accepts :space (default) or :zero"
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
                  
         
     | 
| 
      
 112 
     | 
    
         
            +
                  def validate_size(result)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    # Handle when length is out of range
         
     | 
| 
      
 114 
     | 
    
         
            +
                    if result.length > @length
         
     | 
| 
      
 115 
     | 
    
         
            +
                      if @truncate
         
     | 
| 
      
 116 
     | 
    
         
            +
                        start = @alignment == :left ? 0 : -@length
         
     | 
| 
      
 117 
     | 
    
         
            +
                        result = result[start, @length]
         
     | 
| 
      
 118 
     | 
    
         
            +
                      else
         
     | 
| 
      
 119 
     | 
    
         
            +
                        raise Slither::FormattedStringExceedsLengthError, 
         
     | 
| 
      
 120 
     | 
    
         
            +
                          "The formatted value '#{result}' in column '#{@name}' exceeds the allowed length of #{@length} chararacters."
         
     | 
| 
      
 121 
     | 
    
         
            +
                      end
         
     | 
| 
      
 122 
     | 
    
         
            +
                    end
         
     | 
| 
      
 123 
     | 
    
         
            +
                    result
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
              end  
         
     | 
| 
      
 126 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Slither  
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Definition
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :sections, :templates, :options
         
     | 
| 
      
 4 
     | 
    
         
            +
                
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(options = {})
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @sections = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @templates = {}
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @options = { :align => :right }.merge(options)
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
                
         
     | 
| 
      
 11 
     | 
    
         
            +
                def section(name, options = {}, &block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  raise( ArgumentError, "Reserved or duplicate section name: '#{name}'") if  
         
     | 
| 
      
 13 
     | 
    
         
            +
                  Section::RESERVED_NAMES.include?( name ) || 
         
     | 
| 
      
 14 
     | 
    
         
            +
                  (@sections.size > 0 && @sections.map{ |s| s.name }.include?( name ))
         
     | 
| 
      
 15 
     | 
    
         
            +
                
         
     | 
| 
      
 16 
     | 
    
         
            +
                  section = Slither::Section.new(name, @options.merge(options))
         
     | 
| 
      
 17 
     | 
    
         
            +
                  section.definition = self
         
     | 
| 
      
 18 
     | 
    
         
            +
                  yield(section)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @sections << section
         
     | 
| 
      
 20 
     | 
    
         
            +
                  section
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                def template(name, options = {}, &block)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  section = Slither::Section.new(name, @options.merge(options))
         
     | 
| 
      
 25 
     | 
    
         
            +
                  yield(section)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @templates[name] = section
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
                
         
     | 
| 
      
 29 
     | 
    
         
            +
                def method_missing(method, *args, &block)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  section(method, *args, &block)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end  
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Slither
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Generator
         
     | 
| 
      
 3 
     | 
    
         
            +
            		
         
     | 
| 
      
 4 
     | 
    
         
            +
            		def initialize(definition)
         
     | 
| 
      
 5 
     | 
    
         
            +
            			@definition = definition
         
     | 
| 
      
 6 
     | 
    
         
            +
            		end
         
     | 
| 
      
 7 
     | 
    
         
            +
            		
         
     | 
| 
      
 8 
     | 
    
         
            +
            		def generate(data)
         
     | 
| 
      
 9 
     | 
    
         
            +
            	    @builder = []
         
     | 
| 
      
 10 
     | 
    
         
            +
            	    @definition.sections.each do |section|
         
     | 
| 
      
 11 
     | 
    
         
            +
            	      content = data[section.name]
         
     | 
| 
      
 12 
     | 
    
         
            +
            	      if content
         
     | 
| 
      
 13 
     | 
    
         
            +
              	      content = [content] unless content.is_a?(Array)
         
     | 
| 
      
 14 
     | 
    
         
            +
              	      raise(Slither::RequiredSectionEmptyError, "Required section '#{section.name}' was empty.") if content.empty?
         
     | 
| 
      
 15 
     | 
    
         
            +
              	      content.each do |row|
         
     | 
| 
      
 16 
     | 
    
         
            +
              	        @builder << section.format(row)
         
     | 
| 
      
 17 
     | 
    
         
            +
              	      end
         
     | 
| 
      
 18 
     | 
    
         
            +
              	    else
         
     | 
| 
      
 19 
     | 
    
         
            +
              	      raise(Slither::RequiredSectionEmptyError, "Required section '#{section.name}' was empty.") unless section.optional
         
     | 
| 
      
 20 
     | 
    
         
            +
            	      end
         
     | 
| 
      
 21 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 22 
     | 
    
         
            +
            	    @builder.join("\n")
         
     | 
| 
      
 23 
     | 
    
         
            +
            		end
         
     | 
| 
      
 24 
     | 
    
         
            +
            		
         
     | 
| 
      
 25 
     | 
    
         
            +
            	end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Slither
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Parser
         
     | 
| 
      
 3 
     | 
    
         
            +
                    
         
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(definition, file)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  @definition = definition
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @file = file
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # This may be used in the future for non-linear or repeating sections
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @mode = :linear
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
                
         
     | 
| 
      
 11 
     | 
    
         
            +
                def parse()
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @parsed = {}
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @content = read_file      
         
     | 
| 
      
 14 
     | 
    
         
            +
                  unless @content.empty?
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @definition.sections.each do |section|
         
     | 
| 
      
 16 
     | 
    
         
            +
                      rows = fill_content(section)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      raise(Slither::RequiredSectionNotFoundError, "Required section '#{section.name}' was not found.") unless rows > 0 || section.optional
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @parsed
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                private
         
     | 
| 
      
 24 
     | 
    
         
            +
                
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def read_file
         
     | 
| 
      
 26 
     | 
    
         
            +
                    content = []
         
     | 
| 
      
 27 
     | 
    
         
            +
                    File.open(@file, 'r') do |f|
         
     | 
| 
      
 28 
     | 
    
         
            +
                      while (line = f.gets) do
         
     | 
| 
      
 29 
     | 
    
         
            +
                        content << line
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                    content
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def fill_content(section)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    matches = 0
         
     | 
| 
      
 37 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 38 
     | 
    
         
            +
                      line = @content.first
         
     | 
| 
      
 39 
     | 
    
         
            +
                      break unless section.match(line) 
         
     | 
| 
      
 40 
     | 
    
         
            +
                      add_to_section(section, line)
         
     | 
| 
      
 41 
     | 
    
         
            +
                      matches += 1
         
     | 
| 
      
 42 
     | 
    
         
            +
                      @content.shift
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                    matches
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  
         
     | 
| 
      
 47 
     | 
    
         
            +
                  def add_to_section(section, line)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @parsed[section.name] = [] unless @parsed[section.name]
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @parsed[section.name] << section.parse(line)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,76 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Slither
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Section
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_accessor :definition, :optional
         
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :name, :columns, :options
         
     | 
| 
      
 5 
     | 
    
         
            +
                
         
     | 
| 
      
 6 
     | 
    
         
            +
                RESERVED_NAMES = [:spacer]
         
     | 
| 
      
 7 
     | 
    
         
            +
                
         
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(name, options = {})
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @options = options
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @columns = []
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @trap = options[:trap]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @optional = options[:optional] || false
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
                
         
     | 
| 
      
 16 
     | 
    
         
            +
                def column(name, length, options = {})
         
     | 
| 
      
 17 
     | 
    
         
            +
                  raise(Slither::DuplicateColumnNameError, "You have already defined a column named '#{name}'.") if @columns.map do |c|
         
     | 
| 
      
 18 
     | 
    
         
            +
                    RESERVED_NAMES.include?(c.name) ? nil : c.name
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end.flatten.include?(name)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  col = Column.new(name, length, @options.merge(options))
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @columns << col
         
     | 
| 
      
 22 
     | 
    
         
            +
                  col
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                
         
     | 
| 
      
 25 
     | 
    
         
            +
                def spacer(length)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  column(:spacer, length)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
                
         
     | 
| 
      
 29 
     | 
    
         
            +
                def trap(&block)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @trap = block
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                
         
     | 
| 
      
 33 
     | 
    
         
            +
                def template(name)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  template = @definition.templates[name]
         
     | 
| 
      
 35 
     | 
    
         
            +
                  raise ArgumentError, "Template #{name} not found as a known template." unless template
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @columns = @columns + template.columns
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # Section options should trump template options
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @options = template.options.merge(@options)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                
         
     | 
| 
      
 41 
     | 
    
         
            +
                def format(data)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  # raise( ColumnMismatchError,
         
     | 
| 
      
 43 
     | 
    
         
            +
                  #   "The '#{@name}' section has #{@columns.size} column(s) defined, but there are #{data.size} column(s) provided in the data."
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # ) unless @columns.size == data.size
         
     | 
| 
      
 45 
     | 
    
         
            +
                  row = ''      
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @columns.each do |column|
         
     | 
| 
      
 47 
     | 
    
         
            +
                    row += column.format(data[column.name])
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  row
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                
         
     | 
| 
      
 52 
     | 
    
         
            +
                def parse(line)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  line_data = line.unpack(unpacker)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  row = {}
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @columns.each_with_index do |c, i|
         
     | 
| 
      
 56 
     | 
    
         
            +
                    row[c.name] = c.parse(line_data[i]) unless RESERVED_NAMES.include?(c.name)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  row
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
                
         
     | 
| 
      
 61 
     | 
    
         
            +
                def match(raw_line)
         
     | 
| 
      
 62 
     | 
    
         
            +
                  raw_line.nil? ? false : @trap.call(raw_line)
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
                
         
     | 
| 
      
 65 
     | 
    
         
            +
                def method_missing(method, *args)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  column(method, *args)
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
              
         
     | 
| 
      
 69 
     | 
    
         
            +
                private
         
     | 
| 
      
 70 
     | 
    
         
            +
                  
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def unpacker
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @columns.map { |c| c.unpacker }.join('')
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              end  
         
     | 
| 
      
 76 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Slither
         
     | 
| 
      
 2 
     | 
    
         
            +
              
         
     | 
| 
      
 3 
     | 
    
         
            +
              VERSION = '0.99.0'
         
     | 
| 
      
 4 
     | 
    
         
            +
              
         
     | 
| 
      
 5 
     | 
    
         
            +
              class DuplicateColumnNameError < StandardError; end
         
     | 
| 
      
 6 
     | 
    
         
            +
              class RequiredSectionNotFoundError < StandardError; end
         
     | 
| 
      
 7 
     | 
    
         
            +
              class RequiredSectionEmptyError < StandardError; end
         
     | 
| 
      
 8 
     | 
    
         
            +
              class FormattedStringExceedsLengthError < StandardError; end
         
     | 
| 
      
 9 
     | 
    
         
            +
              class ColumnMismatchError < StandardError; end
         
     | 
| 
      
 10 
     | 
    
         
            +
              
         
     | 
| 
      
 11 
     | 
    
         
            +
              
         
     | 
| 
      
 12 
     | 
    
         
            +
              def self.define(name, options = {}, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                definition = Definition.new(options)
         
     | 
| 
      
 14 
     | 
    
         
            +
                yield(definition)
         
     | 
| 
      
 15 
     | 
    
         
            +
                definitions[name] = definition
         
     | 
| 
      
 16 
     | 
    
         
            +
                definition
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              
         
     | 
| 
      
 19 
     | 
    
         
            +
              def self.generate(definition_name, data)
         
     | 
| 
      
 20 
     | 
    
         
            +
                definition = definition(definition_name)
         
     | 
| 
      
 21 
     | 
    
         
            +
                raise ArgumentError, "Definition name '#{name}' was not found." unless definition
         
     | 
| 
      
 22 
     | 
    
         
            +
                generator = Generator.new(definition)
         
     | 
| 
      
 23 
     | 
    
         
            +
                generator.generate(data)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              
         
     | 
| 
      
 26 
     | 
    
         
            +
              def self.write(filename, definition_name, data)
         
     | 
| 
      
 27 
     | 
    
         
            +
                File.open(filename, 'w') do |f|
         
     | 
| 
      
 28 
     | 
    
         
            +
                  f.write generate(definition_name, data)  
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
              
         
     | 
| 
      
 32 
     | 
    
         
            +
              def self.parse(filename, definition_name)
         
     | 
| 
      
 33 
     | 
    
         
            +
                raise ArgumentError, "File #{filename} does not exist." unless File.exists?(filename)
         
     | 
| 
      
 34 
     | 
    
         
            +
                definition = definition(definition_name)
         
     | 
| 
      
 35 
     | 
    
         
            +
                raise ArgumentError, "Definition name '#{definition_name}' was not found." unless definition    
         
     | 
| 
      
 36 
     | 
    
         
            +
                parser = Parser.new(definition, filename)
         
     | 
| 
      
 37 
     | 
    
         
            +
                parser.parse    
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
              
         
     | 
| 
      
 40 
     | 
    
         
            +
              private
         
     | 
| 
      
 41 
     | 
    
         
            +
              
         
     | 
| 
      
 42 
     | 
    
         
            +
                def self.definitions
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @@definitions ||= {}
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
                
         
     | 
| 
      
 46 
     | 
    
         
            +
                def self.definition(name)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  definitions[name]
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
    
        data/slither.gemspec
    ADDED
    
    | 
         Binary file 
     | 
    
        data/spec/column_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,224 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
                
         
     | 
| 
      
 3 
     | 
    
         
            +
            describe Slither::Column do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @name = :id
         
     | 
| 
      
 6 
     | 
    
         
            +
                @length = 5
         
     | 
| 
      
 7 
     | 
    
         
            +
                @column = Slither::Column.new(@name, @length)
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              describe "when being created" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                it "should have a name" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @column.name.should == @name
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
                
         
     | 
| 
      
 15 
     | 
    
         
            +
                it "should have a length" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @column.length.should == @length
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
                
         
     | 
| 
      
 19 
     | 
    
         
            +
                it "should have a default padding" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @column.padding.should == :space
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                it "should have a default alignment" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @column.alignment.should == :right
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
               
         
     | 
| 
      
 27 
     | 
    
         
            +
                it "should return a proper formatter" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @column.send(:formatter).should == "%5s"
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              describe "when specifying an alignment" do
         
     | 
| 
      
 33 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :align => :left)
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
                
         
     | 
| 
      
 37 
     | 
    
         
            +
                it "should only accept :right or :left for an alignment" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  lambda{ Slither::Column.new(@name, @length, :align => :bogus) }.should raise_error(ArgumentError, "Option :align only accepts :right (default) or :left")
         
     | 
| 
      
 39 
     | 
    
         
            +
                end 
         
     | 
| 
      
 40 
     | 
    
         
            +
                    
         
     | 
| 
      
 41 
     | 
    
         
            +
                it "should override the default alignment" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @column.alignment.should == :left
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
              
         
     | 
| 
      
 46 
     | 
    
         
            +
              describe "when specifying padding" do
         
     | 
| 
      
 47 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :padding => :zero)
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                it "should accept only :space or :zero" do
         
     | 
| 
      
 52 
     | 
    
         
            +
                  lambda{ Slither::Column.new(@name, @length, :padding => :bogus) }.should raise_error(ArgumentError, "Option :padding only accepts :space (default) or :zero")  
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
                
         
     | 
| 
      
 55 
     | 
    
         
            +
                it "should override the default padding" do
         
     | 
| 
      
 56 
     | 
    
         
            +
                  @column.padding.should == :zero
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              it "should return the proper unpack value for a string" do
         
     | 
| 
      
 61 
     | 
    
         
            +
                @column.send(:unpacker).should == 'A5'
         
     | 
| 
      
 62 
     | 
    
         
            +
              end
         
     | 
| 
      
 63 
     | 
    
         
            +
                
         
     | 
| 
      
 64 
     | 
    
         
            +
              describe "when parsing a value from a file" do    
         
     | 
| 
      
 65 
     | 
    
         
            +
                it "should default to a string" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                  @column.parse('    name ').should == 'name'
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @column.parse('      234').should == '234'
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @column.parse('000000234').should == '000000234'
         
     | 
| 
      
 69 
     | 
    
         
            +
                  @column.parse('12.34').should == '12.34'
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
              
         
     | 
| 
      
 72 
     | 
    
         
            +
                it "should support the integer type" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type=> :integer)
         
     | 
| 
      
 74 
     | 
    
         
            +
                  @column.parse('234     ').should == 234
         
     | 
| 
      
 75 
     | 
    
         
            +
                  @column.parse('     234').should == 234
         
     | 
| 
      
 76 
     | 
    
         
            +
                  @column.parse('00000234').should == 234
         
     | 
| 
      
 77 
     | 
    
         
            +
                  @column.parse('Ryan    ').should == 0
         
     | 
| 
      
 78 
     | 
    
         
            +
                  @column.parse('00023.45').should == 23
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                it "should support the float type" do
         
     | 
| 
      
 82 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type=> :float)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  @column.parse('  234.45').should == 234.45
         
     | 
| 
      
 84 
     | 
    
         
            +
                  @column.parse('234.5600').should == 234.56
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @column.parse('     234').should == 234.0
         
     | 
| 
      
 86 
     | 
    
         
            +
                  @column.parse('00000234').should == 234.0
         
     | 
| 
      
 87 
     | 
    
         
            +
                  @column.parse('Ryan    ').should == 0
         
     | 
| 
      
 88 
     | 
    
         
            +
                  @column.parse('00023.45').should == 23.45
         
     | 
| 
      
 89 
     | 
    
         
            +
                end
         
     | 
| 
      
 90 
     | 
    
         
            +
                
         
     | 
| 
      
 91 
     | 
    
         
            +
                it "should support the money_with_implied_decimal type" do
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type=> :money_with_implied_decimal)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  @column.parse('   23445').should == 234.45
         
     | 
| 
      
 94 
     | 
    
         
            +
                end    
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                it "should support the date type" do
         
     | 
| 
      
 97 
     | 
    
         
            +
                  @column = Slither::Column.new(:date, 10, :type => :date)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  dt = @column.parse('2009-08-22')
         
     | 
| 
      
 99 
     | 
    
         
            +
                  dt.should be_a(Date)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  dt.to_s.should == '2009-08-22'
         
     | 
| 
      
 101 
     | 
    
         
            +
                end   
         
     | 
| 
      
 102 
     | 
    
         
            +
                
         
     | 
| 
      
 103 
     | 
    
         
            +
                it "should use the format option with date type if available" do
         
     | 
| 
      
 104 
     | 
    
         
            +
                  @column = Slither::Column.new(:date, 10, :type => :date, :format => "%m%d%Y")
         
     | 
| 
      
 105 
     | 
    
         
            +
                  dt = @column.parse('08222009')
         
     | 
| 
      
 106 
     | 
    
         
            +
                  dt.should be_a(Date)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  dt.to_s.should == '2009-08-22'
         
     | 
| 
      
 108 
     | 
    
         
            +
                end   
         
     | 
| 
      
 109 
     | 
    
         
            +
              end
         
     | 
| 
      
 110 
     | 
    
         
            +
              
         
     | 
| 
      
 111 
     | 
    
         
            +
              describe "when applying formatting options" do
         
     | 
| 
      
 112 
     | 
    
         
            +
                it "should return a proper formatter" do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :align => :left)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @column.send(:formatter).should == "%-5s"
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
                
         
     | 
| 
      
 117 
     | 
    
         
            +
                it "should respect a right alignment" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :align => :right)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  @column.format(25).should == '   25'
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
                
         
     | 
| 
      
 122 
     | 
    
         
            +
                it "should respect a left alignment" do
         
     | 
| 
      
 123 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :align => :left)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  @column.format(25).should == '25   '
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
                
         
     | 
| 
      
 127 
     | 
    
         
            +
                it "should respect padding with spaces" do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :padding => :space)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  @column.format(25).should == '   25'
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
                
         
     | 
| 
      
 132 
     | 
    
         
            +
                it "should respect padding with zeros with integer types" do
         
     | 
| 
      
 133 
     | 
    
         
            +
                  @column = Slither::Column.new(@name, @length, :type => :integer, :padding => :zero)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  @column.format(25).should == '00025'
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
                
         
     | 
| 
      
 137 
     | 
    
         
            +
                describe "that is a float type" do
         
     | 
| 
      
 138 
     | 
    
         
            +
                  it "should respect padding with zeros aligned right" do
         
     | 
| 
      
 139 
     | 
    
         
            +
                    @column = Slither::Column.new(@name, @length, :type => :float, :padding => :zero, :align => :right)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    @column.format(4.45).should == '04.45'
         
     | 
| 
      
 141 
     | 
    
         
            +
                  end
         
     | 
| 
      
 142 
     | 
    
         
            +
                  
         
     | 
| 
      
 143 
     | 
    
         
            +
                  it "should respect padding with zeros aligned left" do
         
     | 
| 
      
 144 
     | 
    
         
            +
                    @column = Slither::Column.new(@name, @length, :type => :float, :padding => :zero, :align => :left)
         
     | 
| 
      
 145 
     | 
    
         
            +
                    @column.format(4.45).should == '4.450'
         
     | 
| 
      
 146 
     | 
    
         
            +
                  end
         
     | 
| 
      
 147 
     | 
    
         
            +
                end    
         
     | 
| 
      
 148 
     | 
    
         
            +
              end
         
     | 
| 
      
 149 
     | 
    
         
            +
                
         
     | 
| 
      
 150 
     | 
    
         
            +
              describe "when formatting values for a file" do
         
     | 
| 
      
 151 
     | 
    
         
            +
                it "should default to a string" do
         
     | 
| 
      
 152 
     | 
    
         
            +
                  @column = Slither::Column.new(:name, 10)
         
     | 
| 
      
 153 
     | 
    
         
            +
                  @column.format('Bill').should == '      Bill'
         
     | 
| 
      
 154 
     | 
    
         
            +
                end
         
     | 
| 
      
 155 
     | 
    
         
            +
                
         
     | 
| 
      
 156 
     | 
    
         
            +
                describe "whose size is too long" do
         
     | 
| 
      
 157 
     | 
    
         
            +
                  it "should raise an error if truncate is false" do
         
     | 
| 
      
 158 
     | 
    
         
            +
                    @value = "XX" * @length
         
     | 
| 
      
 159 
     | 
    
         
            +
                    lambda { @column.format(@value) }.should raise_error(
         
     | 
| 
      
 160 
     | 
    
         
            +
                      Slither::FormattedStringExceedsLengthError,
         
     | 
| 
      
 161 
     | 
    
         
            +
                      "The formatted value '#{@value}' in column '#{@name}' exceeds the allowed length of #{@length} chararacters."
         
     | 
| 
      
 162 
     | 
    
         
            +
                    )
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
                  
         
     | 
| 
      
 165 
     | 
    
         
            +
                  it "should truncate from the left if truncate is true and aligned left" do
         
     | 
| 
      
 166 
     | 
    
         
            +
                    @column = Slither::Column.new(@name, @length, :truncate => true, :align => :left)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    @column.format("This is too long").should == "This "
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
                  
         
     | 
| 
      
 170 
     | 
    
         
            +
                  it "should truncate from the right if truncate is true and aligned right" do
         
     | 
| 
      
 171 
     | 
    
         
            +
                    @column = Slither::Column.new(@name, @length, :truncate => true, :align => :right)
         
     | 
| 
      
 172 
     | 
    
         
            +
                    @column.format("This is too long").should == " long"
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
                end
         
     | 
| 
      
 175 
     | 
    
         
            +
                
         
     | 
| 
      
 176 
     | 
    
         
            +
                it "should support the integer type" do
         
     | 
| 
      
 177 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type => :integer)
         
     | 
| 
      
 178 
     | 
    
         
            +
                  @column.format(234).should        == '       234'
         
     | 
| 
      
 179 
     | 
    
         
            +
                  @column.format('234').should      == '       234'
         
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
              
         
     | 
| 
      
 182 
     | 
    
         
            +
                it "should support the float type" do
         
     | 
| 
      
 183 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type => :float)
         
     | 
| 
      
 184 
     | 
    
         
            +
                  @column.format(234.45).should       == '    234.45'
         
     | 
| 
      
 185 
     | 
    
         
            +
                  @column.format('234.4500').should   == '    234.45'
         
     | 
| 
      
 186 
     | 
    
         
            +
                  @column.format('3').should          == '       3.0'
         
     | 
| 
      
 187 
     | 
    
         
            +
                end
         
     | 
| 
      
 188 
     | 
    
         
            +
                
         
     | 
| 
      
 189 
     | 
    
         
            +
                it "should support the float type with a format" do
         
     | 
| 
      
 190 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.3f")
         
     | 
| 
      
 191 
     | 
    
         
            +
                  @column.format(234.45).should       == '   234.450'
         
     | 
| 
      
 192 
     | 
    
         
            +
                  @column.format('234.4500').should   == '   234.450'
         
     | 
| 
      
 193 
     | 
    
         
            +
                  @column.format('3').should          == '     3.000'
         
     | 
| 
      
 194 
     | 
    
         
            +
                end
         
     | 
| 
      
 195 
     | 
    
         
            +
                
         
     | 
| 
      
 196 
     | 
    
         
            +
                it "should support the float type with a format, alignment and padding" do
         
     | 
| 
      
 197 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.2f", :align => :left, :padding => :zero)
         
     | 
| 
      
 198 
     | 
    
         
            +
                  @column.format(234.45).should       == '234.450000'
         
     | 
| 
      
 199 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.2f", :align => :right, :padding => :zero)
         
     | 
| 
      
 200 
     | 
    
         
            +
                  @column.format('234.400').should    == '0000234.40'
         
     | 
| 
      
 201 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.4f", :align => :left, :padding => :space)
         
     | 
| 
      
 202 
     | 
    
         
            +
                  @column.format('3').should          == '3.0000    '
         
     | 
| 
      
 203 
     | 
    
         
            +
                end
         
     | 
| 
      
 204 
     | 
    
         
            +
                
         
     | 
| 
      
 205 
     | 
    
         
            +
                it "should support the money_with_implied_decimal type" do
         
     | 
| 
      
 206 
     | 
    
         
            +
                  @column = Slither::Column.new(:amount, 10, :type=> :money_with_implied_decimal)
         
     | 
| 
      
 207 
     | 
    
         
            +
                  @column.format(234.450).should   == "     23445"
         
     | 
| 
      
 208 
     | 
    
         
            +
                  @column.format(12.34).should     == "      1234"
         
     | 
| 
      
 209 
     | 
    
         
            +
                end    
         
     | 
| 
      
 210 
     | 
    
         
            +
              
         
     | 
| 
      
 211 
     | 
    
         
            +
                it "should support the date type" do
         
     | 
| 
      
 212 
     | 
    
         
            +
                  dt = Date.new(2009, 8, 22)
         
     | 
| 
      
 213 
     | 
    
         
            +
                  @column = Slither::Column.new(:date, 10, :type => :date)
         
     | 
| 
      
 214 
     | 
    
         
            +
                  @column.format(dt).should == '2009-08-22'
         
     | 
| 
      
 215 
     | 
    
         
            +
                end   
         
     | 
| 
      
 216 
     | 
    
         
            +
                
         
     | 
| 
      
 217 
     | 
    
         
            +
                it "should support the date type with a :format" do
         
     | 
| 
      
 218 
     | 
    
         
            +
                  dt = Date.new(2009, 8, 22)
         
     | 
| 
      
 219 
     | 
    
         
            +
                  @column = Slither::Column.new(:date, 8, :type => :date, :format => "%m%d%Y")
         
     | 
| 
      
 220 
     | 
    
         
            +
                  @column.format(dt).should == '08222009'
         
     | 
| 
      
 221 
     | 
    
         
            +
                end 
         
     | 
| 
      
 222 
     | 
    
         
            +
              end
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Slither::Definition do  
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
              end
         
     | 
| 
      
 6 
     | 
    
         
            +
              
         
     | 
| 
      
 7 
     | 
    
         
            +
              describe "when specifying alignment" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                it "should have an alignment option" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                  d = Slither::Definition.new :align => :right
         
     | 
| 
      
 10 
     | 
    
         
            +
                  d.options[:align].should == :right
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
                
         
     | 
| 
      
 13 
     | 
    
         
            +
                it "should default to being right aligned" do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  d = Slither::Definition.new
         
     | 
| 
      
 15 
     | 
    
         
            +
                  d.options[:align].should == :right
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              
         
     | 
| 
      
 18 
     | 
    
         
            +
                it "should override the default if :align is passed to the section" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  section = mock('section', :null_object => true)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  Slither::Section.should_receive(:new).with('name', {:align => :left}).and_return(section)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  d = Slither::Definition.new
         
     | 
| 
      
 22 
     | 
    
         
            +
                  d.options[:align].should == :right
         
     | 
| 
      
 23 
     | 
    
         
            +
                  d.section('name', :align => :left) {}
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
              
         
     | 
| 
      
 27 
     | 
    
         
            +
              describe "when creating a section" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @d = Slither::Definition.new
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @section = mock('section', :null_object => true)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                
         
     | 
| 
      
 33 
     | 
    
         
            +
                it "should create and yield a new section object" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  yielded = nil
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @d.section :header do |section|
         
     | 
| 
      
 36 
     | 
    
         
            +
                    yielded = section
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
                  yielded.should be_a(Slither::Section)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @d.sections.first.should == yielded
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
                      
         
     | 
| 
      
 42 
     | 
    
         
            +
                it "should magically build a section from an unknown method" do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  Slither::Section.should_receive(:new).with(:header, anything()).and_return(@section)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @d.header {}
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
                
         
     | 
| 
      
 47 
     | 
    
         
            +
                it "should not create duplicate section names" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  lambda { @d.section(:header) {} }.should_not raise_error(ArgumentError)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  lambda { @d.section(:header) {} }.should raise_error(ArgumentError, "Reserved or duplicate section name: 'header'")
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                
         
     | 
| 
      
 52 
     | 
    
         
            +
                it "should throw an error if a reserved section name is used" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                  lambda { @d.section(:spacer) {} }.should raise_error(ArgumentError, "Reserved or duplicate section name: 'spacer'")
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
              
         
     | 
| 
      
 57 
     | 
    
         
            +
              describe "when creating a template" do
         
     | 
| 
      
 58 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @d = Slither::Definition.new
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @section = mock('section', :null_object => true)
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
                
         
     | 
| 
      
 63 
     | 
    
         
            +
                it "should create a new section" do
         
     | 
| 
      
 64 
     | 
    
         
            +
                  Slither::Section.should_receive(:new).with(:row, anything()).and_return(@section)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @d.template(:row) {}
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
                
         
     | 
| 
      
 68 
     | 
    
         
            +
                it "should yield the new section" do
         
     | 
| 
      
 69 
     | 
    
         
            +
                  Slither::Section.should_receive(:new).with(:row, anything()).and_return(@section)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  yielded = nil
         
     | 
| 
      
 71 
     | 
    
         
            +
                  @d.template :row do |section|
         
     | 
| 
      
 72 
     | 
    
         
            +
                    yielded = section
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                  yielded.should == @section
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
                
         
     | 
| 
      
 77 
     | 
    
         
            +
                it "add a section to the templates collection" do
         
     | 
| 
      
 78 
     | 
    
         
            +
                  @d.should have(0).templates
         
     | 
| 
      
 79 
     | 
    
         
            +
                  @d.template :row do |t|
         
     | 
| 
      
 80 
     | 
    
         
            +
                    t.column :id, 3
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                  @d.should have(1).templates
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
                
         
     | 
| 
      
 3 
     | 
    
         
            +
            describe Slither::Generator do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @definition = Slither.define :test do |d|
         
     | 
| 
      
 6 
     | 
    
         
            +
                  d.header do |h|
         
     | 
| 
      
 7 
     | 
    
         
            +
                    h.trap { |line| line[0,4] == 'HEAD' }
         
     | 
| 
      
 8 
     | 
    
         
            +
                    h.column :type, 4
         
     | 
| 
      
 9 
     | 
    
         
            +
                    h.column :file_id, 10
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                  d.body do |b|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    b.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
         
     | 
| 
      
 13 
     | 
    
         
            +
                    b.column :first, 10
         
     | 
| 
      
 14 
     | 
    
         
            +
                    b.column :last, 10
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  d.footer do |f|
         
     | 
| 
      
 17 
     | 
    
         
            +
                    f.trap { |line| line[0,4] == 'FOOT' }
         
     | 
| 
      
 18 
     | 
    
         
            +
                    f.column :type, 4
         
     | 
| 
      
 19 
     | 
    
         
            +
                    f.column :file_id, 10
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end     
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                @data = {
         
     | 
| 
      
 23 
     | 
    
         
            +
                  :header => [ {:type => "HEAD", :file_id => "1" }],
         
     | 
| 
      
 24 
     | 
    
         
            +
                  :body => [ 
         
     | 
| 
      
 25 
     | 
    
         
            +
                    {:first => "Paul", :last => "Hewson" },
         
     | 
| 
      
 26 
     | 
    
         
            +
                    {:first => "Dave", :last => "Evans" }
         
     | 
| 
      
 27 
     | 
    
         
            +
                  ],
         
     | 
| 
      
 28 
     | 
    
         
            +
                  :footer => [ {:type => "FOOT", :file_id => "1" }]
         
     | 
| 
      
 29 
     | 
    
         
            +
                }   
         
     | 
| 
      
 30 
     | 
    
         
            +
                @generator = Slither::Generator.new(@definition)
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
              
         
     | 
| 
      
 33 
     | 
    
         
            +
              it "should raise an error if there is no data for a required section" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                @data.delete :header
         
     | 
| 
      
 35 
     | 
    
         
            +
                lambda {  @generator.generate(@data) }.should raise_error(Slither::RequiredSectionEmptyError, "Required section 'header' was empty.")
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
              
         
     | 
| 
      
 38 
     | 
    
         
            +
              it "should generate a string" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                expected = "HEAD         1\n      Paul    Hewson\n      Dave     Evans\nFOOT         1"
         
     | 
| 
      
 40 
     | 
    
         
            +
                @generator.generate(@data).should == expected
         
     | 
| 
      
 41 
     | 
    
         
            +
              end 
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/parser_spec.rb
    ADDED
    
    | 
         @@ -0,0 +1,74 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
                
         
     | 
| 
      
 3 
     | 
    
         
            +
            describe Slither::Parser do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @definition = mock('definition', :sections => [])
         
     | 
| 
      
 6 
     | 
    
         
            +
                @file = mock("file", :gets => nil)
         
     | 
| 
      
 7 
     | 
    
         
            +
                @file_name = 'test.txt'
         
     | 
| 
      
 8 
     | 
    
         
            +
                @parser = Slither::Parser.new(@definition, @file_name)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
              
         
     | 
| 
      
 11 
     | 
    
         
            +
              it "should open and yield the source file" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                File.should_receive(:open).with(@file_name, 'r').and_yield(@file)
         
     | 
| 
      
 13 
     | 
    
         
            +
                @parser.parse
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              
         
     | 
| 
      
 16 
     | 
    
         
            +
              describe "when parsing sections" do
         
     | 
| 
      
 17 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @definition = Slither.define :test do |d|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    d.header do |h|
         
     | 
| 
      
 20 
     | 
    
         
            +
                      h.trap { |line| line[0,4] == 'HEAD' }
         
     | 
| 
      
 21 
     | 
    
         
            +
                      h.column :type, 4
         
     | 
| 
      
 22 
     | 
    
         
            +
                      h.column :file_id, 10
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                    d.body do |b|
         
     | 
| 
      
 25 
     | 
    
         
            +
                      b.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
         
     | 
| 
      
 26 
     | 
    
         
            +
                      b.column :first, 10
         
     | 
| 
      
 27 
     | 
    
         
            +
                      b.column :last, 10
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                    d.footer do |f|
         
     | 
| 
      
 30 
     | 
    
         
            +
                      f.trap { |line| line[0,4] == 'FOOT' }
         
     | 
| 
      
 31 
     | 
    
         
            +
                      f.column :type, 4
         
     | 
| 
      
 32 
     | 
    
         
            +
                      f.column :file_id, 10
         
     | 
| 
      
 33 
     | 
    
         
            +
                    end     
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  File.should_receive(:open).with(@file_name, 'r').and_yield(@file)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @parser = Slither::Parser.new(@definition, @file_name)
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                it "should add lines to the proper sections" do
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @file.should_receive(:gets).exactly(4).times.and_return(
         
     | 
| 
      
 41 
     | 
    
         
            +
                    'HEAD         1',
         
     | 
| 
      
 42 
     | 
    
         
            +
                    '      Paul    Hewson',
         
     | 
| 
      
 43 
     | 
    
         
            +
                    '      Dave     Evans',
         
     | 
| 
      
 44 
     | 
    
         
            +
                    'FOOT         1',
         
     | 
| 
      
 45 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 46 
     | 
    
         
            +
                  )
         
     | 
| 
      
 47 
     | 
    
         
            +
                  expected = {
         
     | 
| 
      
 48 
     | 
    
         
            +
                    :header => [ {:type => "HEAD", :file_id => "1" }],
         
     | 
| 
      
 49 
     | 
    
         
            +
                    :body => [ 
         
     | 
| 
      
 50 
     | 
    
         
            +
                      {:first => "Paul", :last => "Hewson" },
         
     | 
| 
      
 51 
     | 
    
         
            +
                      {:first => "Dave", :last => "Evans" }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    ],
         
     | 
| 
      
 53 
     | 
    
         
            +
                    :footer => [ {:type => "FOOT", :file_id => "1" }]
         
     | 
| 
      
 54 
     | 
    
         
            +
                  }      
         
     | 
| 
      
 55 
     | 
    
         
            +
                  result = @parser.parse
         
     | 
| 
      
 56 
     | 
    
         
            +
                  result.should == expected
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                it "should allow optional sections to be skipped" do
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @definition.sections[0].optional = true
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @definition.sections[2].optional = true
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @file.should_receive(:gets).twice.and_return('      Paul    Hewson', nil)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  expected = { :body => [ {:first => "Paul", :last => "Hewson" } ] }
         
     | 
| 
      
 64 
     | 
    
         
            +
                  @parser.parse.should == expected      
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
                  
         
     | 
| 
      
 67 
     | 
    
         
            +
                it "should raise an error if a required section is not found" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @file.should_receive(:gets).twice.and_return('      Ryan      Wood', nil)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  lambda { @parser.parse }.should raise_error(Slither::RequiredSectionNotFoundError, "Required section 'header' was not found.")
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
                
         
     | 
| 
      
 72 
     | 
    
         
            +
                # it "raise an error if a section limit is over run"
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,146 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
                
         
     | 
| 
      
 3 
     | 
    
         
            +
            describe Slither::Section do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @section = Slither::Section.new(:body)
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
              
         
     | 
| 
      
 8 
     | 
    
         
            +
              it "should have no columns after creation" do
         
     | 
| 
      
 9 
     | 
    
         
            +
                @section.columns.should be_empty
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
              
         
     | 
| 
      
 12 
     | 
    
         
            +
              it "should know it's reserved names" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                Slither::Section::RESERVED_NAMES.should == [:spacer]
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
              
         
     | 
| 
      
 16 
     | 
    
         
            +
              describe "when adding columns" do    
         
     | 
| 
      
 17 
     | 
    
         
            +
                it "should build an ordered column list" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @section.should have(0).columns
         
     | 
| 
      
 19 
     | 
    
         
            +
                
         
     | 
| 
      
 20 
     | 
    
         
            +
                  col1 = @section.column :id, 10
         
     | 
| 
      
 21 
     | 
    
         
            +
                  col2 = @section.column :name, 30
         
     | 
| 
      
 22 
     | 
    
         
            +
                  col3 = @section.column :state, 2
         
     | 
| 
      
 23 
     | 
    
         
            +
                
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @section.should have(3).columns
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @section.columns[0].should be(col1)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @section.columns[1].should be(col2)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @section.columns[2].should be(col3)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
      
 30 
     | 
    
         
            +
                it "should create spacer columns" do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @section.should have(0).columns
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @section.spacer(5)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @section.should have(1).columns
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              
         
     | 
| 
      
 36 
     | 
    
         
            +
                it "can should override the alignment of the definition" do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  section = Slither::Section.new('name', :align => :left)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  section.options[:align].should == :left
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                
         
     | 
| 
      
 41 
     | 
    
         
            +
                it "should use a missing method to create a column" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @section.should have(0).columns
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @section.first_name 5
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @section.should have(1).columns
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
                
         
     | 
| 
      
 47 
     | 
    
         
            +
                it "should prevent duplicate column names" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @section.column :id, 10
         
     | 
| 
      
 49 
     | 
    
         
            +
                  lambda { @section.column(:id, 30) }.should raise_error(Slither::DuplicateColumnNameError, "You have already defined a column named 'id'.")
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
                
         
     | 
| 
      
 52 
     | 
    
         
            +
                it "should allow duplicate column names that are reserved (i.e. spacer)" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @section.spacer 10
         
     | 
| 
      
 54 
     | 
    
         
            +
                  lambda { @section.spacer 10 }.should_not raise_error(Slither::DuplicateColumnNameError)
         
     | 
| 
      
 55 
     | 
    
         
            +
                end    
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
              it "should accept and store the trap as a block" do
         
     | 
| 
      
 59 
     | 
    
         
            +
                @section.trap { |v| v == 4 }
         
     | 
| 
      
 60 
     | 
    
         
            +
                trap = @section.instance_variable_get(:@trap)
         
     | 
| 
      
 61 
     | 
    
         
            +
                trap.should be_a(Proc)
         
     | 
| 
      
 62 
     | 
    
         
            +
                trap.call(4).should == true
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
              
         
     | 
| 
      
 65 
     | 
    
         
            +
              describe "when adding a template" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @template = mock('templated section', :columns => [1,2,3], :options => {})
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @definition = mock("definition", :templates => { :test => @template } )
         
     | 
| 
      
 69 
     | 
    
         
            +
                  @section.definition = @definition
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
                
         
     | 
| 
      
 72 
     | 
    
         
            +
                it "should ensure the template exists" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                  @definition.stub! :templates => {}
         
     | 
| 
      
 74 
     | 
    
         
            +
                  lambda { @section.template(:none) }.should raise_error(ArgumentError)
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
                
         
     | 
| 
      
 77 
     | 
    
         
            +
                it "should add the template columns to the current column list" do
         
     | 
| 
      
 78 
     | 
    
         
            +
                  @section.template :test
         
     | 
| 
      
 79 
     | 
    
         
            +
                  @section.should have(3).columns
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
                
         
     | 
| 
      
 82 
     | 
    
         
            +
                it "should merge the template option" do
         
     | 
| 
      
 83 
     | 
    
         
            +
                   @section = Slither::Section.new(:body, :align => :left)
         
     | 
| 
      
 84 
     | 
    
         
            +
                   @section.definition = @definition
         
     | 
| 
      
 85 
     | 
    
         
            +
                   @template.stub! :options => {:align => :right}
         
     | 
| 
      
 86 
     | 
    
         
            +
                   @section.template :test
         
     | 
| 
      
 87 
     | 
    
         
            +
                   @section.options.should == {:align => :left}
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              describe "when formatting a row" do    
         
     | 
| 
      
 92 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 93 
     | 
    
         
            +
                  @data = { :id => 3, :name => "Ryan" }
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
                
         
     | 
| 
      
 96 
     | 
    
         
            +
                it "should default to string data aligned right" do
         
     | 
| 
      
 97 
     | 
    
         
            +
                  @section.column(:id, 5)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  @section.column(:name, 10)      
         
     | 
| 
      
 99 
     | 
    
         
            +
                  @section.format( @data ).should == "    3      Ryan"      
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
                
         
     | 
| 
      
 102 
     | 
    
         
            +
                it "should left align if asked" do
         
     | 
| 
      
 103 
     | 
    
         
            +
                  @section.column(:id, 5)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  @section.column(:name, 10, :align => :left)  
         
     | 
| 
      
 105 
     | 
    
         
            +
                  @section.format(@data).should == "    3Ryan      "      
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
                
         
     | 
| 
      
 108 
     | 
    
         
            +
                # it "should raise an error if the data and column definitions aren't the same size" do
         
     | 
| 
      
 109 
     | 
    
         
            +
                #   @section.column(:id, 5)
         
     | 
| 
      
 110 
     | 
    
         
            +
                #   lambda { @section.format(@data) }.should raise_error(
         
     | 
| 
      
 111 
     | 
    
         
            +
                #     Slither::ColumnMismatchError,
         
     | 
| 
      
 112 
     | 
    
         
            +
                #     "The 'body' section has 1 column(s) defined, but there are 2 column(s) provided in the data."
         
     | 
| 
      
 113 
     | 
    
         
            +
                #   )
         
     | 
| 
      
 114 
     | 
    
         
            +
                # end
         
     | 
| 
      
 115 
     | 
    
         
            +
              end
         
     | 
| 
      
 116 
     | 
    
         
            +
              
         
     | 
| 
      
 117 
     | 
    
         
            +
              describe "when parsing a file" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 119 
     | 
    
         
            +
                  @line = '   45      Ryan      WoodSC '
         
     | 
| 
      
 120 
     | 
    
         
            +
                  @section = Slither::Section.new(:body)
         
     | 
| 
      
 121 
     | 
    
         
            +
                  @column_content = { :id => 5, :first => 10, :last => 10, :state => 2 }      
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
                
         
     | 
| 
      
 124 
     | 
    
         
            +
                it "should return a key for key column" do
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @column_content.each { |k,v| @section.column(k, v) }
         
     | 
| 
      
 126 
     | 
    
         
            +
                  parsed = @section.parse(@line)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  @column_content.each_key { |name| parsed.should have_key(name) }
         
     | 
| 
      
 128 
     | 
    
         
            +
                end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                it "should not return a key for reserved names" do
         
     | 
| 
      
 131 
     | 
    
         
            +
                  @column_content.each { |k,v| @section.column(k, v) }
         
     | 
| 
      
 132 
     | 
    
         
            +
                  @section.spacer 5
         
     | 
| 
      
 133 
     | 
    
         
            +
                  @section.should have(5).columns
         
     | 
| 
      
 134 
     | 
    
         
            +
                  parsed = @section.parse(@line)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  parsed.should have(4).keys
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
              
         
     | 
| 
      
 139 
     | 
    
         
            +
              it "should try to match a line using the trap" do
         
     | 
| 
      
 140 
     | 
    
         
            +
                @section.trap do |line|
         
     | 
| 
      
 141 
     | 
    
         
            +
                  line == 'hello'
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
                @section.match('hello').should be_true
         
     | 
| 
      
 144 
     | 
    
         
            +
                @section.match('goodbye').should be_false
         
     | 
| 
      
 145 
     | 
    
         
            +
              end
         
     | 
| 
      
 146 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,84 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.join(File.dirname(__FILE__), 'spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Slither do
         
     | 
| 
      
 4 
     | 
    
         
            +
              
         
     | 
| 
      
 5 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 6 
     | 
    
         
            +
                @name = :doc
         
     | 
| 
      
 7 
     | 
    
         
            +
                @options = { :align => :left }
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
              
         
     | 
| 
      
 10 
     | 
    
         
            +
              describe "when defining a format" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @definition = mock('definition')
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              
         
     | 
| 
      
 15 
     | 
    
         
            +
                it "should create a new definition using the specified name and options" do
         
     | 
| 
      
 16 
     | 
    
         
            +
                  Slither.should_receive(:define).with(@name, @options).and_return(@definition)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Slither.define(@name , @options)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
                
         
     | 
| 
      
 20 
     | 
    
         
            +
                it "should pass the definition to the block" do
         
     | 
| 
      
 21 
     | 
    
         
            +
                  yielded = nil
         
     | 
| 
      
 22 
     | 
    
         
            +
                  Slither.define(@name) do |y|
         
     | 
| 
      
 23 
     | 
    
         
            +
                    yielded = y
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  yielded.should be_a( Slither::Definition )
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
                
         
     | 
| 
      
 28 
     | 
    
         
            +
                it "should add to the internal definition count" do
         
     | 
| 
      
 29 
     | 
    
         
            +
                  Slither.definitions.clear
         
     | 
| 
      
 30 
     | 
    
         
            +
                  Slither.should have(0).definitions
         
     | 
| 
      
 31 
     | 
    
         
            +
                  Slither.define(@name , @options) {}
         
     | 
| 
      
 32 
     | 
    
         
            +
                  Slither.should have(1).definitions
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
              
         
     | 
| 
      
 36 
     | 
    
         
            +
              describe "when creating file from data" do 
         
     | 
| 
      
 37 
     | 
    
         
            +
                it "should raise an error if the definition name is not found" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  lambda { Slither.generate(:not_there, {}) }.should raise_error(ArgumentError)      
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
                
         
     | 
| 
      
 41 
     | 
    
         
            +
                it "should output a string" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                  definition = mock('definition')
         
     | 
| 
      
 43 
     | 
    
         
            +
                  generator = mock('generator')
         
     | 
| 
      
 44 
     | 
    
         
            +
                  generator.should_receive(:generate).with({})
         
     | 
| 
      
 45 
     | 
    
         
            +
                  Slither.should_receive(:definition).with(:test).and_return(definition)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  Slither::Generator.should_receive(:new).with(definition).and_return(generator)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  Slither.generate(:test, {})
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
                
         
     | 
| 
      
 50 
     | 
    
         
            +
                it "should output a file" do
         
     | 
| 
      
 51 
     | 
    
         
            +
              	  file = mock('file')
         
     | 
| 
      
 52 
     | 
    
         
            +
              	  text = mock('string')
         
     | 
| 
      
 53 
     | 
    
         
            +
              	  file.should_receive(:write).with(text)
         
     | 
| 
      
 54 
     | 
    
         
            +
              	  File.should_receive(:open).with('file.txt', 'w').and_yield(file)
         
     | 
| 
      
 55 
     | 
    
         
            +
              	  Slither.should_receive(:generate).with(:test, {}).and_return(text)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  Slither.write('file.txt', :test, {})
         
     | 
| 
      
 57 
     | 
    
         
            +
              	end       
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            	
         
     | 
| 
      
 60 
     | 
    
         
            +
              describe "when parsing a file" do
         
     | 
| 
      
 61 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @file_name = 'file.txt'
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
                
         
     | 
| 
      
 65 
     | 
    
         
            +
                it "should check the file exists" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                  lambda { Slither.parse(@file_name, :test, {}) }.should raise_error(ArgumentError)
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
                
         
     | 
| 
      
 69 
     | 
    
         
            +
                it "should raise an error if the definition name is not found" do
         
     | 
| 
      
 70 
     | 
    
         
            +
                  Slither.definitions.clear
         
     | 
| 
      
 71 
     | 
    
         
            +
                  File.stub!(:exists? => true)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  lambda { Slither.parse(@file_name, :test, {}) }.should raise_error(ArgumentError)      
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
                
         
     | 
| 
      
 75 
     | 
    
         
            +
                it "should create a parser and call parse" do
         
     | 
| 
      
 76 
     | 
    
         
            +
                  File.stub!(:exists? => true)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  parser = mock("parser", :null_object => true)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  definition = mock('definition')     
         
     | 
| 
      
 79 
     | 
    
         
            +
                  Slither.should_receive(:definition).with(:test).and_return(definition)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  Slither::Parser.should_receive(:new).with(definition, @file_name).and_return(parser)      
         
     | 
| 
      
 81 
     | 
    
         
            +
                  Slither.parse(@file_name, :test)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
      
 83 
     | 
    
         
            +
              end
         
     | 
| 
      
 84 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,104 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: slither-ruby19
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 405
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 99
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 3
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.99.3
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Ryan Wood
         
     | 
| 
      
 14 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 15 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 16 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            date: 2009-06-22 00:00:00 -05:00
         
     | 
| 
      
 19 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 20 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 21 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 22 
     | 
    
         
            +
              name: bones
         
     | 
| 
      
 23 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 24 
     | 
    
         
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 25 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 26 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 27 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 28 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 29 
     | 
    
         
            +
                    hash: 25
         
     | 
| 
      
 30 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 31 
     | 
    
         
            +
                    - 2
         
     | 
| 
      
 32 
     | 
    
         
            +
                    - 5
         
     | 
| 
      
 33 
     | 
    
         
            +
                    - 1
         
     | 
| 
      
 34 
     | 
    
         
            +
                    version: 2.5.1
         
     | 
| 
      
 35 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: *id001
         
     | 
| 
      
 37 
     | 
    
         
            +
            description: (Temporary fork of slither gem that works with ruby 1.9) A simple, clean DSL for describing, writing, and parsing fixed-width text files.
         
     | 
| 
      
 38 
     | 
    
         
            +
            email: ryan.wood@gmail.com
         
     | 
| 
      
 39 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 44 
     | 
    
         
            +
            - History.txt
         
     | 
| 
      
 45 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 46 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 47 
     | 
    
         
            +
            - History.txt
         
     | 
| 
      
 48 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 49 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 50 
     | 
    
         
            +
            - TODO
         
     | 
| 
      
 51 
     | 
    
         
            +
            - lib/slither.rb
         
     | 
| 
      
 52 
     | 
    
         
            +
            - lib/slither/column.rb
         
     | 
| 
      
 53 
     | 
    
         
            +
            - lib/slither/definition.rb
         
     | 
| 
      
 54 
     | 
    
         
            +
            - lib/slither/generator.rb
         
     | 
| 
      
 55 
     | 
    
         
            +
            - lib/slither/parser.rb
         
     | 
| 
      
 56 
     | 
    
         
            +
            - lib/slither/section.rb
         
     | 
| 
      
 57 
     | 
    
         
            +
            - lib/slither/slither.rb
         
     | 
| 
      
 58 
     | 
    
         
            +
            - slither.gemspec
         
     | 
| 
      
 59 
     | 
    
         
            +
            - spec/column_spec.rb
         
     | 
| 
      
 60 
     | 
    
         
            +
            - spec/definition_spec.rb
         
     | 
| 
      
 61 
     | 
    
         
            +
            - spec/generator_spec.rb
         
     | 
| 
      
 62 
     | 
    
         
            +
            - spec/parser_spec.rb
         
     | 
| 
      
 63 
     | 
    
         
            +
            - spec/section_spec.rb
         
     | 
| 
      
 64 
     | 
    
         
            +
            - spec/slither_spec.rb
         
     | 
| 
      
 65 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 66 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 67 
     | 
    
         
            +
            homepage: http://github.com/ryanwood/slither
         
     | 
| 
      
 68 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 71 
     | 
    
         
            +
            rdoc_options: 
         
     | 
| 
      
 72 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 73 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 74 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 75 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 76 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 77 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 78 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 79 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 80 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 81 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 82 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 83 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 84 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 85 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 86 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 87 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 88 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 89 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 90 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 91 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 92 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 93 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 94 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            rubyforge_project: !binary |
         
     | 
| 
      
 97 
     | 
    
         
            +
              AA==
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            rubygems_version: 1.3.7
         
     | 
| 
      
 100 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 101 
     | 
    
         
            +
            specification_version: 2
         
     | 
| 
      
 102 
     | 
    
         
            +
            summary: (Temporary fork of slither gem that works with ruby 1.9) A simple, clean DSL for describing, writing, and parsing fixed-width text files
         
     | 
| 
      
 103 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     |