Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a way to elide diffs #91

Merged
merged 1 commit into from
May 13, 2021
Merged

Add a way to elide diffs #91

merged 1 commit into from
May 13, 2021

Commits on May 9, 2021

  1. Add a way to elide diffs

    When looking at a large diff for which many of the lines do not change,
    it can be difficult to locate the lines which do. Text-oriented
    diffs such as those you get from a conventional version control system
    solve this problem by removing those unchanged lines from the diff
    entirely. For instance, here is a section of the README with a line
    removed. Notice that only the part of the file we care about, which is
    around the line deleted, is displayed in the diff:
    
    ```
    diff --git a/README.md b/README.md
    index 56b046c..b38f4ca 100644
    --- a/README.md
    +++ b/README.md
    @@ -169,7 +169,6 @@ SuperDiff.configure do |config|
       config.add_extra_differ_class(YourDiffer)
       config.add_extra_operation_tree_builder_class(YourOperationTreeBuilder)
       config.add_extra_operation_tree_class(YourOperationTree)
    -  config.add_extra_diff_formatter_class(YourDiffFormatter)
     end
    ```
    
    This commit implements a similar feature for data-oriented diffs. It
    adds two new configuration options to allow you to control the elision
    logic:
    
    * `diff_elision_enabled` — The elision logic is disabled by default so
      as not to surprise people, so setting this to `true` will turn it on.
    * `diff_elision_maximum` — This number controls what happens to
       unchanged lines (i.e. lines that are neither "insert" lines nor
       "delete" lines) that are in between changed lines. If a section of
       unchanged lines is beyond this number, the gem will elide (a fancy
       word for remove) the data structures within that section as much as
       possible until the limit is reached or it cannot go further. Elided
       lines are replaced with a `# ...` marker.
    
    Here are a few examples:
    
    \### Elision enabled
    
    If you add this to your test helper:
    
    ``` ruby
    SuperDiff.configure do |config|
      config.diff_elision_enabled = true
    end
    ```
    
    And you have this test:
    
    ``` ruby
    expected = [
      "Afghanistan",
      "Aland Islands",
      "Albania",
      "American Samoa",
      "Andorra",
      "Angola",
      "Anguilla",
      "Antarctica",
      "Antigua And Barbuda",
      "Argentina",
      "Aruba",
      "Australia"
    ]
    actual = [
      "Afghanistan",
      "Aland Islands",
      "Algeria",
      "American Samoa",
      "Andorra",
      "Angola",
      "Anguilla",
      "Antarctica",
      "Antigua And Barbuda",
      "Armenia",
      "Aruba",
      "Australia"
    ]
    expect(actual).to eq(expected)
    ```
    
    Then you will get a diff that looks like:
    
    ```
      [
        # ...
    -   "Albania",
    +   "Algeria",
        # ...
    -   "Argentina",
    +   "Armenia",
        "Aruba",
        "Australia"
      ]
    ```
    
    \### Elision enabled and maximum specified
    
    Configuration:
    
    ``` ruby
    SuperDiff.configure do |config|
      config.diff_elision_enabled = true
      config.diff_elision_maximum = 5
    end
    ```
    
    Test:
    
    ```
    expected = [
      "Afghanistan",
      "Aland Islands",
      "Albania",
      "American Samoa",
      "Andorra",
      "Angola",
      "Anguilla",
      "Antarctica",
      "Antigua And Barbuda",
      "Argentina",
      "Aruba",
      "Australia"
    ]
    actual = [
      "Afghanistan",
      "Aland Islands",
      "Algeria",
      "American Samoa",
      "Andorra",
      "Angola",
      "Anguilla",
      "Antarctica",
      "Antigua And Barbuda",
      "Armenia",
      "Aruba",
      "Australia"
    ]
    expect(actual).to eq(expected)
    ```
    
    Resulting diff:
    
    ```
      [
        "Afghanistan",
        "Aland Islands",
    -   "Albania",
    +   "Algeria",
        "American Samoa",
        "Andorra",
        # ...
        "Antarctica",
        "Antigua And Barbuda",
    -   "Argentina",
    +   "Armenia",
        "Aruba",
        "Australia"
      ]
    ```
    
    \### Elision enabled and maximum specified, but indentation limits complete elision
    
    Configuration:
    
    ``` ruby
    SuperDiff.configure do |config|
      config.diff_elision_enabled = true
    end
    ```
    
    Test:
    
    ``` ruby
    expected = {
      foo: {
        bar: [
          "one",
          "two",
          "three"
        ],
        baz: "qux",
        fizz: "buzz",
        zing: "bing"
      }
    }
    actual = [
      foo: {
        bar: [
          "one",
          "two",
          "tree"
        ],
        baz: "qux",
        fizz: "buzz",
        zing: "bing"
      }
    ]
    expect(actual).to eq(expected)
    ```
    
    Resulting diff:
    
    ```
      {
        foo: {
          bar: [
            # ...
    -       "three"
    +       "tree"
          ],
          # ...
        }
      }
    ```
    
    Notice how we cannot fully elide all of the unchanged lines in this case
    because otherwise the diff would look like this and it wouldn't make
    sense:
    
    ```
      # ...
    -       "three"
    +       "tree"
      # ...
    ```
    mcmire committed May 9, 2021
    Configuration menu
    Copy the full SHA
    48a48b4 View commit details
    Browse the repository at this point in the history