Giter Club home page Giter Club logo

speclj's Introduction

speclj

(pronounced "speckle" [spek-uhl])

It's a TDD/BDD framework for Clojure and Clojurescript, based on RSpec.

Speclj Build

Installation | Clojure | ClojureScript

Installation

Clojars Project

NOTE: Speclj 3.3+ requires Clojure 1.7+.

From Scratch

lein new speclj YOUR_PROJECT_NAME

@trptcolin's speclj template will generate all the files you need.

Or, if you're using ClojureScript:

lein new specljs YOUR_PROJECT_NAME

@ecmendenhall's specljs template will save you lots of time by getting you started with a running Clojure & ClojureScript setup.

Using Leiningen (2.0 or later)

Include speclj in your :dev profile :dependencies and:plugins. Then change the :test-paths to "spec"

; - snip
:dependencies [[org.clojure/clojure "1.11.3"]]
:profiles {:dev {:dependencies [[speclj "3.4.8"]]}}
:plugins [[speclj "3.4.8"]]
:test-paths ["spec"]

Manual installation

  1. Check out the source code: https://github.com/slagyr/speclj
  2. Install it:
$ clj -T:build install

Usage

Start with the speclj.core namespace. That is Speclj's API and it's very unlikely you'll need anything else.

Clojure

File Structure

All your speclj code should go into a directory named spec at the root of your project. Conventionally, the spec directory will mirror the src directory structure except that all the spec files will have the '_spec.clj' postfix.

| sample_project
|-- project.clj
|-- src
    |-- sample
        |-- core.clj
        | (All your other source code)
|-- spec
    |-- sample
        |-- core_spec.clj
       	| (All your other test code)

A Sample Spec File

Checkout this example spec file. It would be located at sample_project/spec/sample/core_spec.clj. Below we'll look at it piece by piece.

(ns sample.core-spec
  (:require [speclj.core :refer :all]
            [sample.core :refer :all]))

(describe "Truth"

  (it "is true"
    (should true))

  (it "is not false"
    (should-not false)))

(run-specs)

speclj.core namespace

Your spec files should :require the speclj.core in it's entirety. It's a clean namespace and you're likely going to use all the definitions within it. Don't forget to pull in the library that you're testing as well (sample.core in this case).

(require '[speclj.core :refer :all])
(require '[sample.core :refer :all])

describe

describe is the outermost container for specs. It takes a String name and any number of spec components.

(describe "Truth" ...)

it

it specifies a characteristic of the subject. This is where assertions go. Be sure to provide good names as the first parameter of it calls.

(it "is true" ...)

should and should-not

Assertions. All assertions begin with should. should and should-not are just two of the many assertions available. They both take expressions that they will check for truthy-ness and falsy-ness respectively.

(should ...)
(should-not ...)

run-specs

At the very end of the file is an invocation of (run-specs). This will invoke the specs and print a summary. When running a suite of specs, this call is benign.

(run-specs)

should Variants (Assertions)

There are many ways to make assertions. Check out the API Documentation. Take note of everything that starts with should.

Spec Components

it or characteristics are just one of several spec components allowed in a describe. Others like before, with, around, etc are helpful in keeping your specs clean and dry. The same API Documentation lists the spec component (everything that doesn't start with should).

Running Specs

With deps.edn

Add a spec alias to your deps.edn.

{
 :aliases {:spec  {:main-opts ["-m" "speclj.main" "-c"]
                   :extra-deps  {speclj/speclj {:mvn/version "3.4.8"}}
                   :extra-paths ["spec"]}}
 }

Run specs.

clj -M:spec     # printing dots
clj -M:spec -a  # auto running with doc output
clj -M:spec <OPTIONS>

With Leiningen

Speclj includes a Leiningen task.

$ lein spec <OPTIONS>

Using lein run

Speclj also includes a Clojure main namespace:

$ lein run -m speclj.main <OPTIONS>

As a Java command

And sometimes it's just easier to run a Java command, like from an IDE.

$ java -cp <...> speclj.main <OPTIONS>
$ java -cp `lein classpath` speclj.main

Autotest

The -a options invokes the "vigilant" auto-runner. This command will run all your specs, and then wait. When you save any test(ed) code, it will run all the affected specs, and wait again. It's HIGHLY recommended.

$ lein spec -a

Options

There are several options for the runners. Use the --help options to see them all.

$ lein spec --help

:eval-in

When using lein spec you can get a little faster startup by adding :speclj-eval-in :leiningen to your project map. It will prevent Leiningen from spinning up another Java process and instead run the specs in Leiningen's process. Use at your own risk.

ClojureScript

File Structure

All your speclj code should go into a a directory named spec at the root of your project. Conventionally, the spec directory will mirror the src directory structure except that all the spec files will have the '_spec.cljs' postfix.

| sample_project
|-- project.clj
|-- bin
    |-- speclj.js
|-- src
    |-- cljs
    	|-- sample
        	|-- core.cljs
        	| (All your other source code)
|-- spec
    |-- cljs
    	|-- sample
        	|-- core_spec.cljs
       		| (All your other test code)

1. Configure Your project.clj File

lein-cljsbuild is a Leiningen plugin that'll get you up and running with ClojureScript. You'll need to add a :cljsbuild configuration map to your project.clj.

:plugins [[lein-cljsbuild "1.0.3"]]
:cljsbuild {:builds        {:dev  {:source-paths ["src/cljs" "spec/cljs"]
                                   :compiler     {:output-to "path/to/compiled.js"}
                                   :notify-command ["phantomjs" "bin/speclj" "path/to/compiled.js"]}
                            :prod {:source-paths  ["src/cljs"]
                                   :compiler      {:output-to "path/to/prod.js"
                                                   :optimizations :simple}}}
            :test-commands {"test" ["phantomjs"  "bin/speclj" "path/to/compiled.js"]}}

Speclj works by operating on your compiled ClojureScript. The :notify-command will execute the bin/speclj command after your cljs is compiled. The bin/speclj command will use speclj to evaluate your compiled ClojureScript.

2. Create test runner executable

Create a file named speclj in your bin directory and copy the code below:

#! /usr/bin/env phantomjs

var fs = require("fs");
var p = require('webpage').create();
var sys = require('system');

p.onConsoleMessage = function (x) {
    fs.write("/dev/stdout", x, "w");
};

p.injectJs(phantom.args[0]);

var result = p.evaluate(function () {
  speclj.run.standard.arm();
  return speclj.run.standard.run_specs("color", true);
});

phantom.exit(result);

A Sample Spec File

Checkout this example spec file. It would be located at sample_project/spec/cljs/sample/core_spec.cljs. Below we'll look at it piece by piece.

(ns sample.core-spec
  (:require-macros [speclj.core :refer [describe it should should-not run-specs]])
  (:require [speclj.core]
            [sample.core :as my-core]))

(describe "Truth"

  (it "is true"
    (should true))

  (it "is not false"
    (should-not false)))

(run-specs)

speclj.core namespace

You'll need to :require-macros the speclj.core namespace and :refer each speclj test word that you want to use. In the example below, we are using describe, it, should, should-not, and run-spec. Yes, this is unfortunate, but unavoidable. If you wanted to use context you would simply add it to the current :refer collection. For a list of speclj test words go to the API Documentation

Your spec files must :require the speclj.core too, even though we don't alias it or refer anything. Don't forget this! It loads all the needed speclj namespaces. Also pull in the library that you're testing (sample.core in this case).

As a final note, when requiring your tested namespaces (sample.core in this case), you'll probabaly want to alias it using :as.

(:require-macros [speclj.core :refer [describe it should should-not run-specs])
(:require [speclj.core]
          [sample.core :as my-core]))

Running ClojureScript Specs

With Leiningen

$ lein cljs

Bash

The command below will start a process that will watch the source files and run specs for any updated files.

$ bin/speclj path/to/compiled.js

Code Coverage

Speclj integrated with Cloverage for all your code coverage needs. Make sure speclj 3.4.6 or above is included in the classpath and use Cloverage's --runner :speclj command line option.

Here's an example alias for your deps.edn.

{:aliases {:cov {:main-opts ["-m" "cloverage.coverage" "--runner" ":speclj" "-p" "src" "-s" "spec" ]
                 :extra-deps {cloverage/cloverage {:mvn/version "1.2.4"}
                              speclj/speclj {:mvn/version "3.4.8"}}}}}

Sadly, Cloverage doesn't offer a way to pass arguments to the runner (Speclj in this case). Speclj will use the standard runner and progress reporter by default. If you'd like different options, you can use the speclj.cloverage namespace as a model to create your own cloverage/speclj runner in your project.

Community

Contributing

Clone the master branch, build, and run all the tests:

$ git clone https://github.com/slagyr/speclj.git
$ cd speclj
$ clj -T:build javac
$ clj -M:test:spec

To make sure tests pass ClojureScript too, make sure you have npm:

npm install
clj -T:build clean
clj -M:test:cljs 

To include in a local project

clj -T:build clean
clj -T:build javac
clj -T:build jar

In deps.edn

{speclj/speclj {:local/root "/path/to/speclj/target/speclj-3.4.6.jar"}}

Make patches and submit them along with an issue (see below).

Issues

Post issues on the speclj github project:

Compatibility

  • Speclj 2.* requires Clojure 1.4.0+
  • Clojure 1.3 is not supported by any version of Speclj due to a bug in Clojure 1.3.

License

Copyright (C) 2010-2023 Micah Martin All Rights Reserved.

Distributed under the The MIT License.

speclj's People

Contributors

arlandism avatar atroche avatar batasrki avatar bmcgavin avatar brandoncorrea avatar crazysacx avatar damonkelley avatar danneu avatar donbonifacio avatar dudymas avatar edtsech avatar eyelidlessness avatar glenjamin avatar heybillfinn avatar jsuchy avatar kevbuchanan avatar mdwhatcott avatar mylesmegyesi avatar ndhoule avatar nilnor avatar pgr0ss avatar ryankinderman avatar sdegutis avatar skatenerd avatar slagyr avatar spadin avatar tjennings avatar trptcolin avatar yalh avatar zto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

speclj's Issues

Custom shoulds

RSpec has custom matchers, should speclj ease the creation of custom shoulds?

While working with clojure.core.matrix I encountered a custom == function in the operators namespace. Although I could do something like

(require '[clojure.core.matrix.operators :as mo])
(should-be (partial mo/== expected-form) actual-form)

The resulting output on failure is less descriptive than I'd hope.

I chose to simply make a new namespace, speclj.shoulds.matrix.core with the desired should-matrix== macro (I'm not psyched about the name I came up with but I couldn't think of anything better). This was not particularly hard since I basically copied the source code for should=. Nonetheless, I was unable to find a standard way to make custom shoulds or a well known place to put them. The following seem like decent ideas to me:

  • Guidelines for where to put custom shoulds so others can find and use them
  • Documentation on how to write custom shoulds
  • Macros or functions to make the definition of custom shoulds easier.

The last point is probably the most ambitious and I expect some would find it the least valuable. I didn't get anywhere (my macro-fu is less than guru-like) but my idea was something with a simple usage like:

(defshould= should-matrix== equals-function "some string following 'using: '")

Which would expand to the defmacro I wrote to define should-matrix==.

I'm very open to other ideas, criticisms or other thoughts about this issue. Does anyone else see any value in custom shoulds?

Spelling correction in config_spec

There's a small spelling error in the speclj/spec/config_spec.clj file. "Dynamically" is spelled "dynaimcally". This is my first open-source commit, so I'm not exactly sure if the pull request I sent also counts as an issue, so feel free to close this as a duplicate if so.

Need better workflow when writing many pending tests and using documentation-reporter

@slagyr

Usually I'll write all the pending tests I'll need right up front before starting a feature.

However, using the documentation-reporter, each pending test takes up 4 lines[a]. When I start working on one, the pending tests are printed after the failures. If there's enough pending tests, or I'm working on my laptop with a smaller screen, the pending tests easily push the failures way off the screen.

Here are the solutions I've thought of:

  1. show the name of the pending test in documentation-reporter, omitting the other 3 lines (this could be a command-line option).
  2. print failures results after pending tests.
  3. print pending tests before the rest of the tests, but this isn't a good idea because then I'll never see that I have pending tests.

Out of these, I think I like # 2 the best.

Thoughts?

[a]: one for the description, one for the pending-reason (even if not given), one for the file, and one for a space between them

Make it easier to provide your own reporter

I needed to create a custom reporter for a project I'm working on and found the constraint that that reporter needed to be in a namespace called "speclj.report.name" to be cumbersome and also make it more difficult to supply configuration information to my reporter.

Instead of specifying the report name, it would be nice to just hand in an object implementing speclj.reporting.Reporter.

I'm submitting a suggested implementation for this as a pull-request.

before-suite

In Rspec, you can set up code to run before or after the entire test suite is run, and it's usually here that you put database connections, etc. Is there a way of doing that with Speclj?

Tutorial on speclj.com needs updating

While the tutorial is well written, I've run into two problems so far. First, there's no mention in it of what's needed to work with leiningen 2. Since this info is already in the speclj README, that should be an easy fix.

Second, I just ran into an issue in trying to follow along with the "Decoupling Tests" page with lein2, clojure 1.4 and speclj 2.5.0. I'll probably attempt to debug it and figure out the proper way to do this in clojure 1.4, but this kind of problem with the tutorial is a huge turn-off when I'm flirting with using a new technology.

Consider using a different versioning mechanism

One of my users has reported a bug to me, #333. Basically Cursive cannot synchronise the speclj dependencies because the load-file in project.clj file requires the CWD to be set to the lein project directory. Since Cursive synchronises the dependencies fairly frequently (at every startup plus on several other occasions) we synchronise in-process by calling the Leiningen code directly. CounterClockwise also does the same, and I believe Nightcode does too although I'm not sure.

I need to add functionality to Cursive to be able to sync the dependencies by forking an external process, but that will make this operation much, much slower when working with the speclj source code. I know there are various plugins for managing dependencies in project.clj, would one of them work as an alternative to using load-file directly?

Readme should mention incompatibility with Clojure 1.3

Since Clojure 1.3 seems to be the default with the current version of Leiningen, and a lot of people, especially newbs (like me) are probably using that, the readme should probably mention up front that it requires Clojure 1.4 or 1.2 and doesn't work with 1.3. It wasn't hard to figure out since there's an issue for it that explains everything, but the readme still references speclj v 1.2 and makes no mention the Clojure 1.3 issues.

Seems like someone new to things should be able to use the Readme with common defaults and get a working spec.

I'll see about making the updates and issuing a pull request if I end up with something that reads well.

Provide installation instructions for specljs

Hi, there are two blog posts complaining about installing Specljs being difficult: one mentions "hours of wasted time" while another calls it "the most difficult setup I had done". The readme currently has no install instructions and barely mentions Specljs or ClojureScript at all, making me think I was looking at the wrong repo. As a ClojureScript user coming across this project for the first time, I'm interested in trying it, but we're not off to a great start. At least an up-front acknowledgement that "yes, there's a version called Specljs that works with ClojureScript, too", plus some pointers to setup info, would make this project much more accessible.

consider using standard exception type for assertion failures

Thanks for building this! What are your thoughts on making should= et al. throw the standard exception type AssertionError, rather than your own? It seems like that would facilitate writing interchangeable assertion libraries that work with speclj.

Specs in Do Blocks

The following succeeds:

(describe "counterintuitive"
  (do
    (it "foo"
      (should= 1 2))
    (it "bar"
      (should= 1 1)))

This can have counterintuitive implications when you write tests inside of a let, for example.

I suspect this has to do with the nature of the macro being used. Is it possible to make the first test run, or at least issue a warning?

Define some GitHub labels

In my projects, I tend to use labels to differentiate bugs from suggestions, and perhaps to link issues to specific releases. I also like to have an "in progress" label. That's cheap and easy feedback for your end users.

Typo in tutorial site

Hello,

http://speclj.com/tutorial/step4

In Step 4 of your speclj tutorial, you speak of adding the main project's namespace into the namespace declaration in the core spec file. However the figure you use to describe this is actually missing the main project's namespace declaration and this might be confusing to readers.

As it appears:

(ns change-counter.core-spec
  (:require [speclj.core :refer :all]))

How I believe it should appear:

(ns change-counter.core-spec
  (:require [speclj.core :refer :all]
            [change-counter.core :refer :all]))

I could not find a feedback form so I figured this would be the best way to contact you.

Thanks.

ns errors sometimes missing file/line info

In speclj 2.7.2, given lein new speclj foobar and this implementation:

(ns foobar.core
  (:require [clojure.core :refer [ohai]]))

The lein spec error works fine for me (includes the stacktrace), but the autorunner, lein spec -a, should have more detail to help me track down the error:

----- Thu May 16 13:37:52 CDT 2013 -------------------------------------------------------------------
took 0.21027 to determine file statuses.
reloading files:
  /private/tmp/foobar/spec/foobar/core_spec.clj
java.lang.IllegalAccessError: ohai does not exist

Speclj doesn't re-re-run all test files when there's an exception in between them

Quoting @mylesmegyesi on this:

I have three files:

one.clj
two.clj
three.clj
one.clj and two.clj depend on a function in three.clj

When I delete the function in three.clj, Speclj detects the change and attempts to reload all three files. Speclj encounters an exeception when trying to load one.clj because it's dependency no longer exists. I fix the problem in one.clj. Speclj reloads one.clj and tests pass. However, Speclj did NOT try and reload two.clj again, even though it is still broken. Then I'm forced to restart the test suite to find all errors cause by deleting the function in three.clj.

My proposal for a fix:

Maybe Speclj can keep track of which test files it has to re-run, and it can remove them from this list when it successfully runs them. That way if it doesn't run one because of an exception, then it'll still have record of this for later, and when any file is fixed, it'll try to re-run any still in this list.

Readme Fix For ClojureScript

In your Readme, under the ClojureScript heading, when discussing changes to project.clj, I would encourage you to explain that specljs has to be added as a plugin, something like :

 :plugins [[speclj "2.5.0"]
          [specljs "2.7.4"]]

Such a note would have saved me a lot of time -- about 4 hours. I know it must seem really obvious to you, but to a newbie such as myself, given the surrounding wording, it isn't obvious. :-)

BTW, even the unofficial specljs lein template don't get this right either which compounded the confusion from my point of view.

Unsupported major.minor version 51.0

full stack trace here:

$ lein spec   
Exception in thread "main" java.lang.UnsupportedClassVersionError: speclj/main : Unsupported major.minor version 51.0
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

my leiningen and java version:

$ lein version
Leiningen 2.1.2 on Java 1.6.0_45 Java HotSpot(TM) 64-Bit Server VM

The only thing I can come up with is from this other issue mmcgrana/clj-json#23

Run all tests while in autorunner

It would be nice to be able to re-run all the tests from within the auto runner. For example, pressing "Enter" would force the whole test suite to be run again. Right now, I have to stop the auto runner and restart it to run all the tests, which can be cumbersome.

Automatically running tests fails with namespace not found error

When running tests automatically with "lein spec -a", the tests sometimes fail to run with an error like this:

java.lang.Exception: namespace 'myproject.foo-bar' not found after loading '/myproject/foo_bar'
    ... 9 stack levels elided ...
    at myproject.baz$eval3504$loading__4784__auto____3505.invoke(baz.clj:1)
    [...]

This only happens occasionally on reload and never happens with a plain "lein spec"

lein spec -a is broken in 1.5.0

When I run lein spec -a in speclj 1.5.0, I get the following error:

java.lang.IllegalArgumentException: No implementation of method: :report-message of protocol: #'speclj.reporting/Reporter found for class: clojure.lang.LazySeq
        ... 3 stack levels elided ...
        at fresh.core$make_fresh.invoke(core.clj:188)
        at fresh.core$freshener$fn__714.invoke(core.clj:209)
        ... 18 stack levels elided ...

It works fine with 1.4.0.

How do you test preconditions?

I did (should-throw Exception (something-with-failing-precondition)) and amidst the speclj output, there's a message about an Assert failure.

Failed file always says platform.clj

Every failed test now says that it failed here:

file:/Users/sdegutis/.m2/repository/speclj/speclj/3.0.0/speclj-3.0.0.jar!/speclj/platform.clj:40

use pprint

When big-ish hashes turn out to not be the same, it's hard to see the difference. I find myself doing (pprint result) before should= in these cases. How about just use pprint instead within should=?

with!

Like with but evaluates immediately.

Stacktrace issue

Speclj hides important stacktrace information when the project name starts with clojure.

lein task doesn't use JVM opts

I always use speclj in this manner

lein spec -a

but I am not sure how to set jvm options with leiningen so that speclj can use them. My project.clj file has :jvm-opts ["-Xms256m" "-Xmx2g"], but that doesn't seen to affect how leiningen sets up the REPL.

Can't disable color when running speclj from lein spec task

Speclj doesn't allow the color to be disabled for either terms that don't support it or for outputting to file.

While there are specs to show it's possible to turn off, in practice there is a line in the spec task (line 56 of src/leiningen/spec.clj ) to:

(cons "-c" args)

which essentially defaults color to be on all the time.

I'm going to submit a pull request today for a proposed fix. See if you like the changes, or perhaps we can propose a more effective way to supply defaults to the task.

Easy way to set color and reporter for use in IDE

I don't run the tests much from the command line, I do it from inside IDEA (using the Cursive plugin). It does a fine job with the ANSI colored text, so there's no reason to default that off ... but I end up having to repeat (run-spec :color true) in each namespace. The default for the :color option, when not specified, should come from a configuration file, or from a JVM system property.

"ReferenceError: Can't find variable: specljs"

I get this error when trying to use specljs with cljsbuild 2.7.4:

SyntaxError: Parse error

ReferenceError: Can't find variable: specljs

  phantomjs://webpage.evaluate():2
  phantomjs://webpage.evaluate():6
  phantomjs://webpage.evaluate():6

This is the test runner:

var fs = require("fs");
var p = require('webpage').create();
var sys = require('system');

p.onConsoleMessage = function (x) {
    fs.write("/dev/stdout", x, "w");
};

p.injectJs(phantom.args[0]);

var result = p.evaluate(function () {
  specljs.run.standard.armed = true;
  return specljs.run.standard.run_specs(
     cljs.core.keyword("color"), true
  );
});

phantom.exit(result);

And this is the actual test cljs file:

(ns input-frontend.core-test
  (:require specljs.core
            [input-frontend.core :refer []])
  (:require-macros [specljs.core :refer [describe it should]]))

(describe "Does it work?"
          (it "tests if testing tests."
              (should true)))

I'm using an html-file to load the javascript dependencies and finally the compiled clojurescript file.

CompilerException java.lang.ClassNotFoundException: speclj.components with a new speclj project

Hi - seem to be having a similar issue to https://groups.google.com/forum/#!topic/speclj/S15jYyiTXgs

$ lein new speclj test
Generating a project called test based on the 'speclj' template.
$ cd test
$ lein repl
user=> (require '[speclj.core :refer :all])
nil
user=> (describe "x")

CompilerException java.lang.ClassNotFoundException: speclj.components, compiling:(/private/var/folders/bw/jvjjhp554nv9mbsmq9dzqvm40000gp/T/form-init6459616970337226081.clj:1:1) 

Reverting to 2.6.1 solves the problem.

Any ideas / suggestions?

Can't run Lein Spec. Unable to resolve symbol: file i n this context (spec.clj:16)

I'm simply trying to run some tests and lein spec is failing with speclj.
Here is the beginning of a very long stack trace. (Let me know if you need more).

Exception in thread "main" java.lang.Exception: Unable to resolve symbol: file i
n this context (spec.clj:16)
at clojure.lang.Compiler.analyze(Compiler.java:5206)
at clojure.lang.Compiler.analyze(Compiler.java:5152)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3037)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:5372)
at clojure.lang.Compiler.analyze(Compiler.java:5191)
at clojure.lang.Compiler.analyze(Compiler.java:5152)
at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:831)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:5370)
at clojure.lang.Compiler.analyze(Compiler.java:5191)......................... ...

A little more information, I'm running this on an ARM based computer using the OpenJDK that comes with Ubuntu.

Thanks!

Support templates for defining examples

I'd like to be able to do the following:

    (do-template [key expected]
                 (it (format "should have the correct value for %s" key)
                     (should= expected (key @asset)

                              :resource-path "META-INF/assets/coffeescript-source.coffee"
                              :asset-path "coffeescript-source.coffee"
                              :content-type "text/javascript"
                              :compiled true
                              :size 160
                              :checksum compiled-coffeescript-checksum)))

That is, easily generate a series of examples (it blocks) from templates. Currently, when I do that:

clojure.lang.Compiler$CompilerException: java.lang.Exception: Oops!  It looks like you tried to add 'nil' to a spec.  That's not allowed., compiling:(/Users/hlship/workspaces/annadale/twixt/spec/io/aviso/twixt_spec.clj:55:48)
                    java.lang.Exception: Oops!  It looks like you tried to add 'nil' to a spec.  That's not allowed.
clojure.lang.Compiler$CompilerException: java.lang.Exception: Oops!  It looks like you tried to add 'nil' to a spec.  That's not allowed., compiling:(/Users/hlship/workspaces/annadale/twixt/spec/io/aviso/twixt_spec.clj:55:48)
                    java.lang.Exception: Oops!  It looks like you tried to add 'nil' to a spec.  That's not allowed.
                                             speclj.components/eval2529/fn                    components.clj:   11
                                           speclj.components/eval2496/fn/G                    components.clj:    3
                                       io.aviso.twixt-spec/eval17951/fn/fn                    twixt_spec.clj:   92
                                          io.aviso.twixt-spec/eval17951/fn                    twixt_spec.clj:   92
                                             io.aviso.twixt-spec/eval17951                    twixt_spec.clj:   57
                                                clojure.lang.Compiler.eval                     Compiler.java: 6703
                                                clojure.lang.Compiler.load                     Compiler.java: 7130
                                             io.aviso.twixt-spec/eval17934  form-init1321303564594210912.clj:    1
                                                clojure.lang.Compiler.eval                     Compiler.java: 6703
                                                clojure.lang.Compiler.eval                     Compiler.java: 6666
                                                         clojure.core/eval                          core.clj: 2927
                                      clojure.main/repl/read-eval-print/fn                          main.clj:  239
                                         clojure.main/repl/read-eval-print                          main.clj:  239
                                                      clojure.main/repl/fn                          main.clj:  257
                                                         clojure.main/repl                          main.clj:  257
                                                clojure.lang.RestFn.invoke                       RestFn.java: 1096
             clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn            interruptible_eval.clj:   56
                                            clojure.lang.AFn.applyToHelper                          AFn.java:  152
                                                  clojure.lang.AFn.applyTo                          AFn.java:  144
                                                        clojure.core/apply                          core.clj:  624
                                               clojure.core/with-bindings*                          core.clj: 1862
                                                clojure.lang.RestFn.invoke                       RestFn.java:  425
                clojure.tools.nrepl.middleware.interruptible-eval/evaluate            interruptible_eval.clj:   41
clojure.tools.nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn            interruptible_eval.clj:  171
                                                      clojure.core/comp/fn                          core.clj: 2402
             clojure.tools.nrepl.middleware.interruptible-eval/run-next/fn            interruptible_eval.clj:  138
                                                      clojure.lang.AFn.run                          AFn.java:   22
                         java.util.concurrent.ThreadPoolExecutor.runWorker           ThreadPoolExecutor.java: 1145
                        java.util.concurrent.ThreadPoolExecutor$Worker.run           ThreadPoolExecutor.java:  615
                                                      java.lang.Thread.run                       Thread.java:  724

I'm not quite sure where the nil is coming from.

Issue with the website

The documentation is not showing everything anymore. Problem just started in the past day or two.

lein 2 preview 10 fails

Looks like some new incompability

$ lein spec
WARNING: using numeric exit values in plugins is deprecated.                                                           
Plugins should use leiningen.core.main/abort instead.                                                                  
Support for this will be removed before the stable 2.0.0 release.                                                      
spec failed.                                                       

Running tests in the leiningen process subverts dependencies

The :eval-in :leiningen change introduced by #67 is subtly dangerous as a default setting.

In particular:

  • the version of clojure being used will be set to whatever leiningen happens to use, regardless of what the user wants for their own project
  • the versions of other dependencies can change if any plugins depend on different versions of those dependencies, and this will not be reported by tasks like lein deps :tree.

This second issue has already resulted in hours of spooky debugging at work (and the details of the libraries involved are reproduced in this skeleton project).

As Phil noted in a comment on the original PR, it takes one line for a user to opt-in to this feature if they want it.

Broken for Clojure 1.3.0 projects

This is due to Clojure 1.3.0 Release Feature 1.1: Earmuffed Vars Are No Longer Automatically Considered Dynamic.

https://github.com/clojure/clojure/blob/master/changes.md

I get the following stacktrace when running lein spec for Clojure 1.3.0:

Warning: *reporters* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *reporters* or change the name.
Warning: *runner* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *runner* or change the name.
Warning: *specs* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *specs* or change the name.
Warning: *color?* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *color?* or change the name.
Warning: *full-stack-trace?* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *full-stack-trace?* or change the name.
Warning: *tag-filter* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *tag-filter* or change the name.
Exception in thread "main" java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: speclj.config/*runner*
    at clojure.lang.Var.pushThreadBindings(Var.java:339)
    at clojure.core$push_thread_bindings.invoke(core.clj:1716)
    at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1767)
    at clojure.lang.RestFn.invoke(RestFn.java:425)
    at speclj.main$do_specs.invoke(main.clj:88)
    at speclj.main$run.doInvoke(main.clj:103)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:600)
    at speclj.main$_main.doInvoke(main.clj:106)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:401)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:518)
    at clojure.core$apply.invoke(core.clj:600)
    at clojure.lang.Var.invoke(Var.java:405)
    at speclj.main.main(main.java:13)

lein spec crashes when exposed to core.cache?

Not sure if this should be reported here or on luminus-template, but I can't seem to resolve it... when running this test:

(ns hedgehog.handler-spec
  (:require [speclj.core :refer :all]
            [ring.mock.request :refer :all]
            [hedgehog.handler :refer :all]))

(describe "main-route"
   (it "should return a 200 status"
       (let [response (app (request :get "/"))]
            (should= (:status response) 200))))


(run-specs)

This stacktrace is produced:

Errors:

  1) java.lang.ExceptionInInitializerError
     java.lang.ExceptionInInitializerError
        ... 18 stack levels elided ...
        at ring.middleware.format$loading__4910__auto__.invoke(format.clj:1)
        at ring.middleware.format__init.load(Unknown Source)
        at ring.middleware.format__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at noir.util.middleware$loading__4910__auto__.invoke(middleware.clj:1)
        at noir.util.middleware__init.load(Unknown Source)
        at noir.util.middleware__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at hedgehog.handler$loading__4910__auto__.invoke(handler.clj:1)
        at hedgehog.handler__init.load(Unknown Source)
        at hedgehog.handler__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at hedgehog.handler_spec$eval684$loading__4910__auto____685.invoke(/Users/jason/estuary/hedgehog/spec/hedgehog/handler_spec.clj:1)
        at hedgehog.handler_spec$eval684.invoke(/Users/jason/estuary/hedgehog/spec/hedgehog/handler_spec.clj:1)
        ... 17 stack levels elided ...
        at user$eval676.invoke(NO_SOURCE_FILE)
        ... 4 stack levels elided ...
        at leiningen.core.eval$fn__3577.invoke(eval.clj:304)
        ... 1 stack levels elided ...
        at leiningen.core.eval$eval_in_project.invoke(eval.clj:326)
        at leiningen.spec$spec.doInvoke(spec.clj:36)
        ... 5 stack levels elided ...
        at leiningen.core.main$resolve_task$fn__3029.doInvoke(main.clj:189)
        ... 6 stack levels elided ...
        at leiningen.core.main$apply_task.invoke(main.clj:230)
        at lein_environ.plugin$write_env_to_file.invoke(plugin.clj:11)
        ... 4 stack levels elided ...
        at robert.hooke$compose_hooks$fn__8655.doInvoke(hooke.clj:40)
        ... 2 stack levels elided ...
        at robert.hooke$run_hooks.invoke(hooke.clj:46)
        at robert.hooke$prepare_for_hooks$fn__8660$fn__8661.doInvoke(hooke.clj:54)
        ... 3 stack levels elided ...
        at leiningen.core.main$resolve_and_apply.invoke(main.clj:234)
        at leiningen.core.main$_main$fn__3092.invoke(main.clj:303)
        at leiningen.core.main$_main.doInvoke(main.clj:290)
        ... 12 stack levels elided ...
     Caused by: java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core.cache/through
        ... 9 stack levels elided ...
        at ring.middleware.format_response$make_encoder.invoke(format_response.clj:94)
        at ring.middleware.format_response__init.load(Unknown Source)
        at ring.middleware.format_response__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at ring.middleware.format$loading__4910__auto__.invoke(format.clj:1)
        at ring.middleware.format__init.load(Unknown Source)
        at ring.middleware.format__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at noir.util.middleware$loading__4910__auto__.invoke(middleware.clj:1)
        at noir.util.middleware__init.load(Unknown Source)
        at noir.util.middleware__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at hedgehog.handler$loading__4910__auto__.invoke(handler.clj:1)
        at hedgehog.handler__init.load(Unknown Source)
        at hedgehog.handler__init.<clinit>(Unknown Source)
        ... 18 stack levels elided ...
        at hedgehog.handler_spec$eval684$loading__4910__auto____685.invoke(/Users/jason/estuary/hedgehog/spec/hedgehog/handler_spec.clj:1)
        at hedgehog.handler_spec$eval684.invoke(/Users/jason/estuary/hedgehog/spec/hedgehog/handler_spec.clj:1)
        ... 17 stack levels elided ...
        at user$eval676.invoke(NO_SOURCE_FILE)
        ... 4 stack levels elided ...
        at leiningen.core.eval$fn__3577.invoke(eval.clj:304)
        ... 1 stack levels elided ...
        at leiningen.core.eval$eval_in_project.invoke(eval.clj:326)
        at leiningen.spec$spec.doInvoke(spec.clj:36)
        ... 5 stack levels elided ...
        at leiningen.core.main$resolve_task$fn__3029.doInvoke(main.clj:189)
        ... 6 stack levels elided ...
        at leiningen.core.main$apply_task.invoke(main.clj:230)
        at lein_environ.plugin$write_env_to_file.invoke(plugin.clj:11)
        ... 4 stack levels elided ...
        at robert.hooke$compose_hooks$fn__8655.doInvoke(hooke.clj:40)
        ... 2 stack levels elided ...
        at robert.hooke$run_hooks.invoke(hooke.clj:46)
        at robert.hooke$prepare_for_hooks$fn__8660$fn__8661.doInvoke(hooke.clj:54)
        ... 3 stack levels elided ...
        at leiningen.core.main$resolve_and_apply.invoke(main.clj:234)
        at leiningen.core.main$_main$fn__3092.invoke(main.clj:303)
        at leiningen.core.main$_main.doInvoke(main.clj:290)
        ... 12 stack levels elided ...

Finished in 0.00000 seconds
1 examples, 0 failures, 1 errors

The culprit seems to be java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core.cache/through, but I have no idea how to resolve it...

Running an equivalent test with core.test is successful.

There's a bit more detailed info in this gist

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.