Uniвсячина

понемножку о Linux и программировании

RSpec в 26 строк на Scheme

Развлекаюсь во всю с языком Scheme. Кто не знает, Scheme — это такой диалект Lisp’а. В настоящей момент более-менее дожили до наших лет только два диалекта: Common Lisp и Scheme. Common Lisp — большой динозавр на которого за 50 лет навешали дофига всего (включаю свою ОО-систему – CLOS). Scheme напротив, как элегантная лань, небольшой ядро примитивов, на основе которых реализуется все остальное. Предпоследний стандарт языка Scheme (R5RS) занимал всего порядка 50 страниц (сравните с тысячью страниц для стандарта C++).

Так вот, одно время было модно реализовывать популярный BDD-фреймворк RSpec, написанный на Ruby, на разных языках. Я решил сделать прототип на Scheme. Получилось кратко и элегантно. А возможно даже более гибко. Кстати без всякого ООП :)

(require-extension syntax-case)

(define-syntax desc
  (syntax-rules (it should)
    ((_ doc subject (it it-doc matcher ...) ...)
     (begin (display doc)
            (newline)
            (let ((it-value subject))
              (begin (display (string-append "  - " it-doc))
                     (if (and (matcher it-value) ...)
                         (display " (passed)")
                         (display " (failed)"))
                     (newline))
              ...)))))

(define-syntax should
  (syntax-rules ()
    ((_ predicate)
     (lambda (subject) (predicate subject)))
    ((_ predicate arg1 ...)
     (lambda (subject) (predicate subject arg1 ...)))))

(define-syntax should-not
  (syntax-rules ()
    ((_ predicate)
     (lambda (subject) (not (predicate subject))))
    ((_ predicate arg1 ...)
     (lambda (subject) (not (predicate subject arg1 ...))))))
;; определим собственный матчер
(define (good-number? n)
  (= n 5))

(desc "Given natural number"
      5
      (it "should be integer"
          (should integer?))
      (it "should be positive"
          (should positive?))
      (it "should be good number"
          (should good-number?))
      (it "should not be less than 0"
          (should-not < 0))
      (it "should not be inexact"
          (should-not inexact?)))

При запуске выводит на экран:

Given natural number
  - should be integer (passed)
  - should be positive (passed)
  - should be good number (passed)
  - should not be less than 0 (passed)
  - should not be inexact (passed)

Запускать на Chicken Scheme.

Comments