From 4cfd581e97d8d9efa96dcf3b461efbb4345a2a6a Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 13 May 2024 22:45:28 +0200 Subject: [PATCH 1/4] ``` The following tests FAILED: 3705 - RubyTest-SwigJson_Test-swig_json_special_chars (Failed) 3870 - CLITest-SwigJson_Test-swig_json_special_chars (Failed) ``` --- python/test/test_swigjson.py | 32 ++++++++++++++++++++++++++++++++ ruby/test/SwigJson_Test.rb | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) 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 From d89233aaee1ba16fe6ef03929c800e5fbb309a03 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 13 May 2024 18:48:54 +0200 Subject: [PATCH 2/4] not working yet... --- src/utilities/core/CommonImport.i | 11 +++++++++++ src/utilities/core/jsoncpp.i | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/utilities/core/CommonImport.i b/src/utilities/core/CommonImport.i index 2004bde55b5..b35dae77900 100644 --- a/src/utilities/core/CommonImport.i +++ b/src/utilities/core/CommonImport.i @@ -11,6 +11,17 @@ #include #include #include + +#if defined SWIGRUBY + extern "C" { + #ifdef HAVE_RUBY_ENCODING_H + #include "ruby/encoding.h" + #endif + + rb_encoding *rb_utf8_encoding(void); + ID rb_intern3(const char *name, long len, rb_encoding *enc); + } +#endif %} %include diff --git a/src/utilities/core/jsoncpp.i b/src/utilities/core/jsoncpp.i index 5f57c61e54c..d5d288e40e9 100644 --- a/src/utilities/core/jsoncpp.i +++ b/src/utilities/core/jsoncpp.i @@ -75,7 +75,9 @@ #endif #if defined SWIGRUBY + %fragment("JsonToDict","header", fragment="SWIG_FromCharPtrAndSize") { + SWIGINTERN VALUE SWIG_From_JsonValue(const Json::Value& value) { switch(value.type()) { @@ -107,7 +109,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, + ID2SYM(rb_intern3(id.data(), id.size(), rb_utf8_encoding())), + SWIG_From_JsonValue(value[id]) + ); } return result; } From f36e7e57ef5e3dd690c996c048fab79f11bc332f Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 13 May 2024 21:51:42 +0200 Subject: [PATCH 3/4] Forward declaration works --- src/utilities/core/CommonImport.i | 11 ----------- src/utilities/core/jsoncpp.i | 9 +++++++++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/utilities/core/CommonImport.i b/src/utilities/core/CommonImport.i index b35dae77900..2004bde55b5 100644 --- a/src/utilities/core/CommonImport.i +++ b/src/utilities/core/CommonImport.i @@ -11,17 +11,6 @@ #include #include #include - -#if defined SWIGRUBY - extern "C" { - #ifdef HAVE_RUBY_ENCODING_H - #include "ruby/encoding.h" - #endif - - rb_encoding *rb_utf8_encoding(void); - ID rb_intern3(const char *name, long len, rb_encoding *enc); - } -#endif %} %include diff --git a/src/utilities/core/jsoncpp.i b/src/utilities/core/jsoncpp.i index d5d288e40e9..e5bce4ef2b3 100644 --- a/src/utilities/core/jsoncpp.i +++ b/src/utilities/core/jsoncpp.i @@ -78,6 +78,15 @@ %fragment("JsonToDict","header", fragment="SWIG_FromCharPtrAndSize") { + extern "C" { + struct OnigEncodingTypeST; + typedef struct OnigEncodingTypeST OnigEncodingType; + typedef const OnigEncodingType rb_encoding; + + rb_encoding *rb_utf8_encoding(void); + ID rb_intern3(const char *name, long len, rb_encoding *enc); + } + SWIGINTERN VALUE SWIG_From_JsonValue(const Json::Value& value) { switch(value.type()) { From fb533a2bbbf0992c85635dfb4a36e76f08db789d Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Mon, 13 May 2024 22:18:50 +0200 Subject: [PATCH 4/4] Solve it via fragments --- src/utilities/core/jsoncpp.i | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/utilities/core/jsoncpp.i b/src/utilities/core/jsoncpp.i index e5bce4ef2b3..ab93cc82e1a 100644 --- a/src/utilities/core/jsoncpp.i +++ b/src/utilities/core/jsoncpp.i @@ -76,16 +76,17 @@ #if defined SWIGRUBY -%fragment("JsonToDict","header", fragment="SWIG_FromCharPtrAndSize") { - - extern "C" { - struct OnigEncodingTypeST; - typedef struct OnigEncodingTypeST OnigEncodingType; - typedef const OnigEncodingType rb_encoding; +%fragment("", "header") %{ +#include +%} - rb_encoding *rb_utf8_encoding(void); - ID rb_intern3(const char *name, long len, rb_encoding *enc); +%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) { @@ -119,7 +120,7 @@ VALUE result = rb_hash_new(); for( const auto& id : value.getMemberNames()) { rb_hash_aset(result, - ID2SYM(rb_intern3(id.data(), id.size(), rb_utf8_encoding())), + SWIG_String_to_ruby_utf8_symbol(id), SWIG_From_JsonValue(value[id]) ); }