halogen 0.0.1
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.
- checksums.yaml +7 -0
 - data/.gitignore +15 -0
 - data/.travis.yml +5 -0
 - data/Gemfile +4 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +244 -0
 - data/Rakefile +6 -0
 - data/examples/extensions.md +25 -0
 - data/examples/simple.rb +142 -0
 - data/halogen.gemspec +32 -0
 - data/lib/halogen.rb +157 -0
 - data/lib/halogen/collection.rb +44 -0
 - data/lib/halogen/configuration.rb +15 -0
 - data/lib/halogen/definition.rb +73 -0
 - data/lib/halogen/definitions.rb +23 -0
 - data/lib/halogen/embeds.rb +105 -0
 - data/lib/halogen/embeds/definition.rb +19 -0
 - data/lib/halogen/errors.rb +7 -0
 - data/lib/halogen/hash_util.rb +37 -0
 - data/lib/halogen/links.rb +41 -0
 - data/lib/halogen/links/definition.rb +59 -0
 - data/lib/halogen/properties.rb +40 -0
 - data/lib/halogen/properties/definition.rb +8 -0
 - data/lib/halogen/railtie.rb +11 -0
 - data/lib/halogen/resource.rb +58 -0
 - data/lib/halogen/version.rb +5 -0
 - data/spec/halogen/collection_spec.rb +78 -0
 - data/spec/halogen/configuration_spec.rb +11 -0
 - data/spec/halogen/definition_spec.rb +108 -0
 - data/spec/halogen/definitions_spec.rb +24 -0
 - data/spec/halogen/embeds/definition_spec.rb +23 -0
 - data/spec/halogen/embeds_spec.rb +201 -0
 - data/spec/halogen/links/definition_spec.rb +68 -0
 - data/spec/halogen/links_spec.rb +59 -0
 - data/spec/halogen/properties_spec.rb +41 -0
 - data/spec/halogen/resource_spec.rb +77 -0
 - data/spec/halogen_spec.rb +127 -0
 - data/spec/spec_helper.rb +11 -0
 - metadata +179 -0
 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Embeds
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Definition < Halogen::Definition # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # @return [true] if nothing is raised
         
     | 
| 
      
 7 
     | 
    
         
            +
                  #
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # @raise [Halogen::InvalidDefinition] if the definition is invalid
         
     | 
| 
      
 9 
     | 
    
         
            +
                  #
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def validate
         
     | 
| 
      
 11 
     | 
    
         
            +
                    super
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    return true if procedure
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                    fail InvalidDefinition, "Embed #{name} must be defined with a proc"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 2 
     | 
    
         
            +
              module HashUtil # :nodoc:
         
     | 
| 
      
 3 
     | 
    
         
            +
                extend self
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                # Transform hash keys into strings if necessary
         
     | 
| 
      
 6 
     | 
    
         
            +
                #
         
     | 
| 
      
 7 
     | 
    
         
            +
                # @param hash [Hash]
         
     | 
| 
      
 8 
     | 
    
         
            +
                #
         
     | 
| 
      
 9 
     | 
    
         
            +
                # @return [Hash]
         
     | 
| 
      
 10 
     | 
    
         
            +
                #
         
     | 
| 
      
 11 
     | 
    
         
            +
                def stringify_keys!(hash)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  transform_keys!(hash, &:to_s)
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                # Transform hash keys into symbols if necessary
         
     | 
| 
      
 16 
     | 
    
         
            +
                #
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @param hash [Hash]
         
     | 
| 
      
 18 
     | 
    
         
            +
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                # @return [Hash]
         
     | 
| 
      
 20 
     | 
    
         
            +
                #
         
     | 
| 
      
 21 
     | 
    
         
            +
                def symbolize_keys!(hash)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  transform_keys!(hash, &:to_sym)
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                # Transform hash keys according to block
         
     | 
| 
      
 26 
     | 
    
         
            +
                #
         
     | 
| 
      
 27 
     | 
    
         
            +
                # @param hash [Hash]
         
     | 
| 
      
 28 
     | 
    
         
            +
                #
         
     | 
| 
      
 29 
     | 
    
         
            +
                # @return [Hash]
         
     | 
| 
      
 30 
     | 
    
         
            +
                #
         
     | 
| 
      
 31 
     | 
    
         
            +
                def transform_keys!(hash)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  hash.keys.each { |key| hash[yield(key)] = hash.delete(key) }
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  hash
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Links # :nodoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
                def self.included(base) # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  base.extend ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  base.send :include, InstanceMethods
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                module ClassMethods # :nodoc:
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # @return [Halogen::Embeds::Definition]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def link(name, *args, &procedure)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    definitions.add(Definition.new(name, *args, procedure))
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                module InstanceMethods # :nodoc:
         
     | 
| 
      
 20 
     | 
    
         
            +
                  # @return [Hash] the rendered hash with links, if any
         
     | 
| 
      
 21 
     | 
    
         
            +
                  #
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def render
         
     | 
| 
      
 23 
     | 
    
         
            +
                    decorate_render :links, super
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  # @return [Hash] links from definitions
         
     | 
| 
      
 27 
     | 
    
         
            +
                  #
         
     | 
| 
      
 28 
     | 
    
         
            +
                  def links
         
     | 
| 
      
 29 
     | 
    
         
            +
                    render_definitions(Definition.name) do |definition, result|
         
     | 
| 
      
 30 
     | 
    
         
            +
                      attrs = definition.options.fetch(:attrs, {})
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      href = definition.value(self)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                      result[definition.name] = attrs.merge(href: href) if href
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
            end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            require 'halogen/links/definition'
         
     | 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Links
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Definition < Halogen::Definition # :nodoc
         
     | 
| 
      
 6 
     | 
    
         
            +
                  # Links have special keywords that other definitions don't, so override
         
     | 
| 
      
 7 
     | 
    
         
            +
                  # the standard initializer to build options from keywords
         
     | 
| 
      
 8 
     | 
    
         
            +
                  #
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(name, *args, procedure)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super name, self.class.build_options(args), procedure
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  # @return [true] if nothing is raised
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @raise [Halogen::InvalidDefinition] if the definition is invalid
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def validate
         
     | 
| 
      
 18 
     | 
    
         
            +
                    super
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                    return true if procedure || options.key?(:value)
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    fail InvalidDefinition,
         
     | 
| 
      
 23 
     | 
    
         
            +
                         'Link requires either procedure or explicit value'
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 27 
     | 
    
         
            +
                    # Build hash of options from flexible definition arguments
         
     | 
| 
      
 28 
     | 
    
         
            +
                    #
         
     | 
| 
      
 29 
     | 
    
         
            +
                    # @param args [Array] the raw definition arguments
         
     | 
| 
      
 30 
     | 
    
         
            +
                    #
         
     | 
| 
      
 31 
     | 
    
         
            +
                    # @return [Hash] standardized hash of options
         
     | 
| 
      
 32 
     | 
    
         
            +
                    #
         
     | 
| 
      
 33 
     | 
    
         
            +
                    def build_options(args)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      {}.tap do |options|
         
     | 
| 
      
 35 
     | 
    
         
            +
                        options.merge!(args.pop) if args.last.is_a?(Hash)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                        options[:attrs] ||= {}
         
     | 
| 
      
 38 
     | 
    
         
            +
                        options[:attrs].merge!(build_attrs(args))
         
     | 
| 
      
 39 
     | 
    
         
            +
                      end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                    # @param keywords [Array] array of special keywords
         
     | 
| 
      
 43 
     | 
    
         
            +
                    #
         
     | 
| 
      
 44 
     | 
    
         
            +
                    # @raise [Halogen::InvalidDefinition] if a keyword is unrecognized
         
     | 
| 
      
 45 
     | 
    
         
            +
                    #
         
     | 
| 
      
 46 
     | 
    
         
            +
                    def build_attrs(keywords)
         
     | 
| 
      
 47 
     | 
    
         
            +
                      keywords.each_with_object({}) do |keyword, attrs|
         
     | 
| 
      
 48 
     | 
    
         
            +
                        case keyword
         
     | 
| 
      
 49 
     | 
    
         
            +
                        when :templated, 'templated'
         
     | 
| 
      
 50 
     | 
    
         
            +
                          attrs[:templated] = true
         
     | 
| 
      
 51 
     | 
    
         
            +
                        else
         
     | 
| 
      
 52 
     | 
    
         
            +
                          fail InvalidDefinition, "Unrecognized link keyword: #{keyword}"
         
     | 
| 
      
 53 
     | 
    
         
            +
                        end
         
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Properties # :nodoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
                def self.included(base) # :nodoc:
         
     | 
| 
      
 6 
     | 
    
         
            +
                  base.extend ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  base.send :include, InstanceMethods
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                module ClassMethods # :nodoc:
         
     | 
| 
      
 12 
     | 
    
         
            +
                  # @param name [Symbol, String]
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # @param options [nil, Hash]
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @return [Halogen::Embeds::Definition]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def property(name, options = {}, &procedure)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    definitions.add(Definition.new(name, options, procedure))
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                module InstanceMethods # :nodoc:
         
     | 
| 
      
 23 
     | 
    
         
            +
                  # @return [Hash] the rendered hash with properties, if any
         
     | 
| 
      
 24 
     | 
    
         
            +
                  #
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def render
         
     | 
| 
      
 26 
     | 
    
         
            +
                    super.merge(properties)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  # @return [Hash] properties from definitions
         
     | 
| 
      
 30 
     | 
    
         
            +
                  #
         
     | 
| 
      
 31 
     | 
    
         
            +
                  def properties
         
     | 
| 
      
 32 
     | 
    
         
            +
                    render_definitions(Definition.name) do |definition, result|
         
     | 
| 
      
 33 
     | 
    
         
            +
                      result[definition.name] = definition.value(self)
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            require 'halogen/properties/definition'
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Provide Rails-specific extensions if loaded in a Rails application
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Railtie < ::Rails::Railtie
         
     | 
| 
      
 7 
     | 
    
         
            +
                initializer 'halogen' do |_app|
         
     | 
| 
      
 8 
     | 
    
         
            +
                  Halogen.config.extensions << ::Rails.application.routes.url_helpers
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,58 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            module Halogen
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Behavior for representers with a single primary resource
         
     | 
| 
      
 5 
     | 
    
         
            +
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              module Resource
         
     | 
| 
      
 7 
     | 
    
         
            +
                def self.included(base) # :nodoc:
         
     | 
| 
      
 8 
     | 
    
         
            +
                  if base.included_modules.include?(Collection)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    fail InvalidResource, "#{base.name} has already defined a collection"
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  base.extend ClassMethods
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  base.send :include, InstanceMethods
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  base.send :attr_reader, :resource
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  base.class.send :attr_accessor, :resource_name
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                module ClassMethods # :nodoc:
         
     | 
| 
      
 22 
     | 
    
         
            +
                  # @param name [Symbol, String] name of the resource
         
     | 
| 
      
 23 
     | 
    
         
            +
                  #
         
     | 
| 
      
 24 
     | 
    
         
            +
                  # @return [Module] self
         
     | 
| 
      
 25 
     | 
    
         
            +
                  #
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def define_resource(name)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    self.resource_name = name.to_s
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                    alias_method name, :resource
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # Override standard property definition for resource-based representers
         
     | 
| 
      
 33 
     | 
    
         
            +
                  #
         
     | 
| 
      
 34 
     | 
    
         
            +
                  # @param name [Symbol, String] name of the property
         
     | 
| 
      
 35 
     | 
    
         
            +
                  # @param options [nil, Hash] property options for definition
         
     | 
| 
      
 36 
     | 
    
         
            +
                  #
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def property(name, options = {}, &procedure)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    super.tap do |definition|
         
     | 
| 
      
 39 
     | 
    
         
            +
                      unless definition.procedure || definition.options.key?(:value)
         
     | 
| 
      
 40 
     | 
    
         
            +
                        definition.procedure = proc { resource.send(name) }
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                module InstanceMethods # :nodoc:
         
     | 
| 
      
 47 
     | 
    
         
            +
                  # Override standard initializer to assign primary resource
         
     | 
| 
      
 48 
     | 
    
         
            +
                  #
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # @param resource [Object] the primary resource
         
     | 
| 
      
 50 
     | 
    
         
            +
                  #
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def initialize(resource, *args)
         
     | 
| 
      
 52 
     | 
    
         
            +
                    @resource = resource
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    super *args
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Halogen::Collection do
         
     | 
| 
      
 6 
     | 
    
         
            +
              let :klass do
         
     | 
| 
      
 7 
     | 
    
         
            +
                Class.new do
         
     | 
| 
      
 8 
     | 
    
         
            +
                  include Halogen
         
     | 
| 
      
 9 
     | 
    
         
            +
                  include Halogen::Collection
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              describe '.included' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                it 'raises error if base is already a resource' do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  resource_class = Class.new do
         
     | 
| 
      
 16 
     | 
    
         
            +
                    include Halogen
         
     | 
| 
      
 17 
     | 
    
         
            +
                    include Halogen::Resource
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  expect {
         
     | 
| 
      
 21 
     | 
    
         
            +
                    resource_class.send :include, Halogen::Collection
         
     | 
| 
      
 22 
     | 
    
         
            +
                  }.to raise_error do |exception|
         
     | 
| 
      
 23 
     | 
    
         
            +
                    expect(exception).to be_an_instance_of(Halogen::InvalidCollection)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    expect(exception.message).to match(/has already defined a resource/i)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              describe Halogen::Collection::ClassMethods do
         
     | 
| 
      
 30 
     | 
    
         
            +
                describe '#define_collection' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  it 'handles string argument' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    klass.define_collection 'goats'
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    expect(klass.collection_name).to eq('goats')
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  it 'handles symbol argument' do
         
     | 
| 
      
 38 
     | 
    
         
            +
                    klass.define_collection :goats
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    expect(klass.collection_name).to eq('goats')
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              describe Halogen::Collection::InstanceMethods do
         
     | 
| 
      
 46 
     | 
    
         
            +
                describe '#embed?' do
         
     | 
| 
      
 47 
     | 
    
         
            +
                  it 'returns true if super is true' do
         
     | 
| 
      
 48 
     | 
    
         
            +
                    klass.collection_name = 'bar'
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    klass.embed(:foo) { klass.new }
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                    repr = klass.new(embed: { foo: 1 })
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    expect(repr.embed?('foo')).to eq(true)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  it 'returns true if key matches collection name' do
         
     | 
| 
      
 58 
     | 
    
         
            +
                    klass.collection_name = 'foo'
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    klass.embed(:foo) { klass.new }
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    repr = klass.new(embed: { foo: 0 })
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                    expect(repr.embed?('foo')).to eq(true)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  it 'returns false if no conditions match' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                    klass.collection_name = 'bar'
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    klass.embed(:foo) { klass.new }
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                    repr = klass.new(embed: { foo: 0 })
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                    expect(repr.embed?('foo')).to eq(false)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,108 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            #
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            describe Halogen::Definition do
         
     | 
| 
      
 6 
     | 
    
         
            +
              describe '#initialize' do
         
     | 
| 
      
 7 
     | 
    
         
            +
                it 'symbolizes option keys' do
         
     | 
| 
      
 8 
     | 
    
         
            +
                  definition = Halogen::Definition.new(
         
     | 
| 
      
 9 
     | 
    
         
            +
                    :name, { 'value' => 'some value', 'foo' => 'bar' }, nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  expect(definition.options.keys).to eq([:value, :foo])
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              describe '#value' do
         
     | 
| 
      
 16 
     | 
    
         
            +
                it 'returns value from options if present' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                  definition = Halogen::Definition.new(:name, { value: 'some value' }, nil)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  expect(definition.value(nil)).to eq('some value')
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                it 'evaluates procedure if value from options is missing' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                  definition = Halogen::Definition.new(:name, {}, proc { size })
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  expect(definition.value('foo')).to eq(3)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              describe '#enabled?' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                it 'is true if definition is not guarded' do
         
     | 
| 
      
 31 
     | 
    
         
            +
                  definition = Halogen::Definition.new(:name, {}, nil)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  expect(definition.enabled?(nil)).to eq(true)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                describe 'when guard is a proc' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  let :definition do
         
     | 
| 
      
 38 
     | 
    
         
            +
                    Halogen::Definition.new(:name, { if: proc { empty? } }, nil)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  it 'is true if condition passes' do
         
     | 
| 
      
 42 
     | 
    
         
            +
                    expect(definition.enabled?('')).to eq(true)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  it 'is false if condition fails' do
         
     | 
| 
      
 46 
     | 
    
         
            +
                    expect(definition.enabled?('foo')).to eq(false)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                describe 'when guard is a method name' do
         
     | 
| 
      
 51 
     | 
    
         
            +
                  let :definition do
         
     | 
| 
      
 52 
     | 
    
         
            +
                    Halogen::Definition.new(:name, { if: :empty? }, nil)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                  it 'is true if condition passes' do
         
     | 
| 
      
 56 
     | 
    
         
            +
                    expect(definition.enabled?('')).to eq(true)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  it 'is false if condition fails' do
         
     | 
| 
      
 60 
     | 
    
         
            +
                    expect(definition.enabled?('foo')).to eq(false)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                describe 'when guard is truthy' do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  it 'is true if condition passes' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                    definition = Halogen::Definition.new(:name, { if: true }, nil)
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                    expect(definition.enabled?(nil)).to eq(true)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  it 'is false if condition fails' do
         
     | 
| 
      
 72 
     | 
    
         
            +
                    definition = Halogen::Definition.new(:name, { if: false }, nil)
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                    expect(definition.enabled?(nil)).to eq(false)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                describe 'when guard is negated' do
         
     | 
| 
      
 79 
     | 
    
         
            +
                  let :definition do
         
     | 
| 
      
 80 
     | 
    
         
            +
                    Halogen::Definition.new(:name, { unless: proc { empty? } }, nil)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  it 'is false if condition passes' do
         
     | 
| 
      
 84 
     | 
    
         
            +
                    expect(definition.enabled?('')).to eq(false)
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
              describe '#validate' do
         
     | 
| 
      
 90 
     | 
    
         
            +
                it 'returns true for valid definition' do
         
     | 
| 
      
 91 
     | 
    
         
            +
                  definition = Halogen::Definition.new(:name, { value: 'value' }, nil)
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                  expect(definition.validate).to eq(true)
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                it 'raises error for invalid definition' do
         
     | 
| 
      
 97 
     | 
    
         
            +
                  definition = Halogen::Definition.new(
         
     | 
| 
      
 98 
     | 
    
         
            +
                    :name, { value: 'value' }, proc { 'value' })
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  expect {
         
     | 
| 
      
 101 
     | 
    
         
            +
                    definition.validate
         
     | 
| 
      
 102 
     | 
    
         
            +
                  }.to raise_error(Halogen::InvalidDefinition) do |exception|
         
     | 
| 
      
 103 
     | 
    
         
            +
                    expect(exception.message).to(
         
     | 
| 
      
 104 
     | 
    
         
            +
                      eq('Cannot specify both value and procedure for name'))
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end
         
     |