fredrikaverpil / neotest-golang

Reliable Neotest adapter for running Go tests in Neovim.
MIT License
133 stars 17 forks source link

feature: Color on the output #206

Closed jaymorelli96 closed 2 weeks ago

jaymorelli96 commented 3 weeks ago

Did you check docs and existing issues?

Is your feature request related to a problem? Please describe.

Hi, I don't think neotest-golang supports color in the output like neotest-go does. I would love to contribute but I may need a little help. If it does support how can I configure it?

Describe the solution you'd like to see.

This is the output of neotest-go: image

This is the output of neotest-golang: image

Describe alternatives you've considered.

I guess would be to do something similar of what neotest-go does in the output.

Additional context

No response

fredrikaverpil commented 3 weeks ago

Hi @jaymorelli96 👋 I haven't looked at how neotest-go does this, but if they do it I'm sure it's possible 😄

As long as this can be done reliably and without affecting performance too much, I'm open to accept a PR on this. 👍 Could be good to add a configuration option so to opt-out of this, in case of experiencing issues.

There are a couple of places you can implement this in, based on how you plan to do this. But I guess this is the file you want to look into first, which is responsible for processing the test output into neotest.Result format: https://github.com/fredrikaverpil/neotest-golang/blob/ea1c3a77f147e29583cd756b44ee69d9007bebba/lua/neotest-golang/process.lua

to_neotest_result

This function converts from the internal data structure onto Neotest's neotest.Result format, which is what is used and shown in/by Neotest: https://github.com/fredrikaverpil/neotest-golang/blob/ea1c3a77f147e29583cd756b44ee69d9007bebba/lua/neotest-golang/process.lua#L377-L397

This is basically the last touchpoint in the adapter before returning to Neotest. If you add a vim.notify(vim.inspect(neotest_result[pos_id])) here, you'll get:

{
  errors = {},
  output = "/var/folders/zp/9p20kb0s7n9chkhj9t3j7ymc0000gn/T/fredrik.fredrik/C2Z590/4",
  status = "passed"
}

This means that if the text in this file contains colors, this colorized text will be passed on to Neotest (and shown like in your screenshots).

decorate_with_go_test_results

Most likely, this is a better place to start working, as you can more easily identify any output related to an error and you can also see how I perform other regexps here.

https://github.com/fredrikaverpil/neotest-golang/blob/ea1c3a77f147e29583cd756b44ee69d9007bebba/lua/neotest-golang/process.lua#L282-L335

For example, you could use string.match so to try and find strings such as --- FAIL: and then colorize them.

It's the test_data.gotest_data.output which contains the test output.

fredrikaverpil commented 3 weeks ago

I might add that in order to avoid too much of a spaghetti bowl, you might want to introduce this as its own function, something like:

function M.aggregate_data(tree, gotest_output, golist_output)
  local res = M.gather_neotest_data_and_set_defaults(tree)
  res =
    M.decorate_with_go_package_and_test_name(res, gotest_output, golist_output)
  res = M.decorate_with_go_test_results(res, gotest_output)
+  if options.get().colorize_test_output == true then
+    res = M.colorize_go_test_results(res)
+  end
  return res
end

But it might be more performant to introduce this inside the loop we already iterate through:

function M.decorate_with_go_test_results(res, gotest_output)
+ local colorize = options.get().colorize_test_output
...
        if line.Action == "pass" then
          test_data.status = "passed"
        elseif line.Action == "fail" then
          test_data.status = "failed"
+        elseif line.Action == "output" and colorize then
+          test_data.gotest_data.output =
+            vim.list_extend(test_data.gotest_data.output, { colorize_go_test_results(line.Output) })
        elseif line.Action == "output" then
          test_data.gotest_data.output =
            vim.list_extend(test_data.gotest_data.output, { line.Output })
...
jaymorelli96 commented 3 weeks ago

Wow, that is an amazing help @fredrikaverpil 😄 I really appreciate the fast reply and all the help pointing me in the right direction! I gotta be honest I am not much familiar with lua, let alone creating a plugin, but i am very interested. I will spend the next few days to get a bit more comfortable with it and then I will start playing around with the implementation. As soon as I have some news I will let you know!

fredrikaverpil commented 3 weeks ago

Ok! 😊👍

jaymorelli96 commented 2 weeks ago

Hi @fredrikaverpil, only got time to start working on it this morning. Got to work!
image

I am doing inside the M.decorate_with_go_test_results and just doing a simple string match similar on how neotest-go is doing. I will clean up (create a function for it, set up the opts, and so on) a bit now. I just wanted you to know that I will be working on this a bit over the next few days

It is my first time playing around with lua and neovim plugin and I must say it is pretty fun 😄

fredrikaverpil commented 2 weeks ago

Fixed by #208