amee-data-abstraction 2.1.1 → 2.2.0
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/CHANGELOG.txt +3 -0
 - data/README.txt +26 -14
 - data/VERSION +1 -1
 - data/amee-data-abstraction.gemspec +7 -6
 - data/lib/amee-data-abstraction/calculation.rb +1 -1
 - data/lib/amee-data-abstraction/calculation_set.rb +152 -10
 - data/lib/amee-data-abstraction/input.rb +10 -0
 - data/lib/amee-data-abstraction/ongoing_calculation.rb +1 -1
 - data/lib/amee-data-abstraction/term.rb +31 -13
 - data/spec/amee-data-abstraction/calculation_set_spec.rb +247 -9
 - data/spec/amee-data-abstraction/calculation_spec.rb +24 -19
 - data/spec/amee-data-abstraction/drill_spec.rb +14 -9
 - data/spec/amee-data-abstraction/input_spec.rb +113 -73
 - data/spec/amee-data-abstraction/metadatum_spec.rb +1 -1
 - data/spec/amee-data-abstraction/ongoing_calculation_spec.rb +38 -30
 - data/spec/amee-data-abstraction/profile_spec.rb +4 -2
 - data/spec/amee-data-abstraction/prototype_calculation_spec.rb +13 -8
 - data/spec/amee-data-abstraction/term_spec.rb +45 -4
 - data/spec/amee-data-abstraction/terms_list_spec.rb +23 -12
 - data/spec/config/amee_units_spec.rb +1 -2
 - data/spec/core-extensions/class_spec.rb +18 -18
 - data/spec/core-extensions/hash_spec.rb +1 -2
 - data/spec/core-extensions/ordered_hash_spec.rb +1 -2
 - data/spec/core-extensions/proc_spec.rb +1 -1
 - data/spec/fixtures/config/calculations/electricity.rb +35 -0
 - data/spec/fixtures/config/calculations/electricity_and_transport.rb +53 -0
 - data/spec/fixtures/{transport.rb → config/calculations/transport.rb} +2 -2
 - data/spec/fixtures/{electricity.rb → config/electricity.rb} +1 -1
 - data/spec/spec_helper.rb +30 -2
 - metadata +28 -27
 - data/spec/fixtures/electricity_and_transport.rb +0 -55
 
    
        data/CHANGELOG.txt
    CHANGED
    
    
    
        data/README.txt
    CHANGED
    
    | 
         @@ -25,9 +25,9 @@ Documentation: http://rubydoc.info/gems/amee-data-abstraction 
     | 
|
| 
       25 
25 
     | 
    
         
             
             All gem requirements should be installed as part of the rubygems installation process 
         
     | 
| 
       26 
26 
     | 
    
         
             
             above, but are listed here for completeness.
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             * amee ~>  
     | 
| 
      
 28 
     | 
    
         
            +
             * amee ~> 4.1
         
     | 
| 
       29 
29 
     | 
    
         
             
             * uuidtools = 2.1.2
         
     | 
| 
       30 
     | 
    
         
            -
             * quantify =  
     | 
| 
      
 30 
     | 
    
         
            +
             * quantify = 2.0.0
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            == USAGE
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
         @@ -117,16 +117,10 @@ Submit to AMEE for calculation 
     | 
|
| 
       117 
117 
     | 
    
         | 
| 
       118 
118 
     | 
    
         
             
            Typical practice is initialize the calculation prototypes required for an
         
     | 
| 
       119 
119 
     | 
    
         
             
            application via a configuration file which creates the required calculation
         
     | 
| 
       120 
     | 
    
         
            -
            templates within an instance of CalculationSet.  
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
            initializing new calculations and templating view structures (e.g. tables, forms)
         
     | 
| 
       123 
     | 
    
         
            -
            from anywhere in the application.
         
     | 
| 
      
 120 
     | 
    
         
            +
            templates within an instance of CalculationSet. Such a configuration file can
         
     | 
| 
      
 121 
     | 
    
         
            +
            be structured the follow DSL:
         
     | 
| 
       124 
122 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
              # e.g. /config/initializers/calculations.rb
         
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
               Calculations = AMEE::DataAbstraction::CalculationSet {
         
     | 
| 
      
 123 
     | 
    
         
            +
              # e.g. /config/calculations/my_emissions_calculations.rb
         
     | 
| 
       130 
124 
     | 
    
         | 
| 
       131 
125 
     | 
    
         
             
                calculation {
         
     | 
| 
       132 
126 
     | 
    
         
             
                  label :electricity
         
     | 
| 
         @@ -148,17 +142,35 @@ Adding a configuration to /config or /config/initializers may be appropriate 
     | 
|
| 
       148 
142 
     | 
    
         
             
                  path "/some/fuel/associated/path/in/amee"
         
     | 
| 
       149 
143 
     | 
    
         
             
                  terms_from_amee
         
     | 
| 
       150 
144 
     | 
    
         
             
                }
         
     | 
| 
       151 
     | 
    
         
            -
             
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            The default location for such files within Rails applications is under
         
     | 
| 
      
 147 
     | 
    
         
            +
            /config/calculations. If such an approach is taken, the configuration can be
         
     | 
| 
      
 148 
     | 
    
         
            +
            read and a calculation set generated by using the filename, thus:
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
              CalculationSet.find('my_emissions_calculations')
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                                      #=> <AMEE::DataAbstraction::CalculationSet ... >
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            Otherwise, the path to the configuration file can be provided:
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
              CalculationSet.find('some/directory/my_emissions_calculations')
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                                      #=> <AMEE::DataAbstraction::CalculationSet ... >
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            The calculation set is accessible as follow using the same argument as used
         
     | 
| 
      
 161 
     | 
    
         
            +
            by the Find method (filename if conventional Rails location, path otherwise):
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
              CalculationSet.sets['my_emissions_calculations']
         
     | 
| 
       152 
164 
     | 
    
         | 
| 
       153 
165 
     | 
    
         
             
                                      #=> <AMEE::DataAbstraction::CalculationSet ... >
         
     | 
| 
       154 
166 
     | 
    
         | 
| 
       155 
167 
     | 
    
         
             
            From this global calculation set, initialize a new calculation
         
     | 
| 
       156 
168 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
              my_fuel_calculation =  
     | 
| 
      
 169 
     | 
    
         
            +
              my_fuel_calculation = CalculationSet.sets['my_emissions_calcualtions'][:fuel].begin_calculation
         
     | 
| 
       158 
170 
     | 
    
         | 
| 
       159 
171 
     | 
    
         
             
                                      #=> <AMEE::DataAbstraction::OngoingCalculation ... >
         
     | 
| 
       160 
172 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
              a_different_transport_calculation =  
     | 
| 
      
 173 
     | 
    
         
            +
              a_different_transport_calculation = CalculationSet.sets['my_emissions_calcualtions'][:transport].begin_calculation
         
     | 
| 
       162 
174 
     | 
    
         | 
| 
       163 
175 
     | 
    
         
             
                                      #=> <AMEE::DataAbstraction::OngoingCalculation ... >
         
     | 
| 
       164 
176 
     | 
    
         | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            2. 
     | 
| 
      
 1 
     | 
    
         
            +
            2.2.0
         
     | 
| 
         @@ -5,11 +5,11 @@ 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
            Gem::Specification.new do |s|
         
     | 
| 
       7 
7 
     | 
    
         
             
              s.name = %q{amee-data-abstraction}
         
     | 
| 
       8 
     | 
    
         
            -
              s.version = "2. 
     | 
| 
      
 8 
     | 
    
         
            +
              s.version = "2.2.0"
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
              s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
         
     | 
| 
       11 
11 
     | 
    
         
             
              s.authors = ["James Hetherington", "Andrew Berkeley", "James Smith", "George Palmer"]
         
     | 
| 
       12 
     | 
    
         
            -
              s.date = %q{2011-10- 
     | 
| 
      
 12 
     | 
    
         
            +
              s.date = %q{2011-10-18}
         
     | 
| 
       13 
13 
     | 
    
         
             
              s.description = %q{Part of the AMEEappkit this gem provides a data abstraction layer, decreasing the amount and detail of development required}
         
     | 
| 
       14 
14 
     | 
    
         
             
              s.email = %q{help@amee.com}
         
     | 
| 
       15 
15 
     | 
    
         
             
              s.extra_rdoc_files = [
         
     | 
| 
         @@ -62,16 +62,17 @@ Gem::Specification.new do |s| 
     | 
|
| 
       62 
62 
     | 
    
         
             
                "spec/core-extensions/hash_spec.rb",
         
     | 
| 
       63 
63 
     | 
    
         
             
                "spec/core-extensions/ordered_hash_spec.rb",
         
     | 
| 
       64 
64 
     | 
    
         
             
                "spec/core-extensions/proc_spec.rb",
         
     | 
| 
       65 
     | 
    
         
            -
                "spec/fixtures/electricity.rb",
         
     | 
| 
       66 
     | 
    
         
            -
                "spec/fixtures/electricity_and_transport.rb",
         
     | 
| 
       67 
     | 
    
         
            -
                "spec/fixtures/transport.rb",
         
     | 
| 
      
 65 
     | 
    
         
            +
                "spec/fixtures/config/calculations/electricity.rb",
         
     | 
| 
      
 66 
     | 
    
         
            +
                "spec/fixtures/config/calculations/electricity_and_transport.rb",
         
     | 
| 
      
 67 
     | 
    
         
            +
                "spec/fixtures/config/calculations/transport.rb",
         
     | 
| 
      
 68 
     | 
    
         
            +
                "spec/fixtures/config/electricity.rb",
         
     | 
| 
       68 
69 
     | 
    
         
             
                "spec/spec.opts",
         
     | 
| 
       69 
70 
     | 
    
         
             
                "spec/spec_helper.rb"
         
     | 
| 
       70 
71 
     | 
    
         
             
              ]
         
     | 
| 
       71 
72 
     | 
    
         
             
              s.homepage = %q{http://github.com/AMEE/amee-data-abstraction}
         
     | 
| 
       72 
73 
     | 
    
         
             
              s.licenses = ["BSD 3-Clause"]
         
     | 
| 
       73 
74 
     | 
    
         
             
              s.require_paths = ["lib"]
         
     | 
| 
       74 
     | 
    
         
            -
              s.rubygems_version = %q{1. 
     | 
| 
      
 75 
     | 
    
         
            +
              s.rubygems_version = %q{1.5.3}
         
     | 
| 
       75 
76 
     | 
    
         
             
              s.summary = %q{Calculation and form building tool hiding details of AMEEconnect}
         
     | 
| 
       76 
77 
     | 
    
         | 
| 
       77 
78 
     | 
    
         
             
              if s.respond_to? :specification_version then
         
     | 
| 
         @@ -132,7 +132,7 @@ module AMEE 
     | 
|
| 
       132 
132 
     | 
    
         
             
                  end
         
     | 
| 
       133 
133 
     | 
    
         | 
| 
       134 
134 
     | 
    
         
             
                  def explorer_url
         
     | 
| 
       135 
     | 
    
         
            -
                     ::Rails.logger.info "#explorer_url method deprecated. Use #discover_url" if defined? Rails
         
     | 
| 
      
 135 
     | 
    
         
            +
                     ::Rails.logger.info "#explorer_url method deprecated. Use #discover_url" if defined?(Rails) && ::Rails.logger.present?
         
     | 
| 
       136 
136 
     | 
    
         
             
                     discover_url
         
     | 
| 
       137 
137 
     | 
    
         
             
                  end
         
     | 
| 
       138 
138 
     | 
    
         | 
| 
         @@ -36,22 +36,95 @@ module AMEE 
     | 
|
| 
       36 
36 
     | 
    
         
             
                #
         
     | 
| 
       37 
37 
     | 
    
         
             
                class CalculationSet
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                  #  
     | 
| 
       40 
     | 
    
         
            -
                  #  
     | 
| 
      
 39 
     | 
    
         
            +
                  # Class variable holding all instantiated calculation sets keyed on the set
         
     | 
| 
      
 40 
     | 
    
         
            +
                  # name.
         
     | 
| 
       41 
41 
     | 
    
         
             
                  #
         
     | 
| 
       42 
     | 
    
         
            -
                   
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
                  @@sets = {}
         
     | 
| 
      
 43 
     | 
    
         
            +
                  
         
     | 
| 
      
 44 
     | 
    
         
            +
                  # Convenience method for accessing the @@sets class variable
         
     | 
| 
      
 45 
     | 
    
         
            +
                  def self.sets
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @@sets
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  
         
     | 
| 
      
 49 
     | 
    
         
            +
                  # Retrieve a calculation set on the basis of a configuration file name or
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # relatiev/absolute file path. If configuration files are location within
         
     | 
| 
      
 51 
     | 
    
         
            +
                  # the default Rails location under '/config/calculations' then the path and
         
     | 
| 
      
 52 
     | 
    
         
            +
                  # the .rb extenstion can be omitted from the name.
         
     | 
| 
      
 53 
     | 
    
         
            +
                  #
         
     | 
| 
      
 54 
     | 
    
         
            +
                  def self.find(name)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    @@sets[name.to_sym] or load_set(name)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                  
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # Regenerate a configuration lock file assocaited with the master
         
     | 
| 
      
 59 
     | 
    
         
            +
                  # configuration file <tt>name</tt>. Optionally set a custom path for the
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # lock file as <tt>output_path</tt>, otherwise the lock file path and
         
     | 
| 
      
 61 
     | 
    
         
            +
                  # filename will be based upon the master file with the extension .lock.rb.
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #
         
     | 
| 
      
 63 
     | 
    
         
            +
                  def self.regenerate_lock_file(name,output_path=nil)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    set = CalculationSet.find(name)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    set.generate_lock_file(output_path)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  # Find a specific prototype calculation instance without specifying the set
         
     | 
| 
      
 69 
     | 
    
         
            +
                  # to which it belongs.
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #
         
     | 
| 
      
 71 
     | 
    
         
            +
                  def self.find_prototype_calculation(label)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @@sets.each_pair do |name,set|
         
     | 
| 
      
 73 
     | 
    
         
            +
                      set = find(name)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      return set[label] if set[label]
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  protected
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  # Load a calculation set based on a filename or full path.
         
     | 
| 
      
 82 
     | 
    
         
            +
                  def self.load_set(name)
         
     | 
| 
      
 83 
     | 
    
         
            +
                    CalculationSet.new(name,:file => name) do
         
     | 
| 
      
 84 
     | 
    
         
            +
                      instance_eval(File.open(self.config_path).read)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                  DEFFAULT_RAILS_CONFIG_DIR = "config/calculations"
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  # Find the config file assocaited with <tt>name</tt>. The method first checks
         
     | 
| 
      
 91 
     | 
    
         
            +
                  # the default Rails configuration location (config/calculations) then the
         
     | 
| 
      
 92 
     | 
    
         
            +
                  # file path described by <tt>name</tt> relative to the Rails root and by
         
     | 
| 
      
 93 
     | 
    
         
            +
                  # absolute path.
         
     | 
| 
      
 94 
     | 
    
         
            +
                  def self.find_config_file(name)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    default_config_dir = defined?(::Rails) ? "#{::Rails.root}/#{DEFFAULT_RAILS_CONFIG_DIR}" : nil
         
     | 
| 
      
 96 
     | 
    
         
            +
                    if defined?(::Rails) && File.exists?("#{default_config_dir}/#{name.to_s}.rb")
         
     | 
| 
      
 97 
     | 
    
         
            +
                      "#{default_config_dir}/#{name.to_s}.rb"
         
     | 
| 
      
 98 
     | 
    
         
            +
                    elsif defined?(::Rails) && File.exists?("#{default_config_dir}/#{name.to_s}")
         
     | 
| 
      
 99 
     | 
    
         
            +
                      "#{default_config_dir}/#{name.to_s}"
         
     | 
| 
      
 100 
     | 
    
         
            +
                    elsif defined?(::Rails) && File.exists?("#{::Rails.root}/#{name}")
         
     | 
| 
      
 101 
     | 
    
         
            +
                      "#{::Rails.root}/#{name}"
         
     | 
| 
      
 102 
     | 
    
         
            +
                    elsif File.exists?(name)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      name
         
     | 
| 
      
 104 
     | 
    
         
            +
                    else
         
     | 
| 
      
 105 
     | 
    
         
            +
                      raise ArgumentError, "The config file '#{name}' could not be located"
         
     | 
| 
      
 106 
     | 
    
         
            +
                    end
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  public
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                  attr_accessor :calculations, :name, :file
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  # Initialise a new Calculation set. Specify the name of the calculation set
         
     | 
| 
      
 114 
     | 
    
         
            +
                  # as the first argument. This name is used as the set key within the class
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # variable @@sets hash.
         
     | 
| 
      
 116 
     | 
    
         
            +
                  #
         
     | 
| 
      
 117 
     | 
    
         
            +
                  def initialize(name,options={},&block)
         
     | 
| 
      
 118 
     | 
    
         
            +
                    raise ArgumentError, "Calculation set must have a name" unless name
         
     | 
| 
      
 119 
     | 
    
         
            +
                    @name = name
         
     | 
| 
      
 120 
     | 
    
         
            +
                    @file = CalculationSet.find_config_file(options[:file]) if options[:file]
         
     | 
| 
      
 121 
     | 
    
         
            +
                    @calculations = ActiveSupport::OrderedHash.new
         
     | 
| 
       44 
122 
     | 
    
         
             
                    @all_blocks=[]
         
     | 
| 
       45 
123 
     | 
    
         
             
                    @all_options={}
         
     | 
| 
       46 
124 
     | 
    
         
             
                    instance_eval(&block) if block
         
     | 
| 
      
 125 
     | 
    
         
            +
                    @@sets[@name.to_sym] = self
         
     | 
| 
       47 
126 
     | 
    
         
             
                  end
         
     | 
| 
       48 
127 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                  # Access the @calculations instance variable ordered hash. Keys are labels
         
     | 
| 
       50 
     | 
    
         
            -
                  # assocaited with each prototype calculation; values are the instantiated
         
     | 
| 
       51 
     | 
    
         
            -
                  # <i>PrototypeCalculation</i> objects
         
     | 
| 
       52 
     | 
    
         
            -
                  #
         
     | 
| 
       53 
     | 
    
         
            -
                  attr_accessor :calculations
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
128 
     | 
    
         
             
                  # Shorthand method for returning the prototype calculation which is represented
         
     | 
| 
       56 
129 
     | 
    
         
             
                  # by a label matching <tt>sym</tt>
         
     | 
| 
       57 
130 
     | 
    
         
             
                  #
         
     | 
| 
         @@ -94,8 +167,77 @@ module AMEE 
     | 
|
| 
       94 
167 
     | 
    
         
             
                        instance_exec(usage,&dsl_block)
         
     | 
| 
       95 
168 
     | 
    
         
             
                      }
         
     | 
| 
       96 
169 
     | 
    
         
             
                    end
         
     | 
| 
      
 170 
     | 
    
         
            +
                  end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                  # Returns the path to the configuration file for <tt>self</tt>. If a .lock
         
     | 
| 
      
 173 
     | 
    
         
            +
                  # file exists, this takes precedence, otherwise the master config file
         
     | 
| 
      
 174 
     | 
    
         
            +
                  # described by the <tt>#file</tt> attribute is returned.
         
     | 
| 
      
 175 
     | 
    
         
            +
                  #
         
     | 
| 
      
 176 
     | 
    
         
            +
                  def config_path
         
     | 
| 
      
 177 
     | 
    
         
            +
                    lock_file_exists? ? lock_file_path : @file
         
     | 
| 
      
 178 
     | 
    
         
            +
                  end
         
     | 
| 
       97 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
                  # Returns the path to the configuration lock file
         
     | 
| 
      
 181 
     | 
    
         
            +
                  def lock_file_path
         
     | 
| 
      
 182 
     | 
    
         
            +
                    @file.gsub(".rb",".lock.rb") rescue nil
         
     | 
| 
      
 183 
     | 
    
         
            +
                  end
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
                  # Returns <tt>true</tt> if a configuration lock file exists. Otherwise,
         
     | 
| 
      
 186 
     | 
    
         
            +
                  # returns <tt>false</tt>.
         
     | 
| 
      
 187 
     | 
    
         
            +
                  #
         
     | 
| 
      
 188 
     | 
    
         
            +
                  def lock_file_exists?
         
     | 
| 
      
 189 
     | 
    
         
            +
                    File.exists?(lock_file_path)
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                  # Generates a lock file for the calcuation set configuration. If no argument
         
     | 
| 
      
 193 
     | 
    
         
            +
                  # is provided the, the lock file is generated using the filename and path
         
     | 
| 
      
 194 
     | 
    
         
            +
                  # described by the <tt>#lock_file_path</tt> method. If a custom output
         
     | 
| 
      
 195 
     | 
    
         
            +
                  # location is required, this can be provided optionally as an argument.
         
     | 
| 
      
 196 
     | 
    
         
            +
                  #
         
     | 
| 
      
 197 
     | 
    
         
            +
                  def generate_lock_file(output_path=nil)
         
     | 
| 
      
 198 
     | 
    
         
            +
                    file = output_path || lock_file_path or raise ArgumentError,
         
     | 
| 
      
 199 
     | 
    
         
            +
                      "No path for lock file known. Either set path for the master config file using the #file accessor method or provide as an argument"
         
     | 
| 
      
 200 
     | 
    
         
            +
                    string = ""
         
     | 
| 
      
 201 
     | 
    
         
            +
                    @calculations.values.each do |prototype_calculation|
         
     | 
| 
      
 202 
     | 
    
         
            +
                      string += "calculation {\n\n"
         
     | 
| 
      
 203 
     | 
    
         
            +
                      string += "  name \"#{prototype_calculation.name}\"\n"
         
     | 
| 
      
 204 
     | 
    
         
            +
                      string += "  label :#{prototype_calculation.label}\n"
         
     | 
| 
      
 205 
     | 
    
         
            +
                      string += "  path \"#{prototype_calculation.path}\"\n\n"
         
     | 
| 
      
 206 
     | 
    
         
            +
                      prototype_calculation.terms.each do |term|
         
     | 
| 
      
 207 
     | 
    
         
            +
                        string += "  #{term.class.to_s.split("::").last.downcase} {\n"
         
     | 
| 
      
 208 
     | 
    
         
            +
                        string += "    name \"#{term.name}\"\n" unless term.name.blank?
         
     | 
| 
      
 209 
     | 
    
         
            +
                        string += "    label :#{term.label}\n" unless term.label.blank?
         
     | 
| 
      
 210 
     | 
    
         
            +
                        string += "    path \"#{term.path}\"\n" unless term.path.blank?
         
     | 
| 
      
 211 
     | 
    
         
            +
                        string += "    value \"#{term.value}\"\n" unless term.value.blank?
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                        if term.is_a?(AMEE::DataAbstraction::Input)
         
     | 
| 
      
 214 
     | 
    
         
            +
                          string += "    fixed \"#{term.value}\"\n" if term.fixed? && !term.value.blank?
         
     | 
| 
      
 215 
     | 
    
         
            +
                          if term.is_a?(AMEE::DataAbstraction::Drill)
         
     | 
| 
      
 216 
     | 
    
         
            +
                            string += "    choices \"#{term.choices.join('","')}\"\n" if term.instance_variable_defined?("@choices")  && !term.choices.blank?
         
     | 
| 
      
 217 
     | 
    
         
            +
                          elsif term.is_a?(AMEE::DataAbstraction::Profile)
         
     | 
| 
      
 218 
     | 
    
         
            +
                            string += "    choices [\"#{term.choices.join('","')}\"]\n" if term.instance_variable_defined?("@choices")  && !term.choices.blank?
         
     | 
| 
      
 219 
     | 
    
         
            +
                          end
         
     | 
| 
      
 220 
     | 
    
         
            +
                          string += "    optional!\n" if term.optional?
         
     | 
| 
      
 221 
     | 
    
         
            +
                        end
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                        string += "    default_unit :#{term.default_unit.label}\n" unless term.default_unit.blank?
         
     | 
| 
      
 224 
     | 
    
         
            +
                        string += "    default_per_unit :#{term.default_per_unit.label}\n" unless term.default_per_unit.blank?
         
     | 
| 
      
 225 
     | 
    
         
            +
                        string += "    alternative_units :#{term.alternative_units.map(&:label).join(', :')}\n" unless term.alternative_units.blank?
         
     | 
| 
      
 226 
     | 
    
         
            +
                        string += "    alternative_per_units :#{term.alternative_per_units.map(&:label).join(', :')}\n" unless term.alternative_per_units.blank?
         
     | 
| 
      
 227 
     | 
    
         
            +
                        string += "    unit :#{term.unit.label}\n" unless term.unit.blank?
         
     | 
| 
      
 228 
     | 
    
         
            +
                        string += "    per_unit :#{term.per_unit.label}\n" unless term.per_unit.blank?
         
     | 
| 
      
 229 
     | 
    
         
            +
                        string += "    type :#{term.type}\n" unless term.type.blank?
         
     | 
| 
      
 230 
     | 
    
         
            +
                        string += "    interface :#{term.interface}\n" unless term.interface.blank?
         
     | 
| 
      
 231 
     | 
    
         
            +
                        string += "    note \"#{term.note}\"\n" unless term.note.blank?
         
     | 
| 
      
 232 
     | 
    
         
            +
                        string += "    disable!\n" if !term.is_a?(AMEE::DataAbstraction::Drill) && term.disabled?
         
     | 
| 
      
 233 
     | 
    
         
            +
                        string += "    hide!\n" if term.hidden?
         
     | 
| 
      
 234 
     | 
    
         
            +
                        string += "  }\n\n"
         
     | 
| 
      
 235 
     | 
    
         
            +
                      end
         
     | 
| 
      
 236 
     | 
    
         
            +
                      string += "}\n\n"
         
     | 
| 
      
 237 
     | 
    
         
            +
                    end
         
     | 
| 
      
 238 
     | 
    
         
            +
                    File.open(file,'w') { |f| f.write string }
         
     | 
| 
       98 
239 
     | 
    
         
             
                  end
         
     | 
| 
      
 240 
     | 
    
         
            +
                  
         
     | 
| 
       99 
241 
     | 
    
         
             
                end
         
     | 
| 
       100 
242 
     | 
    
         
             
              end
         
     | 
| 
       101 
243 
     | 
    
         
             
            end
         
     | 
| 
         @@ -158,6 +158,16 @@ module AMEE 
     | 
|
| 
       158 
158 
     | 
    
         
             
                    !optional?(usage)
         
     | 
| 
       159 
159 
     | 
    
         
             
                  end
         
     | 
| 
       160 
160 
     | 
    
         | 
| 
      
 161 
     | 
    
         
            +
                  # Manually set the term as optional
         
     | 
| 
      
 162 
     | 
    
         
            +
                  def optional!
         
     | 
| 
      
 163 
     | 
    
         
            +
                    @optional=true
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                  # Manually set the term as compuslory
         
     | 
| 
      
 167 
     | 
    
         
            +
                  def compulsory!
         
     | 
| 
      
 168 
     | 
    
         
            +
                    @optional=false
         
     | 
| 
      
 169 
     | 
    
         
            +
                  end
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
       161 
171 
     | 
    
         
             
                  # Check that the value of <tt>self</tt> is valid. If invalid, and is defined
         
     | 
| 
       162 
172 
     | 
    
         
             
                  # as part of a calculation, add the invalidity message to the parent
         
     | 
| 
       163 
173 
     | 
    
         
             
                  # calculation's error list. Otherwise, raise a <i>ChoiceValidation</i>
         
     | 
| 
         @@ -258,7 +258,7 @@ module AMEE 
     | 
|
| 
       258 
258 
     | 
    
         
             
                  def load_outputs
         
     | 
| 
       259 
259 
     | 
    
         
             
                    outputs.each do |output|
         
     | 
| 
       260 
260 
     | 
    
         
             
                      res=nil
         
     | 
| 
       261 
     | 
    
         
            -
                      if output.path 
     | 
| 
      
 261 
     | 
    
         
            +
                      if output.path.to_s=='default'
         
     | 
| 
       262 
262 
     | 
    
         
             
                        res= profile_item.amounts.find{|x| x[:default] == true}
         
     | 
| 
       263 
263 
     | 
    
         
             
                      else
         
     | 
| 
       264 
264 
     | 
    
         
             
                        res= profile_item.amounts.find{|x| x[:type] == output.path}
         
     | 
| 
         @@ -84,16 +84,6 @@ module AMEE 
     | 
|
| 
       84 
84 
     | 
    
         
             
                  #
         
     | 
| 
       85 
85 
     | 
    
         
             
                  attr_property :path
         
     | 
| 
       86 
86 
     | 
    
         | 
| 
       87 
     | 
    
         
            -
                  # String representing an annotation for <tt>self</tt>. Set a value by
         
     | 
| 
       88 
     | 
    
         
            -
                  # passing an argument. Retrieve a value by calling without an argument,
         
     | 
| 
       89 
     | 
    
         
            -
                  # e.g.,
         
     | 
| 
       90 
     | 
    
         
            -
                  #
         
     | 
| 
       91 
     | 
    
         
            -
                  #  my_term.note 'Enter the mass of cement produced in the reporting period'
         
     | 
| 
       92 
     | 
    
         
            -
                  #
         
     | 
| 
       93 
     | 
    
         
            -
                  #  my_term.note                       #=> 'Enter the mass of cement ...'
         
     | 
| 
       94 
     | 
    
         
            -
                  #
         
     | 
| 
       95 
     | 
    
         
            -
                  attr_property :note
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
87 
     | 
    
         
             
                  # Symbol representing the owning parent calculation of <tt>self</tt>. Set
         
     | 
| 
       98 
88 
     | 
    
         
             
                  # the owning calculation object by passing as an argument. Retrieve it by
         
     | 
| 
       99 
89 
     | 
    
         
             
                  # calling without an argument, e.g.,
         
     | 
| 
         @@ -211,6 +201,19 @@ module AMEE 
     | 
|
| 
       211 
201 
     | 
    
         
             
                    end
         
     | 
| 
       212 
202 
     | 
    
         
             
                    @value
         
     | 
| 
       213 
203 
     | 
    
         
             
                  end
         
     | 
| 
      
 204 
     | 
    
         
            +
             
     | 
| 
      
 205 
     | 
    
         
            +
                  # String representing an annotation for <tt>self</tt>. Set a value by
         
     | 
| 
      
 206 
     | 
    
         
            +
                  # passing an argument. Retrieve a value by calling without an argument,
         
     | 
| 
      
 207 
     | 
    
         
            +
                  # e.g.,
         
     | 
| 
      
 208 
     | 
    
         
            +
                  #
         
     | 
| 
      
 209 
     | 
    
         
            +
                  #  my_term.note 'Enter the mass of cement produced in the reporting period'
         
     | 
| 
      
 210 
     | 
    
         
            +
                  #
         
     | 
| 
      
 211 
     | 
    
         
            +
                  #  my_term.note                       #=> 'Enter the mass of cement ...'
         
     | 
| 
      
 212 
     | 
    
         
            +
                  #
         
     | 
| 
      
 213 
     | 
    
         
            +
                  def note(string=nil)
         
     | 
| 
      
 214 
     | 
    
         
            +
                    instance_variable_set("@note",string.gsub('"',"'")) unless string.nil?
         
     | 
| 
      
 215 
     | 
    
         
            +
                    instance_variable_get("@note")
         
     | 
| 
      
 216 
     | 
    
         
            +
                  end
         
     | 
| 
       214 
217 
     | 
    
         | 
| 
       215 
218 
     | 
    
         
             
                  # Symbols representing the attributes of <tt>self</tt> which are concerned
         
     | 
| 
       216 
219 
     | 
    
         
             
                  # with quantity units.
         
     | 
| 
         @@ -264,19 +267,33 @@ module AMEE 
     | 
|
| 
       264 
267 
     | 
    
         
             
                  end
         
     | 
| 
       265 
268 
     | 
    
         | 
| 
       266 
269 
     | 
    
         
             
                  [:unit,:per_unit].each do |field|
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                    # If no argument provided, returns the alternative units which are valid
         
     | 
| 
      
 272 
     | 
    
         
            +
                    # for <tt>self</tt>. If a list of units are provided as an argument, these
         
     | 
| 
      
 273 
     | 
    
         
            +
                    # override the dynamically assigned alternative units for <tt>self</tt>.
         
     | 
| 
      
 274 
     | 
    
         
            +
                    #
         
     | 
| 
       267 
275 
     | 
    
         
             
                    define_method("alternative_#{field}s") do |*args|
         
     | 
| 
       268 
276 
     | 
    
         
             
                      ivar = "@alternative_#{field}s"
         
     | 
| 
       269 
     | 
    
         
            -
                      default = send("default_#{field}".to_sym)
         
     | 
| 
       270 
277 
     | 
    
         
             
                      unless args.empty?
         
     | 
| 
       271 
     | 
    
         
            -
                        args << default if default
         
     | 
| 
       272 
278 
     | 
    
         
             
                        units = args.map {|arg| Unit.for(arg) }
         
     | 
| 
       273 
279 
     | 
    
         
             
                        Term.validate_dimensional_equivalence?(*units)
         
     | 
| 
       274 
280 
     | 
    
         
             
                        instance_variable_set(ivar, units)
         
     | 
| 
       275 
281 
     | 
    
         
             
                      else
         
     | 
| 
       276 
282 
     | 
    
         
             
                        return instance_variable_get(ivar) if instance_variable_get(ivar)
         
     | 
| 
       277 
     | 
    
         
            -
                         
     | 
| 
      
 283 
     | 
    
         
            +
                        default = send("default_#{field}".to_sym)
         
     | 
| 
      
 284 
     | 
    
         
            +
                        return instance_variable_set(ivar, (default.alternatives)) if default
         
     | 
| 
       278 
285 
     | 
    
         
             
                      end
         
     | 
| 
       279 
286 
     | 
    
         
             
                    end
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                    # Returns the list of unit choices for <tt>self</tt>, including both the
         
     | 
| 
      
 289 
     | 
    
         
            +
                    # default unit and all alternative units.
         
     | 
| 
      
 290 
     | 
    
         
            +
                    #
         
     | 
| 
      
 291 
     | 
    
         
            +
                    define_method("#{field}_choices") do |*args|
         
     | 
| 
      
 292 
     | 
    
         
            +
                      choices = send("alternative_#{field}s".to_sym)
         
     | 
| 
      
 293 
     | 
    
         
            +
                      default = send("default_#{field}".to_sym)
         
     | 
| 
      
 294 
     | 
    
         
            +
                      choices = [default] + choices if default
         
     | 
| 
      
 295 
     | 
    
         
            +
                      return choices
         
     | 
| 
      
 296 
     | 
    
         
            +
                    end
         
     | 
| 
       280 
297 
     | 
    
         
             
                  end
         
     | 
| 
       281 
298 
     | 
    
         | 
| 
       282 
299 
     | 
    
         
             
                  # Returns <tt>true</tt> if <tt>self</tt> has a populated value attribute.
         
     | 
| 
         @@ -503,6 +520,7 @@ module AMEE 
     | 
|
| 
       503 
520 
     | 
    
         
             
                      else value
         
     | 
| 
       504 
521 
     | 
    
         
             
                    end
         
     | 
| 
       505 
522 
     | 
    
         
             
                  end
         
     | 
| 
      
 523 
     | 
    
         
            +
                  
         
     | 
| 
       506 
524 
     | 
    
         
             
                end
         
     | 
| 
       507 
525 
     | 
    
         
             
              end
         
     | 
| 
       508 
526 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require  
     | 
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
            class CalculationSet
         
     | 
| 
       3 
4 
     | 
    
         
             
              def call_me
         
     | 
| 
       4 
5 
     | 
    
         
             
                #stub, because flexmock doesn't work for new instances during constructor
         
     | 
| 
         @@ -8,25 +9,260 @@ class CalculationSet 
     | 
|
| 
       8 
9 
     | 
    
         
             
                @@called
         
     | 
| 
       9 
10 
     | 
    
         
             
              end
         
     | 
| 
       10 
11 
     | 
    
         
             
            end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       11 
13 
     | 
    
         
             
            describe CalculationSet do
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              before :all do
         
     | 
| 
      
 16 
     | 
    
         
            +
                CalculationSet.sets.clear
         
     | 
| 
      
 17 
     | 
    
         
            +
                @calc_set = CalculationSet.find("electricity_and_transport")
         
     | 
| 
       14 
18 
     | 
    
         
             
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       15 
20 
     | 
    
         
             
              it 'can create an instance' do
         
     | 
| 
       16 
     | 
    
         
            -
                 
     | 
| 
      
 21 
     | 
    
         
            +
                @calc_set.calculations.should be_a ActiveSupport::OrderedHash
         
     | 
| 
      
 22 
     | 
    
         
            +
                @calc_set.should be_a CalculationSet
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              it 'can create an instance and find calcs' do
         
     | 
| 
      
 26 
     | 
    
         
            +
                @calc_set.calculations.should be_a ActiveSupport::OrderedHash
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              it "can access class sets hash" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                CalculationSet.sets[:electricity_and_transport].should be_a CalculationSet
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              it "is included in class sets hash if initialised by find method" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                CalculationSet.sets[:electricity_and_transport].should be_a CalculationSet
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              it "has file attribute if initialised by find method" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                CalculationSet.sets[:electricity_and_transport].file.should eql "#{Rails.root}/config/calculations/electricity_and_transport.rb"
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              it "has name attribute if initialised by find method" do
         
     | 
| 
      
 42 
     | 
    
         
            +
                CalculationSet.sets[:electricity_and_transport].name.should eql "electricity_and_transport"
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              it "is included in class sets hash if initialised manually" do
         
     | 
| 
      
 46 
     | 
    
         
            +
                CalculationSet.new('my_set') {calculation {label :mycalc}}
         
     | 
| 
      
 47 
     | 
    
         
            +
                CalculationSet.sets[:my_set].should be_a CalculationSet
         
     | 
| 
       17 
48 
     | 
    
         
             
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              it "has name" do
         
     | 
| 
      
 51 
     | 
    
         
            +
                CalculationSet.new('my_set') {calculation {label :mycalc}}.name.should eql "my_set"
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
       18 
54 
     | 
    
         
             
              it 'can access a calculation by key' do
         
     | 
| 
       19 
     | 
    
         
            -
                 
     | 
| 
      
 55 
     | 
    
         
            +
                @calc_set[:transport].should be_a PrototypeCalculation
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
              describe "initialising from file" do
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                after(:each) do
         
     | 
| 
      
 61 
     | 
    
         
            +
                  CalculationSet.sets.clear
         
     | 
| 
      
 62 
     | 
    
         
            +
                  delete_lock_files
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                it "should find config file in default Rails location using just file name" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                  CalculationSet.find_config_file("electricity").should eql "#{Rails.root}/config/calculations/electricity.rb"
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                it "should find config file in default Rails location using file name and extension" do
         
     | 
| 
      
 70 
     | 
    
         
            +
                  CalculationSet.find_config_file("electricity.rb").should eql "#{Rails.root}/config/calculations/electricity.rb"
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                it "should find config file in other Rails location using relative path" do
         
     | 
| 
      
 74 
     | 
    
         
            +
                  CalculationSet.find_config_file("config/electricity.rb").should eql "#{Rails.root}/config/electricity.rb"
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                it "should raise error if config file not found" do
         
     | 
| 
      
 78 
     | 
    
         
            +
                  lambda{CalculationSet.find_config_file("fuel")}.should raise_error
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                it "should call load_set if no set exists in class hash" do
         
     | 
| 
      
 82 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_nil
         
     | 
| 
      
 83 
     | 
    
         
            +
                  flexmock(AMEE::DataAbstraction::CalculationSet) do |mock|
         
     | 
| 
      
 84 
     | 
    
         
            +
                    mock.should_receive(:load_set).once
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                it "should not call load_set if set exists in class hash" do
         
     | 
| 
      
 90 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_nil
         
     | 
| 
      
 91 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 92 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_a CalculationSet
         
     | 
| 
      
 93 
     | 
    
         
            +
                  flexmock(AMEE::DataAbstraction::CalculationSet) do |mock|
         
     | 
| 
      
 94 
     | 
    
         
            +
                    mock.should_receive(:load_set).never
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 97 
     | 
    
         
            +
                end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
               it "should generate set from file name using find method" do
         
     | 
| 
      
 100 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_nil
         
     | 
| 
      
 101 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 102 
     | 
    
         
            +
                  set.should be_a CalculationSet
         
     | 
| 
      
 103 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_a CalculationSet
         
     | 
| 
      
 104 
     | 
    
         
            +
                  set.name.should eql 'transport'
         
     | 
| 
      
 105 
     | 
    
         
            +
                  set.file.should eql "#{Rails.root}/config/calculations/transport.rb"
         
     | 
| 
      
 106 
     | 
    
         
            +
                end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                it "should regenerate lock file at default location" do
         
     | 
| 
      
 109 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 110 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 111 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_nil
         
     | 
| 
      
 112 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 113 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 114 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_a CalculationSet
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                  set.generate_lock_file
         
     | 
| 
      
 117 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                  # lock file content
         
     | 
| 
      
 120 
     | 
    
         
            +
                  content = File.open(lock_file).read
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                  # clear lock file to test for regenerated data
         
     | 
| 
      
 123 
     | 
    
         
            +
                  File.open(lock_file,'w') {|file| file.write "overwrite content"}
         
     | 
| 
      
 124 
     | 
    
         
            +
                  File.open(lock_file).read.should eql "overwrite content"
         
     | 
| 
      
 125 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  # regenerate and test content matches original
         
     | 
| 
      
 128 
     | 
    
         
            +
                  CalculationSet.regenerate_lock_file('transport')
         
     | 
| 
      
 129 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 130 
     | 
    
         
            +
                  File.open(lock_file).read.should eql content
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                it "should regenerate lock file at custom location" do
         
     | 
| 
      
 134 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 135 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 136 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_nil
         
     | 
| 
      
 137 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 140 
     | 
    
         
            +
                  CalculationSet.sets[:transport].should be_a CalculationSet
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                  set.generate_lock_file
         
     | 
| 
      
 143 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                  content = File.open(lock_file).read
         
     | 
| 
      
 146 
     | 
    
         
            +
                  File.open(lock_file,'w') {|file| file.write "overwrite content"}
         
     | 
| 
      
 147 
     | 
    
         
            +
                  File.open(lock_file).read.should eql "overwrite content"
         
     | 
| 
      
 148 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  CalculationSet.regenerate_lock_file('transport', "#{Rails.root}/transport.lock.rb")
         
     | 
| 
      
 151 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 152 
     | 
    
         
            +
                  File.exist?("#{Rails.root}/transport.lock.rb").should be_true
         
     | 
| 
      
 153 
     | 
    
         
            +
                  File.open(lock_file).read.should eql "overwrite content"
         
     | 
| 
      
 154 
     | 
    
         
            +
                  File.open("#{Rails.root}/transport.lock.rb").read.should eql content
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
                  File.delete("#{Rails.root}/transport.lock.rb")
         
     | 
| 
      
 157 
     | 
    
         
            +
                end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                it "should return a lock file path based on master config file" do
         
     | 
| 
      
 160 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 161 
     | 
    
         
            +
                  set.lock_file_path.should eql "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 162 
     | 
    
         
            +
                end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                it "should return lock file path if lock file exists" do
         
     | 
| 
      
 165 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 166 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 167 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 168 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 169 
     | 
    
         
            +
                  set.generate_lock_file
         
     | 
| 
      
 170 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 171 
     | 
    
         
            +
                  set.config_path.should eql lock_file
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                it "should return master file path if lock file does not exist" do
         
     | 
| 
      
 175 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 176 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 177 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 178 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 179 
     | 
    
         
            +
                  set.config_path.should eql "#{Rails.root}/config/calculations/transport.rb"
         
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                it "should know if lock file exists" do
         
     | 
| 
      
 183 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 184 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 185 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 186 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 187 
     | 
    
         
            +
                  set.generate_lock_file
         
     | 
| 
      
 188 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 189 
     | 
    
         
            +
                  set.lock_file_exists?.should be_true
         
     | 
| 
      
 190 
     | 
    
         
            +
                  File.delete(lock_file)
         
     | 
| 
      
 191 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 192 
     | 
    
         
            +
                  set.lock_file_exists?.should be_false
         
     | 
| 
      
 193 
     | 
    
         
            +
                end
         
     | 
| 
      
 194 
     | 
    
         
            +
                
         
     | 
| 
      
 195 
     | 
    
         
            +
                it "should generate lock file" do
         
     | 
| 
      
 196 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 197 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 200 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 201 
     | 
    
         
            +
                  set.lock_file_exists?.should be_false
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                  set.generate_lock_file
         
     | 
| 
      
 204 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 205 
     | 
    
         
            +
                  set.lock_file_exists?.should be_true
         
     | 
| 
      
 206 
     | 
    
         
            +
             
     | 
| 
      
 207 
     | 
    
         
            +
                  content = File.open(lock_file).read
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                  File.delete(lock_file)
         
     | 
| 
      
 210 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 211 
     | 
    
         
            +
                  set.lock_file_exists?.should be_false
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                  set.generate_lock_file
         
     | 
| 
      
 214 
     | 
    
         
            +
                  File.exist?(lock_file).should be_true
         
     | 
| 
      
 215 
     | 
    
         
            +
                  set.lock_file_exists?.should be_true
         
     | 
| 
      
 216 
     | 
    
         
            +
                  File.open(lock_file).read.should eql content
         
     | 
| 
      
 217 
     | 
    
         
            +
                end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
                it "should generate lock file at custom location" do
         
     | 
| 
      
 220 
     | 
    
         
            +
                  lock_file = "#{Rails.root}/config/calculations/transport.lock.rb"
         
     | 
| 
      
 221 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
                  set = CalculationSet.find('transport')
         
     | 
| 
      
 224 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 225 
     | 
    
         
            +
                  set.lock_file_exists?.should be_false
         
     | 
| 
      
 226 
     | 
    
         
            +
             
     | 
| 
      
 227 
     | 
    
         
            +
                  set.generate_lock_file("#{Rails.root}/transport.lock.rb")
         
     | 
| 
      
 228 
     | 
    
         
            +
                  File.exist?(lock_file).should be_false
         
     | 
| 
      
 229 
     | 
    
         
            +
                  set.lock_file_exists?.should be_false
         
     | 
| 
      
 230 
     | 
    
         
            +
                  File.exist?("#{Rails.root}/transport.lock.rb").should be_true
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                  File.delete("#{Rails.root}/transport.lock.rb")
         
     | 
| 
      
 233 
     | 
    
         
            +
                end
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
              end
         
     | 
| 
      
 236 
     | 
    
         
            +
             
     | 
| 
      
 237 
     | 
    
         
            +
              it "can find a prototype calc without calc set" do
         
     | 
| 
      
 238 
     | 
    
         
            +
                CalculationSet.new('my_set') {
         
     | 
| 
      
 239 
     | 
    
         
            +
                  calculation {label :my_calc}
         
     | 
| 
      
 240 
     | 
    
         
            +
                  calculation {label :my_other_calc}
         
     | 
| 
      
 241 
     | 
    
         
            +
                }
         
     | 
| 
      
 242 
     | 
    
         
            +
                CalculationSet.new('your_set') {
         
     | 
| 
      
 243 
     | 
    
         
            +
                  calculation {label :your_calc}
         
     | 
| 
      
 244 
     | 
    
         
            +
                  calculation {label :your_other_calc}
         
     | 
| 
      
 245 
     | 
    
         
            +
                }
         
     | 
| 
      
 246 
     | 
    
         
            +
                CalculationSet.find_prototype_calculation(:transport).should be_a PrototypeCalculation
         
     | 
| 
      
 247 
     | 
    
         
            +
                CalculationSet.find_prototype_calculation(:your_calc).should be_a PrototypeCalculation
         
     | 
| 
      
 248 
     | 
    
         
            +
                CalculationSet.find_prototype_calculation(:my_other_calc).should be_a PrototypeCalculation
         
     | 
| 
      
 249 
     | 
    
         
            +
              end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
              it "returns nil where no prototype calcualtion is found" do
         
     | 
| 
      
 252 
     | 
    
         
            +
                CalculationSet.find_prototype_calculation(:fuel).should be_nil
         
     | 
| 
       20 
253 
     | 
    
         
             
              end
         
     | 
| 
      
 254 
     | 
    
         
            +
             
     | 
| 
       21 
255 
     | 
    
         
             
              it 'can construct a calculation' do
         
     | 
| 
       22 
     | 
    
         
            -
                CalculationSet.new {calculation {label :mycalc}}[:mycalc].should be_a PrototypeCalculation
         
     | 
| 
      
 256 
     | 
    
         
            +
                CalculationSet.new('my_set') {calculation {label :mycalc}}[:mycalc].should be_a PrototypeCalculation
         
     | 
| 
       23 
257 
     | 
    
         
             
              end
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
       24 
259 
     | 
    
         
             
              it 'can be initialized with a DSL block' do
         
     | 
| 
       25 
     | 
    
         
            -
                CalculationSet.new {call_me}
         
     | 
| 
      
 260 
     | 
    
         
            +
                CalculationSet.new('my_set') {call_me}
         
     | 
| 
       26 
261 
     | 
    
         
             
                CalculationSet.called.should be_true
         
     | 
| 
       27 
262 
     | 
    
         
             
              end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
       28 
264 
     | 
    
         
             
              it 'can have terms added to all calculations' do
         
     | 
| 
       29 
     | 
    
         
            -
                cs=CalculationSet.new {
         
     | 
| 
      
 265 
     | 
    
         
            +
                cs=CalculationSet.new('my_set') {
         
     | 
| 
       30 
266 
     | 
    
         
             
                  all_calculations {
         
     | 
| 
       31 
267 
     | 
    
         
             
                    drill {label :energetic}
         
     | 
| 
       32 
268 
     | 
    
         
             
                  }
         
     | 
| 
         @@ -37,6 +273,7 @@ describe CalculationSet do 
     | 
|
| 
       37 
273 
     | 
    
         
             
                }
         
     | 
| 
       38 
274 
     | 
    
         
             
                cs[:mycalc].drills.labels.should eql [:remarkably,:energetic]
         
     | 
| 
       39 
275 
     | 
    
         
             
              end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
       40 
277 
     | 
    
         
             
              it 'can make multiple calculations quickly, one for each usage' do
         
     | 
| 
       41 
278 
     | 
    
         
             
                mocker=AMEEMocker.new(self,:path=>'something')
         
     | 
| 
       42 
279 
     | 
    
         
             
                mocker.item_value_definitions.usages(['bybob','byfrank']).
         
     | 
| 
         @@ -44,7 +281,7 @@ describe CalculationSet do 
     | 
|
| 
       44 
281 
     | 
    
         
             
                  item_value_definition('first',['bybob'],[],'byfrank',[],nil,nil,true,false,nil,"TEXT").
         
     | 
| 
       45 
282 
     | 
    
         
             
                  item_value_definition('second',['bybob'],[],'byfrank',[],nil,nil,true,false,nil,"TEXT").
         
     | 
| 
       46 
283 
     | 
    
         
             
                  item_value_definition('third',['byfrank'],[],['bybob'],[],nil,nil,true,false,nil,"TEXT")
         
     | 
| 
       47 
     | 
    
         
            -
                cs=CalculationSet.new {
         
     | 
| 
      
 284 
     | 
    
         
            +
                cs=CalculationSet.new('my_set') {
         
     | 
| 
       48 
285 
     | 
    
         
             
                  calculations_all_usages('/something') { |usage|
         
     | 
| 
       49 
286 
     | 
    
         
             
                    label usage.to_sym
         
     | 
| 
       50 
287 
     | 
    
         
             
                    profiles_from_usage usage
         
     | 
| 
         @@ -53,4 +290,5 @@ describe CalculationSet do 
     | 
|
| 
       53 
290 
     | 
    
         
             
                cs[:bybob].profiles.labels.should eql [:first,:second]
         
     | 
| 
       54 
291 
     | 
    
         
             
                cs[:byfrank].profiles.labels.should eql [:third]
         
     | 
| 
       55 
292 
     | 
    
         
             
              end
         
     | 
| 
      
 293 
     | 
    
         
            +
              
         
     | 
| 
       56 
294 
     | 
    
         
             
            end
         
     |