Giter VIP home page Giter VIP logo

Comments (20)

rcarriga avatar rcarriga commented on August 18, 2024 1

Funny enough I actually embedded https://github.com/manoelcampos/xml2lua inside the neotest libs with the idea of using it for code coverage but never got around to it. Can always use that ๐Ÿ˜… Just call require("neotest.lib").xml.parse(<xml string>)

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024 1

@boonkerz Does your code detect tests which use the @test annotation, as well as methods named test*?

From the PHPUnit documentation:

Alternatively, you can use the @test annotation in a methodโ€™s docblock to mark it as a test method.

source.

currently not but i work on this :)

from neotest.

olimorris avatar olimorris commented on August 18, 2024

I considered doing this after I completed the work on the RSpec adapter. Big challenge will be that PHPUnit outputs in xml only (never understood why they removed the JSON option in previous versions). Guessing you'd need to add a luarocks dependency to be able to process it.

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

currently i working on this but is my first try in lua :)

the message says no tests found but the logfile is showing somthing:

DEBUG | 2022-06-14T15:08:44Z+0200 | .../packer/start/neotest/lua/neotest/client/events/init.lua:48 | Calling listener diagnostic for event discover_positions
DEBUG | 2022-06-14T15:08:44Z+0200 | ...k/packer/start/neotest/lua/neotest/client/state/init.lua:54 | New positions at ID /home/thomas/projekte/calc/tests/PreCalc/ParseTest.php
INFO | 2022-06-14T15:08:44Z+0200 | .../packer/start/neotest/lua/neotest/client/events/init.lua:46 | Emitting discover_positions event
DEBUG | 2022-06-14T15:08:44Z+0200 | .../packer/start/neotest/lua/neotest/client/events/init.lua:48 | Calling listener status for event discover_positions
DEBUG | 2022-06-14T15:08:44Z+0200 | .../packer/start/neotest/lua/neotest/client/events/init.lua:48 | Calling listener summary for event discover_positions
DEBUG | 2022-06-14T15:08:44Z+0200 | .../packer/start/neotest/lua/neotest/client/events/init.lua:48 | Calling listener diagnostic for event discover_positions
DEBUG | 2022-06-14T15:08:44Z+0200 | ...k/packer/start/neotest/lua/neotest/client/state/init.lua:54 | New positions at ID /home/thomas/projekte/calc/tests/PreCalc/ParseVariantTest.php

my query:

(method_declaration
        name: (name) @test.name)
        @test.definition 
    
 (namespace_definition
        name: (namespace_name) @namespace.name)
        @namespace.definition

query is tested with https://tree-sitter.github.io/tree-sitter/playground

from neotest.

rcarriga avatar rcarriga commented on August 18, 2024

Can you provide the adapter code as well? I can't really tell much from the logs

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

very minimal

---@diagnostic disable: undefined-field
local lib = require('neotest.lib')
local logger = require('neotest.logging')

---@type neotest.Adapter
local adapter = { name = 'neotest-phpunit' }

adapter.root = lib.files.match_root_pattern('composer.json')

function adapter.is_test_file(file_path)
  return vim.endswith(file_path, "Test.php")
end

function adapter.build_spec(args)
  local results_path = vim.fn.tempname() .. '.json'
  local tree = args.tree
  if not tree then
    return
  end
  local pos = args.tree:data()
  local testNamePattern = '.*'
  if pos.type == 'test' then
    testNamePattern = pos.name
  end

  local binary = 'phpunit'
  if vim.fn.filereadable('vendor/bin/phpunit') then
    binary = 'vendor/bin/phpunit'
  end

  local command = vim.tbl_flatten({
    binary,
    pos.path,
  })
  return {
    command = command,
    context = {
      results_path = results_path,
      file = pos.path,
    },
  }
end

function adapter.discover_positions(path)
    local query = [[
    (method_declaration
        name: (name) @test.name)
        @test.definition 
    
    (namespace_definition
        name: (namespace_name) @namespace.name)
        @namespace.definition
    ]]
  return lib.treesitter.parse_positions(path, query, { nested_namespace = true })
end

setmetatable(adapter, {
  __call = function()
    return adapter
  end,
})

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

Current Status

image

from neotest.

rcarriga avatar rcarriga commented on August 18, 2024

Ah so it's working ๐Ÿ‘ I see you haven't parsed the class as Neotest's "namespace" type. The namespace in PHP is not really what Neotest means by namespace so the class would be more suitable

from neotest.

Geraint avatar Geraint commented on August 18, 2024

@boonkerz Does your code detect tests which use the @test annotation, as well as methods named test*?

From the PHPUnit documentation:

Alternatively, you can use the @test annotation in a methodโ€™s docblock to mark it as a test method.

source.

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

Ah so it's working +1 I see you haven't parsed the class as Neotest's "namespace" type. The namespace in PHP is not really what Neotest means by namespace so the class would be more suitable

yea currently happy does it do anything :)

my goal for the gui structure is the phpstorm version.
image

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

but the xml is stupid because the failure is only 1 blob of text with \n

 <testcase name="testNotO" class="PSC\Library\Calc\Tests\Complex\firstTest" classname="PSC.Library.Calc.Tests.Complex.firstTest" file="/home/thomas/projekte/phpunit_test/tests/Complex/firstTest.php" line="13" assertions="1" time="0.003164">
        <failure type="PHPUnit\Framework\ExpectationFailedException">PSC\Library\Calc\Tests\Complex\firstTest::testNotO
Failed asserting that true is false.

/home/thomas/projekte/phpunit_test/tests/Complex/firstTest.php:15</failure>
      </testcase>

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

so usable for me :D a little bit slow.

image

from neotest.

olimorris avatar olimorris commented on August 18, 2024

@boonkerz care to share your work so far?

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024
---@diagnostic disable: undefined-field
local lib = require('neotest.lib')
local logger = require('neotest.logging')
local async = require('neotest.async')
local adapter = { name = 'neotest-phpunit' }

adapter.root = lib.files.match_root_pattern('composer.json')

function adapter.is_test_file(file_path)
  if string.match(file_path, "vendor") then
      return false
  end
  return vim.endswith(file_path, "Test.php")
end

function adapter.build_spec(args)
  local results_path = vim.fn.tempname() .. '.xml'
  local tree = args.tree
  if not tree then
    return
  end
  local pos = args.tree:data()
  local testNamePattern = '.*'
  if pos.type == 'test' then
    testNamePattern = pos.name
  end

  local binary = 'phpunit'
  if vim.fn.filereadable('vendor/bin/phpunit') then
    binary = 'vendor/bin/phpunit'
  end

  local command = vim.tbl_flatten({
    binary,
    pos.path,
    '--log-junit='..results_path 
  })
  logger.error('phpunit_command', command)
  return {
    command = command,
    context = {
      results_path = results_path,
      file = pos.path,
    },
  }
end

function adapter.results(spec, result)
  local results = {}

  local success, data = pcall(lib.files.read, spec.context.results_path)

  if not success then
    results = "{}"
  end
  local parsedXml = lib.xml.parse(data)
  for _, containerSuite in pairs(parsedXml.testsuites) do
    for __, testsuite in pairs(containerSuite.testsuite) do
        for ___,testcase in pairs(testsuite.testcase) do
            local error = { message = "Error", line = 15 }
            local alias_id = ""
            if testcase['_attr'] then
                alias_id = testcase._attr.file .. '::' .. testcase._attr.name
            elseif testcase["name"] then
                alias_id = testcase.file .. '::' .. testcase.name
            end
            
            if not testcase["failure"] then
                results[alias_id] = { status = "passed", short = "", output = ""}
            else
                local fname = async.fn.tempname()
                vim.fn.writefile({testcase.failure[1]}, fname)
                results[alias_id] = { status = "failed", short = testcase.failure[1], output = fname, errors = {error} }
            end
        end
    end
  end
  return results
end

local function generate_position_id(position, namespaces)
    local id = table.concat(
        vim.tbl_flatten({
          position.path,
          position.name,
        }),
        "::"
    )   
    logger.error("generate_position_id", id)
    return id
end

function adapter.discover_positions(path)
    local query = [[
    (method_declaration
        name: (name) @test.name
        (#match? @test.name "test"))
        @test.definition

    (namespace_definition
        name: (namespace_name) @namespace.name)
        @namespace.definition
    ]]
  return lib.treesitter.parse_positions(path, query, { nested_namespace = true, position_id = generate_position_id })
end

setmetatable(adapter, {
  __call = function()
    return adapter
  end,
})

return adapter

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

currently i not know what errors in results array does.
dap integration and i love to see not the filenames in gui
run this file does also not work :)

@test works currently not because i not know how to make the query.

from neotest.

olimorris avatar olimorris commented on August 18, 2024

Any plans to put it in a repo? I'd like to work on the @test treesitter query.

from neotest.

Geraint avatar Geraint commented on August 18, 2024

I'm not sure if this will be helpful, but I post in the hope that it will be.

I notice that it's possible to pass the PHPUnit command a --list-tests-xml argument.

This identifies test methods with:

  • the test* method name prefix
  • the @test annotation.

It also identifies different test runs with @dataProvider data-sets (see documentation).

It does not include line numbers, though.

--list-tests-xml seems to need an output file, and you don't seem to be able to filter it by a particular file.

In contrast --list-tests outputs plain text to STDOUT, and you can limit it to a particular file.

from neotest.

boonkerz avatar boonkerz commented on August 18, 2024

link to repo https://github.com/boonkerz/neotest-phpunit

@Geraint thanks

from neotest.

olimorris avatar olimorris commented on August 18, 2024

I haven't heard anything more from @boonkerz on the development of this adapter so I've advanced it quite a bit, here. Would really appreciate people using it in anger and for any bugs they find, raising an issue with an example test I can work against

from neotest.

rcarriga avatar rcarriga commented on August 18, 2024

Since we now have a documented adapter, going to close this out.

from neotest.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.