Merge: libevent: support UNIX domain sockets and add a test and an example
authorJean Privat <jean@pryen.org>
Mon, 13 Aug 2018 19:24:43 +0000 (15:24 -0400)
committerJean Privat <jean@pryen.org>
Mon, 13 Aug 2018 19:24:43 +0000 (15:24 -0400)
Libevent server can now listen on UNIX domain sockets by calling `ConnectionFactory::bind_unix`. The method to listen on TCP ports was renamed to `bind_tcp` for clarity.

This PR intro two new supporting programs in the form of a parallel test for a libevent server and a minimal usage example. If we already had these let me know, because otherwise these two were long overdue.

This PR is built on the work of @matthmsl in #2708, thank you!

Close #2679

Pull-Request: #2726

lib/core/collection/abstract_collection.nit
lib/core/collection/union_find.nit
lib/core/kernel.nit
lib/perfect_hashing/perfect_hashing.nit
lib/trees/bintree.nit
src/testing/testing_doc.nit
tests/sav/nitunit_args1.res
tests/sav/nitunit_args6.res
tests/test_nitunit.nit

index 04dabfa..b51cd22 100644 (file)
@@ -396,6 +396,7 @@ interface SimpleCollection[E]
        fun add(item: E) is abstract
 
        # Add each item of `coll`.
+       #
        #     var a = [1,2]
        #     a.add_all([3..5])
        #     assert a.has(4)  == true
index b44b7f9..6c74ca2 100644 (file)
@@ -14,6 +14,7 @@ module union_find
 import hash_collection
 
 # Data structure to keeps track of elements partitioned into disjoint subsets
+#
 #     var s = new DisjointSet[Int]
 #     s.add(1)
 #     s.add(2)
@@ -139,6 +140,7 @@ class DisjointSet[E]
        end
 
        # Are all elements of `es` in the same subset?
+       #
        #     var s = new DisjointSet[Int]
        #     s.add_all([1,2,3,4,5,6])
        #     s.union_all([1,2,3])
index 45c3ccd..39a5958 100644 (file)
@@ -858,8 +858,11 @@ universal Int
 
        # Return the corresponding digit character
        # If 0 <= `self` <= 9, return the corresponding character.
+       #
        #     assert 5.to_c    == '5'
+       #
        # If 10 <= `self` <= 36, return the corresponding letter [a..z].
+       #
        #     assert 15.to_c   == 'f'
        fun to_c: Char
        do
index d8ab3cb..585130e 100644 (file)
@@ -101,6 +101,7 @@ class Perfecthashing
        # n : number of required free identifiers
        # idc : This array will be filled with n free identifiers
        # return the size of hashTable to create for theses identifiers (mask + 1)
+       #
        #     var ph = new Perfecthashing
        #     var idc = new Array[Int]
        #     assert ph.pnand([3, 7, 10], 1, idc) == 6
index 610ec2e..447a33f 100644 (file)
@@ -36,6 +36,7 @@ import abstract_tree
 #  * delete average O(lg n) worst O(n)
 #
 # Usage:
+#
 #     var tree = new BinTreeMap[Int, String]
 #     tree[1] = "n1"
 #     assert tree.min == "n1"
index a77a331..46f5a4a 100644 (file)
@@ -17,13 +17,12 @@ module testing_doc
 
 private import parser_util
 import testing_base
-import markdown
+import markdown2
 import html
 import realtime
 
 # Extractor, Executor and Reporter for the tests in a module
 class NitUnitExecutor
-       super HTMLDecorator
 
        # Toolcontext used to parse Nit code blocks.
        var toolcontext: ToolContext
@@ -40,12 +39,11 @@ class NitUnitExecutor
        # The name of the suite
        var name: String
 
-       # Markdown processor used to parse markdown comments and extract code.
-       var mdproc = new MarkdownProcessor
+       # Markdown parse used to parse markdown comments and extract code
+       private var md_parser = new MdParser
 
-       init do
-               mdproc.decorator = new NitunitDecorator(self)
-       end
+       # Markdown visitor used to extract markdown code blocks
+       private var md_visitor = new NitunitMdVisitor(self) is lazy
 
        # The associated documentation object
        var mdoc: nullable MDoc = null
@@ -58,8 +56,10 @@ class NitUnitExecutor
        # Is used because a new code-block might just be added to it.
        var last_docunit: nullable DocUnit = null
 
+       # Unit class name in XML output
        var xml_classname: String is noautoinit
 
+       # Unit name in xml output
        var xml_name: String is noautoinit
 
        # The entry point for a new `ndoc` node
@@ -73,17 +73,17 @@ class NitUnitExecutor
                self.mdoc = mdoc
 
                # Populate `blocks` from the markdown decorator
-               mdproc.process(mdoc.content.join("\n"))
+               var md_node = md_parser.parse(mdoc.content.join("\n"))
+               md_visitor.enter_visit(md_node)
        end
 
        # All extracted docunits
        var docunits = new Array[DocUnit]
 
-       fun show_status
-       do
-               toolcontext.show_unit_status(name, docunits)
-       end
+       # Display current testing status
+       fun show_status do toolcontext.show_unit_status(name, docunits)
 
+       # Update display when a test case is done
        fun mark_done(du: DocUnit)
        do
                du.is_done = true
@@ -274,6 +274,7 @@ class NitUnitExecutor
        # `file` should be a valid filepath for a Nit source file.
        private fun create_unitfile(file: String): Writer
        do
+               var mmodule = self.mmodule
                var dir = file.dirname
                if dir != "" then dir.mkdir
                var f
@@ -292,11 +293,12 @@ class NitUnitExecutor
        # Can terminate the program if the compiler is not found
        private fun compile_unitfile(file: String): Int
        do
+               var mmodule = self.mmodule
                var nitc = toolcontext.find_nitc
                var opts = new Array[String]
                if mmodule != null then
                        # FIXME playing this way with the include dir is not safe nor robust
-                       opts.add "-I {mmodule.filepath.dirname}"
+                       opts.add "-I {mmodule.filepath.as(not null).dirname}"
                end
                var cmd = "{nitc} --ignore-visibility --no-color -q '{file}' {opts.join(" ")} >'{file}.out1' 2>&1 </dev/null -o '{file}.bin'"
                var res = toolcontext.safe_exec(cmd)
@@ -343,17 +345,23 @@ class NitUnitExecutor
        end
 end
 
-private class NitunitDecorator
-       super HTMLDecorator
+private class NitunitMdVisitor
+       super MdVisitor
 
        var executor: NitUnitExecutor
 
-       redef fun add_code(v, block) do
-               var code = block.raw_content
-               var meta = block.meta or else "nit"
+       redef fun visit(node) do node.accept_nitunit(self)
+
+       fun parse_code(block: MdCodeBlock) do
+               var code = block.literal
+               if code == null then return
+
+               var meta = block.info or else "nit"
                # Do not try to test non-nit code.
                if meta != "nit" then return
+
                # Try to parse code blocks
+               var executor = self.executor
                var ast = executor.toolcontext.parse_something(code)
 
                var mdoc = executor.mdoc
@@ -364,12 +372,12 @@ private class NitunitDecorator
 
                # The location is computed according to the starts of the mdoc and the block
                # Note, the following assumes that all the comments of the mdoc are correctly aligned.
-               var loc = block.block.location
+               var loc = block.location
                var line_offset = loc.line_start + mdoc.location.line_start - 2
                var column_offset = loc.column_start + mdoc.location.column_start
                # Hack to handle precise location in blocks
                # TODO remove when markdown is more reliable
-               if block isa BlockFence then
+               if block isa MdFencedCodeBlock then
                        # Skip the starting fence
                        line_offset += 1
                else
@@ -423,8 +431,7 @@ private class NitunitDecorator
        end
 
        # Return and register a new empty docunit
-       fun new_docunit: DocUnit
-       do
+       fun new_docunit: DocUnit do
                var mdoc = executor.mdoc
                assert mdoc != null
 
@@ -442,6 +449,14 @@ private class NitunitDecorator
        end
 end
 
+redef class MdNode
+       private fun accept_nitunit(v: NitunitMdVisitor) do visit_all(v)
+end
+
+redef class MdCodeBlock
+       redef fun accept_nitunit(v) do v.parse_code(self)
+end
+
 # A unit-test extracted from some documentation.
 #
 # A docunit is extracted from the code-blocks of mdocs.
@@ -511,10 +526,13 @@ class DocUnit
        fun real_location(ast_location: Location): Location
        do
                var mdoc = self.mdoc
-               var res = new Location(mdoc.location.file, lines[ast_location.line_start-1],
+
+               var res = new Location(mdoc.location.file,
+                       lines[ast_location.line_start-1],
                        lines[ast_location.line_end-1],
                        columns[ast_location.line_start-1] + ast_location.column_start,
                        columns[ast_location.line_end-1] + ast_location.column_end)
+
                return res
        end
 
@@ -639,7 +657,7 @@ redef class ModelBuilder
        fun test_mdoc(mdoc: MDoc): HTMLTag
        do
                var ts = new HTMLTag("testsuite")
-               var file = mdoc.location.file.filename
+               var file = mdoc.location.file.as(not null).filename
 
                toolcontext.info("nitunit: doc-unit file {file}", 2)
 
index 1d1d69c..f1851ee 100644 (file)
@@ -1,17 +1,17 @@
 ==== Docunits of module test_nitunit::test_nitunit | tests: 5
 [OK] test_nitunit::test_nitunit
 [KO] test_nitunit$X
-     test_nitunit.nit:21,7--22,0: Runtime error in nitunit.out/test_nitunit-2.nit with argument 0
+     test_nitunit.nit:23,7--24,0: Runtime error in nitunit.out/test_nitunit-2.nit with argument 0
      Output
        Runtime error: Assert failed (nitunit.out/test_nitunit-2.nit:5)
 
 [KO] test_nitunit$X$foo
-     test_nitunit.nit:24,8--25,0: Compilation error in nitunit.out/test_nitunit-3.nit
+     test_nitunit.nit:27,8--28,0: Compilation error in nitunit.out/test_nitunit-3.nit
      Output
        nitunit.out/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
 
 [KO] test_nitunit$X$foo1
-     test_nitunit.nit:28,15: Syntax Error: unexpected operator '!'.
+     test_nitunit.nit:32,15: Syntax Error: unexpected operator '!'.
 [OK] test_nitunit$X$foo2
 
 ==== Test-suite of module test_test_nitunit::test_test_nitunit | tests: 3
index 30f2862..afcfb13 100644 (file)
@@ -5,7 +5,7 @@
        Runtime error: Assert failed (nitunit.out/test_nitunit3-0.nit:7)
 
 [KO] test_nitunit3>#2
-     test_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\].
+     test_nitunit3/README.md:8,3--5: Syntax Error: unexpected malformed character '\].
 
 ==== Docunits of module test_nitunit3::test_nitunit3 | tests: 1
 [OK] test_nitunit3::test_nitunit3
index e3b3301..64bc744 100644 (file)
 # limitations under the License.
 
 # a 'success' unit test (pass)
+#
 #     assert true
 module test_nitunit
 # a 'error' unit test (do not pass)
+#
 #     assert false
 class X
        # a 'failure' unit test (does not compile)
+       #
        #     assert undefined_identifier
        fun foo do end
 
        # a 'failure' unit test (does not parse)
+       #
        #     assert !@#$%^&*()
        fun foo1(a, b: Int) do end