Module: Broadlistening::Compatibility

Defined in:
lib/broadlistening/compatibility.rb

Overview

Compatibility utilities for comparing outputs between Kouchou-AI (Python) and Broadlistening gem (Ruby) implementations.

Examples:

Compare two output files

report = Compatibility.compare_outputs(
  python_output: "path/to/python/result.json",
  ruby_output: "path/to/ruby/result.json"
)
puts report.summary

Validate output against schema

errors = Compatibility.validate_output(result_hash)

Defined Under Namespace

Classes: ComparisonReport

Constant Summary collapse

REQUIRED_TOP_LEVEL_KEYS =

Expected structure for hierarchical_result.json

%w[arguments clusters comments propertyMap translations overview config].freeze
REQUIRED_ARGUMENT_KEYS =
%w[arg_id argument comment_id x y cluster_ids].freeze
REQUIRED_CLUSTER_KEYS =
%w[level id label takeaway value parent].freeze
SCHEMA_PATH =

Path to JSON Schema file

File.expand_path("../../schema/hierarchical_result.json", __dir__)

Class Method Summary collapse

Class Method Details

.compare_outputs(python_output:, ruby_output:) ⇒ ComparisonReport

Compare outputs from Python and Ruby implementations

Parameters:

  • Path to JSON file or parsed hash

  • Path to JSON file or parsed hash

Returns:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/broadlistening/compatibility.rb', line 97

def compare_outputs(python_output:, ruby_output:)
  python_data = load_output(python_output)
  ruby_data = load_output(ruby_output)

  report = ComparisonReport.new
  report.python_stats = collect_stats(python_data)
  report.ruby_stats = collect_stats(ruby_data)

  compare_structure(python_data, ruby_data, report)
  compare_arguments(python_data, ruby_data, report)
  compare_clusters(python_data, ruby_data, report)
  compare_overview(python_data, ruby_data, report)

  report
end

.schemaHash

Get the JSON Schema as a Hash

Returns:

  • The JSON Schema



188
189
190
# File 'lib/broadlistening/compatibility.rb', line 188

def schema
  @schema ||= JSON.parse(File.read(SCHEMA_PATH))
end

.schema_pathString

Get the path to the JSON Schema file

Returns:

  • Path to schema file



195
196
197
# File 'lib/broadlistening/compatibility.rb', line 195

def schema_path
  SCHEMA_PATH
end

.valid_output?(output) ⇒ Boolean

Check if output is structurally compatible with Kouchou-AI format

Parameters:

  • Parsed output hash

Returns:



153
154
155
# File 'lib/broadlistening/compatibility.rb', line 153

def valid_output?(output)
  validate_output(output).empty?
end

.valid_schema?(output) ⇒ Boolean

Check if output is valid according to JSON Schema

Parameters:

  • Parsed output hash or path to JSON file

Returns:



181
182
183
# File 'lib/broadlistening/compatibility.rb', line 181

def valid_schema?(output)
  validate_with_schema(output).empty?
end

.validate_output(output) ⇒ Array<String>

Validate output structure

Parameters:

  • Parsed output hash

Returns:

  • List of validation errors



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/broadlistening/compatibility.rb', line 117

def validate_output(output)
  errors = []

  # Check top-level keys
  missing_keys = REQUIRED_TOP_LEVEL_KEYS - output.keys.map(&:to_s)
  errors << "Missing top-level keys: #{missing_keys.join(', ')}" if missing_keys.any?

  # Check arguments structure
  if output["arguments"] || output[:arguments]
    args = output["arguments"] || output[:arguments]
    if args.is_a?(Array) && args.any?
      sample = args.first
      sample_keys = sample.keys.map(&:to_s)
      missing_arg_keys = REQUIRED_ARGUMENT_KEYS - sample_keys
      errors << "Missing argument keys: #{missing_arg_keys.join(', ')}" if missing_arg_keys.any?
    end
  end

  # Check clusters structure
  if output["clusters"] || output[:clusters]
    clusters = output["clusters"] || output[:clusters]
    if clusters.is_a?(Array) && clusters.any?
      sample = clusters.first
      sample_keys = sample.keys.map(&:to_s)
      missing_cluster_keys = REQUIRED_CLUSTER_KEYS - sample_keys
      errors << "Missing cluster keys: #{missing_cluster_keys.join(', ')}" if missing_cluster_keys.any?
    end
  end

  errors
end

.validate_with_schema(output) ⇒ Array<Hash>

Validate output against JSON Schema

Parameters:

  • Parsed output hash or path to JSON file

Returns:

  • List of validation errors from JSON Schema



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/broadlistening/compatibility.rb', line 161

def validate_with_schema(output)
  data = output.is_a?(String) ? JSON.parse(File.read(output)) : output
  data = deep_stringify_keys(data) if data.is_a?(Hash)

  schema = JSONSchemer.schema(Pathname.new(SCHEMA_PATH))
  errors = schema.validate(data).to_a

  errors.map do |error|
    {
      path: error["data_pointer"],
      message: error["error"],
      details: error["details"] || {}
    }
  end
end