freenode/#lisp - IRC Chatlog
Search
17:33:47
dim
yeah, write the README first, as in how are the users going to benefit from any code you wirte
17:37:15
skidd0
Once i have a readme, i'll probably have a good idea of where to start with testing, too
17:47:06
pfdietz
I think fiveam, and then prove and stefil, are the most popular unit testing packages.
17:47:25
pfdietz
But automated testing includes automated test generation, which is a separate thing.
17:50:34
dim
what's hard for me with testing is choosing what to test in a way that makes the tests a good security to feel free to change the implementation while not adding useless work when changing your mind about some implementation choices
17:51:42
pfdietz
Well, you want to test through the public interface(s), which should be less likely to change. Failing that, test at the major internal interfaces, which also should be somewhat stable. Tiny unit tests of low level functions? Arguably not a good idea.
17:53:26
dim
yeah finding the proper boundaries where tests are going to be a net bonus... I'm not good at that
18:09:02
pjb
skidd0: first you have to decide what level of testing you want to do. https://yandex.com/collections/card/5aedac160265c1e2e48c40d5/
18:10:34
pjb
skidd0: in particular, unit-testing can require internal module knowledge and hooks. If the code is not designed to be tested, this will be the most difficult part to implement. On the other hand, if you do bottom-up programming in lisp, testing subexpressions in the repl, etc, it can be rather easy to just save the testing expression into a unit-test file.
18:11:04
pjb
skidd0: component testing should be rather easy and straighforward, unless you defined crazy APIs.
18:11:19
skidd0
i'm reading On Lisp currently to get a better understanding of the lang and bottom-up
18:11:33
pjb
skidd0: system integration testing may require more resources, since you may have to launch servers, test user interfaces, etc.
18:12:40
pfdietz
When evaluating your tests, coverage information is useful. sbcl lets you compile code with coverage enabled and then see which parts are executed by your tests. Anything not executed has not been tested.
18:13:17
pfdietz
Coverage is not a guarantee the tests are sufficient, but lack of coverage means they probably aren't.
18:14:00
pfdietz
I need to get back to work on my mutation testing framework, which is intended to test tests.
18:14:26
skidd0
so sbcl can be made aware of my testing setup (with a library), then report line coverage?
18:15:05
pfdietz
skidd0: if you explore various quicklisp systems, you will find many are sadly lacking in tests. Some are just dead though.
18:15:52
pfdietz
Line coverage requires support of some kind. In general tests just see if the program does the right thing; the tests have no hooks into the source code to do coverage themselves.
18:17:09
pfdietz
sbcl just lets your find out what parts of a program have been executed, line (or branch) by line. It doesn't care whether that execution was in a "test framework".
18:17:49
pfdietz
There's also a public domain implementation-independent coverage package, COVER (in quicklisp now). It has some drawbacks, though.
18:18:34
pjb
And yes, one difficulty with coverage, is to also test it with all implementations and combinations of features, so you're sure you've covered all #+/#- cases.
18:22:51
pjb
in that case you can #-your-implementation (error "~S not implemented yet for ~A" 'name-of-function (lisp-implementation-type))
18:40:54
skidd0
so for testing, i'd want to create a test/ dir with my tests that pulls in my library, and keep the library in it's own src/, right?
18:50:03
pjb
So I can (asdf:oos 'asdf:test-op :<system>) and it will compile and load the <system>.test and run the forms defined in it to run the test.
20:48:36
pjb
anamorphic: (define-condition example-condition (error) ()) #| --> example-condition |# (make-condition 'example-condition) #| --> #<example-condition #x30227DDBE9ED> |# (princ-to-string (make-condition 'example-condition)) #| --> "Error #<example-condition #x30227DE5E9CD>" |#
20:49:12
pjb
anamorphic: some conditions have a format-string and format-argument that they format when asked to be printed, like simple-error.
20:58:35
anamorphic
I see. Similarly for restarts, does one just princ them too and hope for something that makes sense to the user?
22:37:43
Bike
"If multiple iteration clauses are used to control iteration, variable initialization and stepping[1] occur sequentially by default. The and construct can be used to connect two or more iteration clauses when sequential binding and stepping[1] are not necessary. The iteration behavior of clauses joined by and is analogous to the behavior of the macro do with respect to do*. "
22:39:14
dim
I think my fav example of that are the following examples: (loop repeat 10 for a = 1 then b for b = 1 then (+ a b) collect a) and then (loop repeat 10 for a = 1 then b and b = 1 then (+ a b) collect a)
22:40:42
makomo
can anyone else try to indent the top-level form corresponding to this ONCE-ONLY definition https://gitlab.common-lisp.net/alexandria/alexandria/blob/master/macros.lisp#L58 and tell me if anything changes
22:41:13
makomo
and more specifically, regarding its behavior when indenting operators (MAPCAR in this case) that are unquoted
22:41:59
makomo
the 2nd and 3rd arguments to the MAPCAR on line 58 get shifted to the left, under "MAPCAR"
22:44:28
dim
I pushed a clean-up patch to the PR already, and now I'm seeing more that the github UI did hide from me before
22:45:13
dim
the (format nil (sql "some/file/in/the/source/tree/foo.sql") param param param ...) is my poor man's attempt at cl-yesql, because at the time it wasn't ready for this
22:46:41
phoe
sure - formatting queries this way is good as long as you don't care about SQL injections
22:47:05
phoe
and I think if you're doing pgloader, you usually trust your input and output and the pgloader itself.
22:47:07
dim
maybe I could introduce named arguments or stop relying so much on the format string facilities in my SQL templates and use something else instead, but I'm not sure about that
22:47:55
dim
SQL injection on Postgres with postmodern is a non issue, because it uses the parse/bind/execute query protocol
22:48:27
phoe
yes, but here we're creating raw SQL strings with FORMAT - normally that would be an issue
22:48:31
dim
you can't fool Postgres around with some parameters suddenly being interpreted as SQL statement when using parse/bind/execute, becase at PARSE time Postgres didn't receive the parameters yet
22:49:09
phoe
dim: or just create a macro-wrapper around DEFUN and FORMAT, something like (define-query-generator my-query (foo bar baz) "SELECT ~A FROM ~A JOIN ~A" foo bar baz)
22:49:10
dim
I went on with my usual answer without thinking about the exact use case I have under my eyes, not good :/
22:49:30
phoe
this would be a dumb way to create something like (defun my-query (foo bar baz) (format nil "
22:50:08
phoe
it's possible to write a poor man's yesql that uses flat files and FORMAT to create SQL strings
22:51:54
dim
I'm just thinking of doing (defun sql (url &rest args) (apply #'format nil (gethash url *fs*) args)) now
22:53:12
phoe
or use asdf:system-relative-pathname inside the function - I think you already do that
22:55:24
dim
I've been using a hash-table as a proxy for that, the key being an absolute pathname, here for the SQL queries it looks like (sql "/mysql/list-all-columns.sql")
22:55:56
dim
works well enough for my taste; I did that first with static assets for a website that ends up all being into the image, that's a nice delivery then
22:56:48
dim
Xach: https://github.com/dimitri/pgcharts/blob/master/src/resources.lisp might be useful for you then
22:58:55
Xach
still, for functions not directly under your control that expect to work with files/pathnames, would be fun to bundle files along with the image somehow.
22:59:10
dim
the derivative in pgloader is at https://github.com/dimitri/pgloader/blob/master/src/utils/queries.lisp ; same idea, different taste, specialized in load .sql files from the source tree
23:00:17
dim
well then you need to hack things more seriously so that open/close/file-position and many other things just work on top of your image based file system, right?
23:01:12
dim
maybe you can do a logicial pathname translation unit (or something, can't remember the proper terminology) and make it happen that way? I think pjb has implemented something AGPL for that
23:31:00
dim
(and I had to manually restart two builds that wouldn't pass the first time, no code changes, and pass the second time; Travis being unable to fetch some apt key or something again) (damn it)
3:00:19
beach
minion: memo for makomo: Yes, you are right, with SLIME-INDENTATION at least, the arguments of the first and third MAPCAR are indented differently.
3:17:20
pjb
beach: Hi! This article explains why being efficient is not rewarded: https://www.ribbonfarm.com/2009/10/07/the-gervais-principle-or-the-office-according-to-the-office/