module BTAPMeasureTestHelper

Public Instance Methods

argument_type(argument) click to toggle source

Determines the OS argument type dynamically.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 367
def argument_type(argument)
  case argument.type.value
    when 0
      return 'Bool'
    when 1 # Double
      return 'Double'
    when 2 # Quantity
      return 'Quantity'
    when 3 # Integer
      return 'Integer'
    when 4
      return 'String'
    when 5 # Choice
      return 'Choice'
    when 6 # Path
      return 'Path'
    when 7 # Separator
      return 'Separator'
    else
      return 'Blah'
  end
end
copy_model(model) click to toggle source

Method does a deep copy of a model.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 398
def copy_model(model)
  copy_model = OpenStudio::Model::Model.new
  # remove existing objects from model
  handles = OpenStudio::UUIDVector.new
  copy_model.objects.each do |obj|
    handles << obj.handle
  end
  copy_model.removeObjects(handles)
  # put contents of new_model into model_to_replace
  copy_model.addObjects(model.toIdfFile.objects)
  return copy_model
end
create_necb_protype_model(building_type, climate_zone, epw_file, template) click to toggle source

helper method to create necb archetype as a starting point for testing.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 299
def create_necb_protype_model(building_type, climate_zone, epw_file, template)
  osm_directory = "#{__dir__}/output/#{building_type}-#{template}-#{climate_zone}-#{epw_file}"
  FileUtils.mkdir_p(osm_directory)

  # Set building location from epw file
  weather_file_path = OpenstudioStandards::Weather.get_standards_weather_file_path(epw_file)
  OpenstudioStandards::Weather.model_set_building_location(model, weather_file_path: weather_file_path)

  # create model
  prototype_creator = Standard.build("#{template}_#{building_type}")
  model = prototype_creator.model_create_prototype_model(climate_zone,
                                                         epw_file,
                                                         osm_directory,
                                                         @debug,
                                                         model)
  return model
end
get_measure_object() click to toggle source

Fancy way of getting the measure object automatically.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 355
def get_measure_object
  measure_class_name = self.class.name.to_s.match(/(BTAP.*)(\_Test)/i).captures[0]
  measure = nil
  eval "measure = #{measure_class_name}.new"
  if measure.nil?
    puts "Measure class #{measure_class_name} is invalid. Please ensure the test class name is of the form 'BTAPMeasureName_Test' (Note: BTAP is case sensitive.) ".red
    return false
  end
  return measure
end
run_measure(input_arguments, model) click to toggle source

Custom way to run the measure in the test.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 318
def run_measure(input_arguments, model)
  # This will create a instance of the measure you wish to test. It does this based on the test class name.
  measure = get_measure_object
  measure.use_json_package = @use_json_package
  measure.use_string_double = @use_string_double
  # Return false if can't
  return false if measure == false

  arguments = measure.arguments(model)
  argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
  runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)
  # Check if

  # Set the arguements in the argument map use json or real arguments.
  if @use_json_package
    argument = arguments[0].clone
    assert(argument.setValue(input_arguments['json_input']), "Could not set value for 'json_input' to #{input_arguments['json_input']}")
    argument_map['json_input'] = argument
  else
    input_arguments.each_with_index do |(key, value), index|
      argument = arguments[index].clone
      if argument_type(argument) == 'Double'
        # forces it to a double if it is a double.
        assert(argument.setValue(value.to_f), "Could not set value for #{key} to #{value}")
      else
        assert(argument.setValue(value.to_s), "Could not set value for #{key} to #{value}")
      end
      argument_map[key] = argument
    end
  end
  # run the measure
  measure.run(model, runner, argument_map)
  runner.result
  return runner
end
test_argument_ranges() click to toggle source

Test argument ranges.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 208
def test_argument_ranges
  model = OpenStudio::Model::Model.new
  standard = Standard.build('NECB2015')
  weather_file_path = OpenstudioStandards::Weather.get_standards_weather_file_path('CAN_AB_Edmonton.Intl.AP.711230_CWEC2020.epw')
  OpenstudioStandards::Weather.model_set_building_location(model, weather_file_path: weather_file_path)

  [true, false].each do |json_input|
    [true, false].each do |string_double|
      @use_json_package = json_input
      @use_string_double = string_double
      @measure_interface_detailed.each do |argument|
        ##########################
        if argument['type'] == 'Integer'
          puts "Testing range for #{argument['name']}".blue
          # Check over max

          if !argument['max_integer_value'].nil?
            puts 'Testing max limit'
            input_arguments = @good_input_arguments.clone
            over_max_value = argument['max_integer_value'].to_i + 1
            input_arguments[argument['name']] = over_max_value
            puts "Testing argument #{argument['name']} max limit of #{argument['max_integer_value']}".light_blue
            input_arguments = { 'json_input' => JSON.pretty_generate(input_arguments) } if @use_json_package
            run_measure(input_arguments, model)
            runner = run_measure(input_arguments, model)
            assert(runner.result.value.valueName != 'Success', "Checks did not stop a lower than limit value of #{over_max_value} for #{argument['name']}")
            puts "Success: Testing argument #{argument['name']} max limit of #{argument['max_integer_value']}".green
          end
          # Check over max
          if !argument['min_integer_value'].nil?
            puts 'Testing min limit'
            input_arguments = @good_input_arguments.clone
            over_min_value = argument['min_integer_value'].to_i - 1
            input_arguments[argument['name']] = over_min_value
            puts "Testing argument #{argument['name']} min limit of #{argument['min_integer_value']}".light_blue
            input_arguments = { 'json_input' => JSON.pretty_generate(input_arguments) } if @use_json_package
            runner = run_measure(input_arguments, model)
            assert(runner.result.value.valueName != 'Success', "Checks did not stop a lower than limit value of #{over_min_value} for #{argument['name']}")
            puts "Success:Testing argument #{argument['name']} min limit of #{argument['min_integer_value']}".green
          end

        end
        ###########################

        if (argument['type'] == 'Double') || (argument['type'] == 'StringDouble')
          puts "Testing range for #{argument['name']} ".blue
          # Check over max

          if !argument['max_double_value'].nil?
            puts 'Testing max limit'
            input_arguments = @good_input_arguments.clone
            over_max_value = argument['max_double_value'].to_f + 1.0
            over_max_value = over_max_value.to_s if argument['type'].downcase == 'StringDouble'.downcase
            input_arguments[argument['name']] = over_max_value
            puts "Testing argument #{argument['name']} max limit of #{argument['max_double_value']}".light_blue
            input_arguments = { 'json_input' => JSON.pretty_generate(input_arguments) } if @use_json_package
            run_measure(input_arguments, model)
            runner = run_measure(input_arguments, model)
            assert(runner.result.value.valueName != 'Success', "Checks did not stop a lower than limit value of #{over_max_value} for #{argument['name']}")
            puts "Success: Testing argument #{argument['name']} max limit of #{argument['max_double_value']}".green
          end
          # Check over max
          if !argument['min_double_value'].nil?
            puts 'Testing min limit'
            input_arguments = @good_input_arguments.clone
            over_min_value = argument['min_double_value'].to_f - 1.0
            over_min_value = over_max_value.to_s if argument['type'].downcase == 'StringDouble'.downcase
            input_arguments[argument['name']] = over_min_value
            puts "Testing argument #{argument['name']} min limit of #{argument['min_double_value']}".light_blue
            input_arguments = { 'json_input' => JSON.pretty_generate(input_arguments) } if @use_json_package
            runner = run_measure(input_arguments, model)
            assert(runner.result.value.valueName != 'Success', "Checks did not stop a lower than limit value of #{over_min_value} for #{argument['name']}")
            puts "Success:Testing argument #{argument['name']} min limit of #{argument['min_double_value']}".green
          end

        end

        if (argument['type'] == 'StringDouble') && !argument['valid_strings'].nil? && @use_string_double
          input_arguments = @good_input_arguments.clone
          input_arguments[argument['name']] = SecureRandom.uuid.to_s
          puts "Testing argument #{argument['name']} min limit of #{argument['min_double_value']}".light_blue
          input_arguments = { 'json_input' => JSON.pretty_generate(input_arguments) } if @use_json_package
          runner = run_measure(input_arguments, model)
          assert(runner.result.value.valueName != 'Success', "Checks did not stop a lower than limit value of #{over_min_value} for #{argument['name']}")
        end
      end
    end
  end
end
test_arguments_and_defaults() click to toggle source

Boiler plate to default values and number of arguments against what is in your test’s setup method.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 164
def test_arguments_and_defaults
  [true, false].each do |json_input|
    [true, false].each do |string_double|
      @use_json_package = json_input
      @use_string_double = string_double

      # Create an instance of the measure
      measure = get_measure_object
      measure.use_json_package = @use_json_package
      measure.use_string_double = @use_string_double
      model = OpenStudio::Model::Model.new

      # Create an instance of a runner
      runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)

      # Test arguments and defaults
      arguments = measure.arguments(model)
      # convert whatever the input was into a hash. Then test.

      # check number of arguments.
      if @use_json_package
        assert_equal(@measure_interface_detailed.size, JSON.parse(arguments[0].defaultValueAsString).size, "The measure should have #{@measure_interface_detailed.size} but actually has #{arguments.size}. Here the the arguement expected #{JSON.pretty_generate(@measure_interface_detailed)} /n and this is the actual /n #{JSON.pretty_generate(arguments[0])}")
      else
        assert_equal(@measure_interface_detailed.size, arguments.size, "The measure should have #{@measure_interface_detailed.size} but actually has #{arguments.size}. Here the the arguement expected #{@measure_interface_detailed} and this is the actual #{arguments}")
        @measure_interface_detailed.each_with_index do |argument_expected, index|
          assert_equal(argument_expected['name'], arguments[index].name, "Measure argument name of #{argument_expected['name']} was expected, but got #{arguments[index].name} instead.")
          assert_equal(argument_expected['display_name'], arguments[index].displayName, "Display name for argument #{argument_expected['name']} was expected to be #{argument_expected['display_name']}, but got #{arguments[index].displayName} instead.")
          case argument_type(arguments[index])
            when 'String', 'Choice'
              assert_equal(argument_expected['default_value'].to_s, arguments[index].defaultValueAsString, "The default value for argument #{argument_expected['name']} was #{argument_expected['default_value']}, but actual was #{arguments[index].defaultValueAsString}")
            when 'Double'
              assert_equal(argument_expected['default_value'].to_f, arguments[index].defaultValueAsDouble.to_f, "The default value for argument #{argument_expected['name']} was #{argument_expected['default_value']}, but actual was #{arguments[index].defaultValueAsString}")
            when 'Integer'
              assert_equal(argument_expected['default_value'].to_i, arguments[index].defaultValueAsInteger.to_i, "The default value for argument #{argument_expected['name']} was #{argument_expected['default_value']}, but actual was #{arguments[index].defaultValueAsString}")
            when 'Bool'
              assert_equal(argument_expected['default_value'], arguments[index].defaultValueAsBool, "The default value for argument #{argument_expected['name']} was #{argument_expected['default_value']}, but actual was #{arguments[index].defaultValueAsString}")
          end
        end
      end
    end
  end
end
valid_float?(str) click to toggle source

Valid float helper.

# File lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb, line 391
def valid_float?(str)
  !!Float(str)
rescue StandardError
  false
end