summaryrefslogtreecommitdiff
path: root/vendor/oojs/oojs-ui/bin/doccomparer.rb
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/oojs/oojs-ui/bin/doccomparer.rb')
-rw-r--r--vendor/oojs/oojs-ui/bin/doccomparer.rb165
1 files changed, 165 insertions, 0 deletions
diff --git a/vendor/oojs/oojs-ui/bin/doccomparer.rb b/vendor/oojs/oojs-ui/bin/doccomparer.rb
new file mode 100644
index 00000000..cd3623df
--- /dev/null
+++ b/vendor/oojs/oojs-ui/bin/doccomparer.rb
@@ -0,0 +1,165 @@
+require 'pp'
+require_relative 'docparser'
+
+# convert [ {name: 'foo'}, … ] to { foo: {name: 'foo'}, … }
+def reindex arg
+ if arg.is_a?(Array) && arg.all?{|v| v.is_a? Hash }
+ Hash[ arg.map{|v| [ v[:name], reindex(v) ] } ]
+ elsif arg.is_a? Hash
+ arg.each_pair{|k, v| arg[k] = reindex(v) }
+ else
+ arg
+ end
+end
+
+def indent text, tabs
+ text == '' ? text : text.gsub(/^/, ' ' * tabs)
+end
+
+# whitespace-insensitive strings
+def canonicalize value
+ if value.is_a? String
+ value.strip.gsub(/\s+/, ' ')
+ elsif value.is_a? Array
+ value.map{|v| canonicalize v }
+ elsif value.is_a? Hash
+ value.each_pair{|k, v| value[k] = canonicalize v }
+ else
+ value
+ end
+end
+
+def sanitize_description text
+ cleanup_class_name(text)
+ .gsub('null and undefined', 'null')
+ .gsub('undefined and null', 'null')
+ .gsub('array()', '[]')
+ .gsub('jQuery|string|Function', 'string')
+ .gsub('jQuery', 'Tag')
+ .gsub('string|Function', 'string')
+ .gsub('object', 'array')
+ .gsub(/#(\w+)/, '\1()')
+ .gsub(/Object\.<.+?>/, 'array')
+end
+
+def smart_compare_process val, type
+ val[:description] = sanitize_description val[:description]
+
+ case type
+ when :class
+ val = val.dup
+ val[:mixins].delete 'OO.EventEmitter' # JS only
+ val[:mixins].delete 'PendingElement' # JS only
+ val.delete :parent if val[:parent] == 'ElementMixin' # PHP only
+ val.delete :methods
+ val.delete :properties
+ val.delete :events
+
+ when :method
+ if val[:name] == '#constructor'
+ val[:params].delete 'element' # PHP only
+ end
+ val[:config].each_pair{|_k, v|
+ default = v.delete :default
+ v[:description] << " (default: #{default})" if default
+ v[:description] = sanitize_description v[:description]
+ v[:type] = sanitize_description v[:type]
+ }
+ val[:params].each_pair{|_k, v|
+ default = v.delete :default
+ v[:description] << " (default: #{default})" if default
+ v[:description] = sanitize_description v[:description]
+ v[:type] = sanitize_description v[:type]
+ }
+ if val[:return]
+ val[:return][:description] = sanitize_description val[:return][:description]
+ val[:return][:type] = sanitize_description val[:return][:type]
+ end
+
+ when :property
+ val[:description] = sanitize_description val[:description]
+ val[:type] = sanitize_description val[:type]
+
+ end
+ val
+end
+
+def smart_compare a, b, a_name, b_name, type
+ a = smart_compare_process a, type
+ b = smart_compare_process b, type
+ compare_hash a, b, a_name, b_name
+end
+
+def smart_compare_methods a, b, a_name, b_name
+ smart_compare a, b, a_name, b_name, :method
+end
+
+def smart_compare_properties a, b, a_name, b_name
+ smart_compare a, b, a_name, b_name, :property
+end
+
+def compare_hash a, b, a_name, b_name, nested=:compare_hash
+ keys = (a ? a.keys : []) + (b ? b.keys : [])
+ out = keys.to_a.sort.uniq.map do |key|
+ a_val = a ? canonicalize(a[key]) : nil
+ b_val = b ? canonicalize(b[key]) : nil
+
+ if [a_val, b_val] == [{}, []] || [a_val, b_val] == [[], {}]
+ a_val, b_val = {}, {}
+ end
+
+ if a_val.is_a?(Hash) && b_val.is_a?(Hash)
+ comparison_result = indent method(nested).call(a_val, b_val, a_name, b_name), 2
+ if comparison_result.strip == ''
+ "#{key}: match" if $VERBOSE
+ else
+ "#{key}: MISMATCH\n#{comparison_result}"
+ end
+ else
+ if a_val == b_val
+ "#{key}: match" if $VERBOSE
+ elsif a_val.nil?
+ "#{key}: #{a_name} missing"
+ elsif b_val.nil?
+ "#{key}: #{b_name} missing"
+ else
+ "#{key}: MISMATCH\n #{a_name}: #{a_val.inspect}\n #{b_name}: #{b_val.inspect}"
+ end
+ end
+ end
+ out.compact.join "\n"
+end
+
+if ARGV.empty? || ARGV == ['-h'] || ARGV == ['--help']
+ $stderr.puts "usage: ruby [-v] #{$PROGRAM_NAME} <dirA> <dirB> <nameA> <nameB>"
+ $stderr.puts " ruby #{$PROGRAM_NAME} src php JS PHP > compare.txt"
+else
+ dir_a, dir_b, name_a, name_b = ARGV
+
+ js = parse_any_path dir_a
+ php = parse_any_path dir_b
+
+ js = reindex js
+ php = reindex php
+
+ (js.keys + php.keys).sort.uniq.each do |class_name|
+ where = [js.key?(class_name) ? name_a : nil, php.key?(class_name) ? name_b : nil].compact
+ puts "\n#{class_name}: #{where.join '/'}" if $VERBOSE || where.length == 2
+
+ if where.length == 2
+ data = {
+ 'Basic:' =>
+ smart_compare(js[class_name], php[class_name], name_a, name_b, :class),
+ 'Methods:' =>
+ compare_hash(js[class_name][:methods], php[class_name][:methods], name_a, name_b, :smart_compare_methods),
+ 'Properties:' =>
+ compare_hash(js[class_name][:properties], php[class_name][:properties], name_a, name_b, :smart_compare_properties),
+ }
+ data = data
+ .select{|_k, v| v != ''}
+ .map{|k, v| "#{k}\n#{indent v, 2}" }
+ .join("\n")
+ puts indent data, 2
+ end
+ end
+end