Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hover framework & refactoring #39

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
136 changes: 136 additions & 0 deletions ccw.core.test/src/clj/ccw/editors/clojure/hover_support_test.clj
@@ -0,0 +1,136 @@
(ns ccw.editors.clojure.hover-support-test
(:use clojure.java.data
clojure.pprint)
(:require [ccw.editors.clojure.hover-support :refer :all]
[ccw.extensions :refer :all]
[clojure.test :refer :all])
(:import org.eclipse.swt.SWT
ccw.editors.clojure.hovers.HoverDescriptor))

(defmacro with-private-fns [[ns fns] & tests]
"Refers private fns from ns and runs tests in context."
`(let ~(reduce #(conj %1 %2 `(ns-resolve '~ns '~%2)) [] fns)
~@tests))

(with-private-fns [ccw.editors.clojure.hover-support [hover-element->descriptor
descriptor-valid?
assoc-create-hover-closure
merge-descriptors
read-and-sanitize-descriptor-string
select-default-descriptor
select-hover-by-state-mask
select-hover-or-default
remove-and-cons]]
(deftest hover-support-tests

(defn build-test-descriptor-fn
([element]
(build-test-descriptor-fn element true))
([element enabled]
{:element element
:instance nil
:enabled enabled
:description "Mock Description"
:label "Mock"
:id "ccw.editors.clojure.hovers.MockHover"
:activate "true"
:modifier-string nil
:state-mask SWT/DEFAULT}))

;; Test of validity fiters
(def test-invalid-element (mock-element :valid false))
(def test-valid-element (mock-element :valid true))
(def test-invalid-descriptor (build-test-descriptor-fn test-invalid-element))
(def test-valid-descriptor (build-test-descriptor-fn test-valid-element))

(testing "Descriptor validity"
(defn load-valid-hovers! []
(lazy-seq [test-valid-descriptor test-valid-descriptor test-valid-descriptor]))

(defn load-invalid-hovers! []
(lazy-seq [test-invalid-descriptor test-valid-descriptor]))

(is (every? descriptor-valid? (load-valid-hovers!)))
(is (not (every? descriptor-valid? (load-invalid-hovers!))))
(is (function? (:create-hover (assoc-create-hover-closure test-valid-descriptor)))))

(testing "Descriptor Java conversion"
(def descriptor {:enabled true :description "Mock Description" :label "Mock"
:id "ccw.editors.clojure.hovers.MockHover" :modifier-string nil
:state-mask SWT/DEFAULT})
(def java-descriptor (HoverDescriptor. "ccw.editors.clojure.hovers.MockHover"
"Mock" true "Mock Description" SWT/DEFAULT nil))

(is (= java-descriptor (to-java HoverDescriptor descriptor)))
(is (= descriptor (from-java java-descriptor))))

(testing "Descriptors from preferences"
(def test-pref-descriptors (list {:id "ccw.editors.clojure.hovers.MockHover"
:enabled false
:modifier-string "Alt"}
{:id "not.editors.clojure.hovers.MockHover"
:enabled true
:modifier-string "Shift + Alt"}))

(def merged-descriptors (merge-descriptors (list test-valid-descriptor) test-pref-descriptors))
(is (= "ccw.editors.clojure.hovers.MockHover" (:id (first merged-descriptors))))
(is (= false (:enabled (first merged-descriptors))))
(is (= "Alt" (:modifier-string (first merged-descriptors))))

(def test-string-invalid-modifier "({:modifier-string \"Shiftrasars\", :enabled true, :id \"Wrong\"}
{:modifier-string \"\", :enabled true, :id \"Empty\"}
{ :enabled true, :id \"Nil\"})")
(def invalid-descriptors (read-and-sanitize-descriptor-string test-string-invalid-modifier))
(def wrong-modifier-descriptor (first (filter #(= "Wrong" (%1 :id)) invalid-descriptors)))
(def empty-modifier-descriptor (first (filter #(= "Empty" (%1 :id)) invalid-descriptors)))
(def nil-modifier-descriptor (first (filter #(= "Nil" (%1 :id)) invalid-descriptors)))

(is (nil? (:modifier-string wrong-modifier-descriptor)))
(is (= SWT/DEFAULT (:state-mask wrong-modifier-descriptor)))
(is (= "" (:modifier-string empty-modifier-descriptor)))
(is (= SWT/NONE (:state-mask empty-modifier-descriptor)))
(is (nil? (:modifier-string nil-modifier-descriptor)))
(is (= SWT/DEFAULT (:state-mask nil-modifier-descriptor)))


(def test-string-valid-modifier "({:modifier-string \"Alt + Shift\", :enabled true, :id \"Id1\"}
{:modifier-string \"Ctrl\", :enabled true, :id \"Id2\"})")
(def test-descriptors (read-and-sanitize-descriptor-string test-string-valid-modifier))
(def test-first-descriptor (first (filter #(= "Id1" (%1 :id)) test-descriptors)))
(def test-second-descriptor (first (filter #(= "Id2" (%1 :id)) test-descriptors)))

(is (= "Alt + Shift" (:modifier-string test-first-descriptor)))
(is (= 196608 (:state-mask test-first-descriptor)))
(is (= "Ctrl" (:modifier-string test-second-descriptor)))
(is (= 262144 (:state-mask test-second-descriptor))))

(testing "Descriptor selection"
(is (= test-first-descriptor (select-hover-by-state-mask "" 196608 test-descriptors)))
(is (not= test-second-descriptor (select-hover-by-state-mask "" 196608 test-descriptors)))
(is (not= test-first-descriptor (select-hover-by-state-mask "" 262144 test-descriptors)))
(is (= test-second-descriptor (select-hover-by-state-mask "" 262144 test-descriptors)))

;; Test if the default is picked with nil or ""
(is (= "Id1" (:id (select-default-descriptor (read-and-sanitize-descriptor-string "({:modifier-string \"\", :enabled true, :id \"Id1\"})")))))
(is (= "Id1" (:id (select-default-descriptor (read-and-sanitize-descriptor-string "({:enabled true, :id \"Id1\"})")))))

(def test-string-no-modifier "({:modifier-string \"\", :enabled true, :id \"Id1\"}
{:modifier-string \"Alt + Shift\", :enabled true, :id \"Id2\"}
{:modifier-string \"Ctrl\", :enabled true, :id \"Id3\"})")
(def no-modifier-descriptors (read-and-sanitize-descriptor-string test-string-no-modifier))
(def no-modifier-descriptor (first (filter #(= "Id1" (%1 :id)) no-modifier-descriptors)))
(def ctrl-modifier-descriptor (first (filter #(= "Id3" (%1 :id)) no-modifier-descriptors)))

(is (= no-modifier-descriptor (select-default-descriptor no-modifier-descriptors)))
(is (= no-modifier-descriptor (select-hover-or-default select-hover-by-state-mask "" 42 no-modifier-descriptors)))
(is (= ctrl-modifier-descriptor (select-hover-or-default select-hover-by-state-mask "" 262144 no-modifier-descriptors)))
(is (not= ctrl-modifier-descriptor (select-hover-or-default select-hover-by-state-mask "" 196608 no-modifier-descriptors))))

(testing "Descriptor list ops"
(def mock-descriptors (list {:id "Test1" :enabled true} {:id "Test2" :enabled false}))
(is (some #(= "Test3" (:id %1)) (remove-and-cons #(= (:id %1) "Test2") {:id "Test3"} mock-descriptors)))
(is (not-any? #(= "Test2" (:id %1)) (remove-and-cons #(= (:id %1) "Test2") {:id "Test3"} mock-descriptors))))

(testing "Proxy creation"
(def hover-proxy (create-hover-proxy "" 262144))
(is (identical? hover-proxy (create-hover-proxy "" 262144))))))
47 changes: 47 additions & 0 deletions ccw.core.test/src/clj/ccw/extensions_test.clj
@@ -0,0 +1,47 @@
(ns ccw.extensions-test
(:require [ccw.extensions :refer :all]
[clojure.test :refer :all]))

(deftest extensions-tests
(def test-invalid-element (mock-element :valid false))
(def test-valid-element (mock-element :valid true))

(is (element-valid? test-valid-element))
(is (not (element-valid? test-invalid-element)))
(is (= "pippo" (element-name (mock-element :tag "pippo"))))
(is (= "pluto" (element-name (first (element-children
(mock-element :kids (list (mock-zero-kids-element "pluto" nil))))))))
(is (= "a" (element-attribute (mock-element :attrs {:a "a"}) "a")))
(is (= 4 (count (element-children (mock-with-kids "p" nil 4)))))

(is (= {:a "a"} (attributes->map (mock-element :attrs {:a "a"}))))
(is (empty? (attributes->map (mock-element :attrs nil))))
(is (empty? (attributes->map (mock-element :attrs {}))))
(is (not (nil? (attributes->map (mock-element :attrs nil)))))
(is (not (nil? (attributes->map (mock-element :attrs {})))))

(def p (mock-element :tag "parent" :kids (list (mock-zero-kids-element "tizio" nil)
(mock-zero-kids-element "caio" nil)
(mock-zero-kids-element "sempronio" nil)
(mock-zero-kids-element "tizio" nil))))
(is (= 2 (count (element-children p "tizio"))))
(is (every? #(= "tizio" (element-name %1)) (element-children p "tizio")))
(is (not-any? #(= "caio" (element-name %1)) (element-children p "tizio")))
(is (not-any? #(= "sempronio" (element-name %1)) (element-children p "tizio")))
(is (empty? (element-children p "asd")))

(def one-kid-parent (element->map (mock-element :tag "ab"
:attrs {:a "a" :b "b"}
:kids (list (mock-zero-kids-element "kab" {:ka "ka" :kb "kb"})))))
(def content-of-one-kid-parent (:content one-kid-parent))
(is (= "ab" (:tag one-kid-parent)))
(is (= 1 (count content-of-one-kid-parent)))
(is (= {:a "a" :b "b"} (:attrs one-kid-parent)))
(is (= {:ka "ka" :kb "kb"} (:attrs (first content-of-one-kid-parent))))
(is (= "kab" (:tag (first content-of-one-kid-parent))))

(def two-kid-parent (element->map (mock-with-kids "ab" {:c "c" :d "d"} 2 {:kc "kc" :kd "kd"} {:ke "ke" :kf "kf"})))
(def content-of-two-kid-parent (:content two-kid-parent))
(is (= 2 (count content-of-two-kid-parent)))
(is (= {:kc "kc" :kd "kd"} (:attrs (first content-of-two-kid-parent))))
(is (= {:ke "ke" :kf "kf"} (:attrs (second content-of-two-kid-parent)))))
3 changes: 2 additions & 1 deletion ccw.core/.options
Expand Up @@ -7,4 +7,5 @@ ccw.core/builder=false
ccw.core/launcher=false
ccw.core/autocompletion=false
ccw.core/paredit=false
ccw.core/clojure.osgi=false
ccw.core/clojure.osgi=false
ccw.core/support/hover=false
2 changes: 1 addition & 1 deletion ccw.core/Counterclockwise Plugin.launch
Expand Up @@ -22,7 +22,7 @@
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:MaxPermSize=256m -Xms40m -Xmx1024m -Dorg.eclipse.swt.internal.carbon.smallFonts -Dccw.autostartnrepl"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:MaxPermSize=256m -Xms40m -Xmx1024m -Dorg.eclipse.swt.internal.carbon.smallFonts -Dccw.nrepl.autostart"/>
<booleanAttribute key="pde.generated.config" value="false"/>
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.platform.ide"/>
Expand Down
17 changes: 13 additions & 4 deletions ccw.core/META-INF/MANIFEST.MF
Expand Up @@ -5,8 +5,7 @@ Bundle-SymbolicName: ccw.core;singleton:=true
Bundle-Version: 0.31.2.qualifier
Bundle-Localization: plugin
Bundle-Activator: ccw.CCWPlugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui.ide,
org.eclipse.jdt.launching,
org.eclipse.jdt.core,
Expand Down Expand Up @@ -44,7 +43,15 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.e4.ui.widgets,
org.eclipse.e4.ui.workbench,
org.eclipse.core.runtime.compatibility,
org.eclipse.osgi.services
org.eclipse.osgi.services,
org.eclipse.core.databinding,
org.eclipse.core.databinding.property,
org.eclipse.core.databinding.beans,
org.eclipse.ui.workbench,
org.eclipse.jface.databinding,
org.eclipse.core.databinding.observable,
org.eclipse.osgi,
org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional
Bundle-ClassPath: .,
src/clj/,
lib/aether-api.jar,
Expand Down Expand Up @@ -124,7 +131,9 @@ Bundle-ClassPath: .,
lib/junit.jar,
lib/cljunit.jar,
lib/hamcrest-core.jar,
lib/pedantic.jar
lib/pedantic.jar,
lib/tools.logging.jar,
lib/java.data.jar
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-Vendor: Counterclockwise team
Eclipse-BundleShape: dir
Expand Down
7 changes: 7 additions & 0 deletions ccw.core/plugin.properties
Expand Up @@ -102,6 +102,7 @@ preferencePage.editor.name=Editor
preferencePage.syntaxColoring.name=Colors and Fonts
preferencePage.repl.name=REPL View
preferencePage.repl.history.name=REPL History
preferencePage.hover.name=Hovers

ExpandSelectionTo=Expand Selection To
ClojureSelectEnclosing_label=Enclosing Element
Expand Down Expand Up @@ -153,3 +154,9 @@ ccw.leiningen.problemmarker.classpathcontainer=Leiningen Classpath Container
ccw.leiningen.command.launch-headless-repl.name=Launch Headless REPL for the project
ccw.leiningen.command.launch-headless-repl.description=Launch a Headless REPL for the project through Leiningen

cljEditorTextHoversName=Clojure Editor Text Hovers

docstringHover=Clojure Docstring
docstringHoverDescription=Shows the docstring of the selected element.
debugHover=Debug
debugHoverDescription=Debug hover for testing.
41 changes: 41 additions & 0 deletions ccw.core/plugin.xml
Expand Up @@ -2,6 +2,9 @@
<?eclipse version="3.2"?>
<plugin>

<!-- see http://help.eclipse.org/indigo/topic/org.eclipse.jdt.doc.isv/reference/extension-points/org_eclipse_jdt_ui_javaEditorTextHovers.html -->
<extension-point id="cljEditorTextHovers" name="%cljEditorTextHoversExtensionName" schema="schema/cljEditorTextHovers.exsd"/>

<extension point="org.eclipse.ui.console.consolePatternMatchListeners">
<consolePatternMatchListener
id="ccw.editors.clojure.StacktraceHyperlink"
Expand Down Expand Up @@ -1641,6 +1644,12 @@
id="ccw.preferences.REPLHistoryPreferencePage"
name="%preferencePage.repl.history.name">
</page>
<page
name="%preferencePage.hover.name"
category="ccw.preferences.EditorPreferencePage"
class="ccw.preferences.HoverPreferencePage"
id="ccw.preferences.HoverPreferencePage">
</page>
</extension>
<extension
point="org.eclipse.debug.core.sourcePathComputers">
Expand Down Expand Up @@ -3389,4 +3398,36 @@
</element>
</processor>
</extension>
<!-- =========================================================================== -->
<!-- CCW Hover Contributions -->
<!-- =========================================================================== -->
<!-- Taken from org.eclipse.jdt.ui - Note: Do not change the sequence -->

<extension
point="ccw.core.cljEditorTextHovers">
<hover
label="%docstringHover"
description="%docstringHoverDescription"
id="ccw.editors.clojure.hovers.docstringHover"
activate="true">
<run class="ccw.util.GenericExecutableExtension">
<parameter
name="factory"
value="ccw.editors.clojure.hovers.docstring-hover/create-docstring-hover">
</parameter>
</run>
</hover>
<!--<hover
label="%debugHover"
description="%debugHoverDescription"
id="ccw.editors.clojure.hovers.DebugHover"
activate="true">
<factory class="ccw.util.GenericExecutableExtension">
<parameter
name="factory"
value="ccw.editors.clojure.hovers.debug-hover/create-debug-hover">
</parameter>
</factory>
</hover>-->
</extension>
</plugin>
5 changes: 5 additions & 0 deletions ccw.core/pom.xml
Expand Up @@ -81,6 +81,11 @@
<artifactId>ccw.server</artifactId>
<version>0.1.1</version>
</dependency>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>java.data</artifactId>
<version>0.1.1</version>
</dependency>
</dependencies>

<build>
Expand Down