Module: Philiprehberger::Differ
- Defined in:
- lib/philiprehberger/differ.rb,
lib/philiprehberger/differ/change.rb,
lib/philiprehberger/differ/version.rb,
lib/philiprehberger/differ/changeset.rb,
lib/philiprehberger/differ/comparator.rb,
lib/philiprehberger/differ/formatters.rb,
lib/philiprehberger/differ/similarity.rb
Defined Under Namespace
Modules: Formatters, Similarity Classes: Change, Changeset, Comparator, Error
Constant Summary collapse
- VERSION =
'0.5.0'
Class Method Summary collapse
-
.breaking_changes?(changeset) ⇒ Boolean
Detect if a changeset contains breaking changes (removals or type changes).
- .diff(old_val, new_val, ignore: [], array_key: nil) ⇒ Object
-
.merge(base, theirs, ours) ⇒ Hash
Perform a three-way merge with conflict detection.
- .similarity(old_val, new_val, ignore: [], array_key: nil) ⇒ Object
-
.stats(changeset) ⇒ Hash{Symbol => Integer}
Structured count summary of a changeset.
-
.subset(changeset, path) ⇒ Changeset
Filter changeset to only changes under a specific path prefix.
Class Method Details
.breaking_changes?(changeset) ⇒ Boolean
Detect if a changeset contains breaking changes (removals or type changes)
88 89 90 91 92 93 |
# File 'lib/philiprehberger/differ.rb', line 88 def self.breaking_changes?(changeset) changeset.changes.any? do |change| change.type == :removed || (change.type == :changed && change.old_value.class != change.new_value.class) end end |
.diff(old_val, new_val, ignore: [], array_key: nil) ⇒ Object
14 15 16 17 |
# File 'lib/philiprehberger/differ.rb', line 14 def self.diff(old_val, new_val, ignore: [], array_key: nil) changes = Comparator.call(old_val, new_val, ignore: ignore, array_key: array_key) Changeset.new(changes) end |
.merge(base, theirs, ours) ⇒ Hash
Perform a three-way merge with conflict detection
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/philiprehberger/differ.rb', line 42 def self.merge(base, theirs, ours) their_changes = Comparator.call(base, theirs) our_changes = Comparator.call(base, ours) conflicts = detect_conflicts(their_changes, our_changes) conflict_paths = conflicts.map { |c| c[:path] } merged = deep_dup(base) (their_changes + our_changes).each do |change| next if conflict_paths.include?(change.path) apply_merge_change(merged, change) end { merged: merged, conflicts: conflicts } end |
.similarity(old_val, new_val, ignore: [], array_key: nil) ⇒ Object
19 20 21 |
# File 'lib/philiprehberger/differ.rb', line 19 def self.similarity(old_val, new_val, ignore: [], array_key: nil) Similarity.call(old_val, new_val, ignore: ignore, array_key: array_key) end |
.stats(changeset) ⇒ Hash{Symbol => Integer}
Structured count summary of a changeset.
Returns a hash of integer counts for the added, removed, and changed entries in the changeset, along with a running total and the number of unique paths. This method is read-only and never mutates the changeset.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/philiprehberger/differ.rb', line 68 def self.stats(changeset) raise ArgumentError, 'changeset must be a Philiprehberger::Differ::Changeset' unless changeset.is_a?(Changeset) added = changeset.added.length removed = changeset.removed.length changed = changeset.changed.length { added: added, removed: removed, changed: changed, total: added + removed + changed, paths: changeset.paths.length } end |
.subset(changeset, path) ⇒ Changeset
Filter changeset to only changes under a specific path prefix
28 29 30 31 32 33 34 |
# File 'lib/philiprehberger/differ.rb', line 28 def self.subset(changeset, path) prefix = path.to_s filtered = changeset.changes.select do |change| change.path.to_s == prefix || change.path.to_s.start_with?("#{prefix}.") end Changeset.new(filtered) end |