diff --git a/python/test/test_swigjson.py b/python/test/test_swigjson.py index f7fb06d3772..be320e059c7 100644 --- a/python/test/test_swigjson.py +++ b/python/test/test_swigjson.py @@ -47,3 +47,35 @@ def test_osargument_value_as_json(): val = choiceArgument.valueAsJSON() assert isinstance(val, str) assert val == "handle1" + + +def test_swig_json_special_chars(): + workflow = openstudio.WorkflowJSON() + runner = openstudio.measure.OSRunner(workflow) + + step1 = openstudio.MeasureStep("MeasureName1") + step1.setArgument("Argument1", 100) + + workflow_step_result1 = openstudio.WorkflowStepResult() + workflow_step_result1.setMeasureName("measure_name_1") + + name = "name_(|)'*$£*µ%é" + val = "val_(|)'*$£*µ%é" + stepValue1 = openstudio.WorkflowStepValue(name, val) + assert name == stepValue1.name() + assert val == stepValue1.valueAsString() + assert val == stepValue1.valueAsJSON() + + workflow_step_result1.addStepValue(stepValue1) + + workflow_step_result1.setStepResult(openstudio.StepResult("Success")) + workflow_step_result1.setCompletedAt(openstudio.DateTime.nowUTC()) + step1.setResult(workflow_step_result1) + + workflow.setWorkflowSteps([step1]) + + d = runner.getPastStepValuesForMeasure("MeasureName1") + assert len(d) == 1 + k, v = next(iter(d.items())) + assert k == name + assert v == val diff --git a/ruby/test/SwigJson_Test.rb b/ruby/test/SwigJson_Test.rb index 77a59543541..d41545e7f58 100644 --- a/ruby/test/SwigJson_Test.rb +++ b/ruby/test/SwigJson_Test.rb @@ -55,4 +55,36 @@ def test_osargument_value_as_json assert_kind_of(String, val) assert_equal('handle1', val) end + + def test_swig_json_special_chars + workflow = OpenStudio::WorkflowJSON.new + runner = OpenStudio::Measure::OSRunner.new(workflow) + + step1 = OpenStudio::MeasureStep.new('MeasureName1') + step1.setArgument('Argument1', 100) + + workflow_step_result1 = OpenStudio::WorkflowStepResult.new + workflow_step_result1.setMeasureName('measure_name_1') + + name = "name_(|)'*$£*µ%é" + val = "val_(|)'*$£*µ%é" + stepValue1 = OpenStudio::WorkflowStepValue.new(name, val) + assert_equal(name, stepValue1.name) + assert_equal(val, stepValue1.valueAsString) + assert_equal(val, stepValue1.valueAsJSON) + workflow_step_result1.addStepValue(stepValue1) + + workflow_step_result1.setStepResult('Success'.to_StepResult) + workflow_step_result1.setCompletedAt(OpenStudio::DateTime.nowUTC) + step1.setResult(workflow_step_result1) + + workflow.setWorkflowSteps([step1]) + + # workflow.saveAs("OSRunner_getPastStepValues_special_chars.osw") + + h = runner.getPastStepValuesForMeasure('MeasureName1') + assert_equal(1, h.size) + assert_equal(name.to_sym, h.keys.first) + assert_equal(val, h.values.first) + end end diff --git a/src/utilities/core/jsoncpp.i b/src/utilities/core/jsoncpp.i index 5f57c61e54c..ab93cc82e1a 100644 --- a/src/utilities/core/jsoncpp.i +++ b/src/utilities/core/jsoncpp.i @@ -75,7 +75,19 @@ #endif #if defined SWIGRUBY -%fragment("JsonToDict","header", fragment="SWIG_FromCharPtrAndSize") { + +%fragment("", "header") %{ +#include +%} + +%fragment("string_to_ruby_utf8_symbol", "header", fragment="") { + SWIGINTERN VALUE SWIG_String_to_ruby_utf8_symbol(const std::string& str) { + return ID2SYM(rb_intern3(str.data(), str.size(), rb_utf8_encoding())); + } +} + +%fragment("JsonToDict", "header", fragment="SWIG_FromCharPtrAndSize", fragment="string_to_ruby_utf8_symbol") { + SWIGINTERN VALUE SWIG_From_JsonValue(const Json::Value& value) { switch(value.type()) { @@ -107,7 +119,10 @@ case Json::objectValue: { VALUE result = rb_hash_new(); for( const auto& id : value.getMemberNames()) { - rb_hash_aset(result, ID2SYM(rb_intern(id.data())), SWIG_From_JsonValue(value[id])); + rb_hash_aset(result, + SWIG_String_to_ruby_utf8_symbol(id), + SWIG_From_JsonValue(value[id]) + ); } return result; }