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

Completion tests #27

Merged
merged 8 commits into from
Apr 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ede-php-autoload.el
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@ Generate this class name using the class loader information.
FILE-NAME must be absolute or relative to the project root."
(ede-php-autoload-get-class-name-for-file (oref this class-loader) file-name))

(defmethod ede-php-autoload-complete ((this ede-php-autoload-project) prefix)
"Get completion suggestions for the type PREFIX.

PREFIX is the beginning of a fully-qualified name.

The result is a list of completion suggestions for this
prefix."
(ede-php-autoload-complete (oref this class-loader) prefix))

(defmethod ede-php-autoload-complete-type-name ((this ede-php-autoload-project) prefix)
"Get completion suggestions for the type PREFIX.

Expand Down
44 changes: 37 additions & 7 deletions ede-php-autoload/class-loader/core.el
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,34 @@ Generate this class name using the class loader information.
FILE-NAME must be absolute or relative to the project root."
(error "Method `ede-php-autoload-find-class-def-file' must be overriden"))

(defmethod ede-php-autoload-complete-type-name ((this ede-php-autoload-class-loader) prefix)
"Get completion suggestions for the type PREFIX.
(defmethod ede-php-autoload-complete ((this ede-php-autoload-class-loader) prefix)
"Get completion suggestions for the PREFIX.

PREFIX is the beginning of a fully-qualified name.

The result is a list of completion suggestions for this
prefix. Completions are not guaranteed to give full class names,
prefix."
(let* ((split-prefix (split-string prefix "\\\\"))
(ns (mapconcat 'identity (butlast split-prefix) "\\"))
(completions (ede-php-autoload-complete-type-name this prefix)))
;; Try to detect if we got toplevel namespace returned (which can
;; contain multiple components), in which case we should not
;; prepend the base namespace. This is error prone, and just a
;; stop gap until ede-php-autoload-complete-type-name handles
;; namespace sub-completion.
(if (cl-loop for completion in completions
always (string-prefix-p prefix completion t))
completions
(cl-loop for completion in completions
collect (concat ns "\\" completion)))))

(defmethod ede-php-autoload-complete-type-name ((this ede-php-autoload-class-loader) prefix)
"Get type completion suggestions for the type PREFIX.

PREFIX is the beginning of a fully-qualified name.

The result is a list of type completion suggestions for this
prefix. Type completions are not guaranteed to give full class names,
this can only suggest the next namespace."
'())

Expand Down Expand Up @@ -95,10 +116,19 @@ Basically, it returns PROJECT-ROOT/{NS-DIRECTORIES}/RELATIVE-PATH/{PREFIX}*"
dir
(expand-file-name dir project-root))
full-dir (expand-file-name relative-path absolute-dir)
files (append files (directory-files
full-dir
nil
(concat "^" (regexp-quote prefix))))))
files (when (file-exists-p full-dir)
(append files (mapcar
#'(lambda (file-name)
(if (file-directory-p
(expand-file-name file-name full-dir))
(concat file-name "\\")
file-name))
(directory-files
full-dir
nil
(concat "^" (if (string= prefix "")
"[^.]"
(regexp-quote prefix)))))))))
files))

(defun ede-php-autoload--ensure-list (list-or-element)
Expand Down
5 changes: 2 additions & 3 deletions ede-php-autoload/class-loader/psr0.el
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ It basically tries to infer whether \"_\" or \"\\\" should be used.
PREFIX is the type prefix to complete."
(let ((suggestion (file-name-base file-name)))
(cond
((string-match-p suggestion ".") nil)
((string-match-p "\\\\" prefix) suggestion)
(t (mapconcat
'identity
Expand All @@ -110,8 +109,8 @@ PREFIX is the beginning of the type to complete."
(cond
((string-prefix-p prefix namespace t)
;; If `prefix' is the beginning of `namespace', let's use
;; `namespace' as suggestion
(push namespace suggestions))
;; `namespace' as suggestion.
(push (concat namespace "\\") suggestions))
((string-prefix-p namespace prefix)
;; If `prefix' starts with `namespace', let's use directory and
;; file structure to create suggestions
Expand Down
4 changes: 2 additions & 2 deletions ede-php-autoload/class-loader/psr4.el
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ PREFIX is the beginning of the type to complete."
(cond
((string-prefix-p prefix namespace t)
;; If `prefix' is the beginning of `namespace', let's use
;; `namespace' as suggestion
(push namespace suggestions))
;; `namespace' as suggestion.
(push (concat namespace "\\") suggestions))
((string-prefix-p namespace prefix)
;; If `prefix' starts with `namespace', let's use directory and
;; file structure to create suggestions
Expand Down
87 changes: 80 additions & 7 deletions features/ede-php-autoload-completion.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,109 @@ Feature: Class name completion

Scenario: Complete PSR-0 namespaces
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "Psr0" should be:
| name |
| Psr0Ns\ |
| Psr0Split\Ns1\ |
| Psr0Split\Ns2\ |
| Psr0Fallback\ |
Then completions for query "Psr0" should be:
| Psr0Ns | Psr0Split\Ns1 | Psr0Split\Ns2 |
| name |
| Psr0Ns\ |
| Psr0Split\Ns1\ |
| Psr0Split\Ns2\ |
| Psr0Fallback\ |

Scenario: Complete PSR-0 namespace with slashes
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "Psr0Ns\T" should be:
| name |
| TheClass |
| TheSubdir\ |
And type completions for query "Psr0Ns\TheSubdir\" should be:
| name |
| TheClass1 |
| TheClass2 |
Then completions for query "Psr0Ns\T" should be:
| TheClass |
| name |
| Psr0Ns\TheClass |
| Psr0Ns\TheSubdir\ |
And completions for query "Psr0Ns\TheSubdir\" should be:
| name |
| Psr0Ns\TheSubdir\TheClass1 |
| Psr0Ns\TheSubdir\TheClass2 |

Scenario: Complete PSR-0 namespace with underscores
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "Psr0Ns_T" should be:
| name |
| Psr0Ns_TheClass |
| Psr0Ns_TheSubdir\ |
And type completions for query "Psr0Ns_TheSubdir_" should be:
| name |
| Psr0Ns_TheSubdir_TheClass1 |
| Psr0Ns_TheSubdir_TheClass2 |
Then completions for query "Psr0Ns_T" should be:
| Psr0Ns_TheClass |
| name |
| Psr0Ns_TheClass |
| Psr0Ns_TheSubdir\ |
And completions for query "Psr0Ns_TheSubdir_" should be:
| name |
| Psr0Ns_TheSubdir_TheClass1 |
| Psr0Ns_TheSubdir_TheClass2 |

Scenario: Complete PSR-4 namespaces
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "Psr4" should be:
| name |
| Psr4Ns\ |
| Psr4Split\Ns1\ |
| Psr4Split\Ns2\ |
| Psr4Fallback\ |
And type completions for query "Psr4Ns\T" should be:
| name |
| TheClass |
| TheSubdir\ |
And type completions for query "Psr4Ns\TheSubdir\" should be:
| name |
| TheClass1 |
| TheClass2 |
Then completions for query "Psr4" should be:
| Psr4Ns | Psr4Split\Ns1 | Psr4Split\Ns2 |
| name |
| Psr4Ns\ |
| Psr4Split\Ns1\ |
| Psr4Split\Ns2\ |
| Psr4Fallback\ |
And completions for query "Psr4Ns\T" should be:
| TheClass |
| name |
| Psr4Ns\TheClass |
| Psr4Ns\TheSubdir\ |
And completions for query "Psr4Ns\TheSubdir\" should be:
| name |
| Psr4Ns\TheSubdir\TheClass1 |
| Psr4Ns\TheSubdir\TheClass2 |

Scenario: Complete PSR-4 multi-dir namespaces
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "MultiDirNs\T" should be:
| name |
| TheClass1 |
| TheClass2 |
Then completions for query "MultiDirNs\T" should be:
| TheClass1 | TheClass2 |

| name |
| MultiDirNs\TheClass1 |
| MultiDirNs\TheClass2 |

Scenario: Complete classmap namespaces
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "ClassMapNs\" should be:
| name |
| ClassMapNs\MyClass |
Then completions for query "ClassMapNs\" should be:
| name |
| ClassMapNs\MyClass |

Scenario: Complete non-existing dir
Given I visit "src/main.php" in project "without-composer"
Then type completions for query "NonExisting\" should be nil
Then completions for query "NonExisting\" should be nil
21 changes: 17 additions & 4 deletions features/step-definitions/ede-php-autoload-steps.el
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,24 @@
file-name)
class-name))))

(Then "^completions for query \"\\(.+\\)\" should be:"
(Then "^type completions for query \"\\(.+\\)\" should be:"
(lambda (query suggestion-table)
(should (equal (ede-php-autoload-complete-type-name (ede-current-project) query)
(car suggestion-table)))))
(let ((suggestions (cl-loop for suggestion in (cdr suggestion-table)
collect (car suggestion))))
(should (equal (ede-php-autoload-complete-type-name (ede-current-project) query)
suggestions)))))

(Then "^completions for query \"\\(.+\\)\" should be nil"
(Then "^type completions for query \"\\(.+\\)\" should be nil"
(lambda (query)
(should (null (ede-php-autoload-complete-type-name (ede-current-project) query)))))

(Then "^completions for query \"\\(.+\\)\" should be:"
(lambda (query suggestion-table)
(let ((suggestions (cl-loop for suggestion in (cdr suggestion-table)
collect (car suggestion))))
(should (equal (ede-php-autoload-complete (ede-current-project) query)
suggestions)))))

(Then "^completions for query \"\\(.+\\)\" should be nil"
(lambda (query)
(should (null (ede-php-autoload-complete (ede-current-project) query)))))
6 changes: 4 additions & 2 deletions features/support/env.el
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,14 @@ COMPOSER-FILE-NAME is either default or new."
"without-composer/project")
:class-autoloads '(:psr-0 (("Psr0Ns" . "src/Psr0Ns")
("Psr0Split\\Ns1" . "src/Psr0Split/Ns1")
("Psr0Split\\Ns2" . "src/Psr0Split/Ns2"))
("Psr0Split\\Ns2" . "src/Psr0Split/Ns2")
("" . "src/Fallback/Psr0"))
:psr-4 (("Psr4Ns" . "src/Psr4Ns")
("MultiDirNs" . ("src/MultiDirNs1" "src/MultiDirNs2"))
("Psr4Split\\Ns1" . "src/Psr4Split/Ns1")
("Psr4Split\\Ns2" . "src/Psr4Split/Ns2")
("NonExisting" . "src/NonExisting"))
("NonExisting" . "src/NonExisting")
("" . "src/Fallback/Psr4"))
:class-map ((ClassMapNs\\MyClass . "src/ClassMapNs/MyClass.php")))
:include-path '(".")
:system-include-path '("/usr/share/php")))
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
namespace Psr0Fallback;

class MyClass {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
namespace Psr4Fallback;

class MyClass {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
namespace Psr0Ns\Subdir;

class TheClass1
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
namespace Psr0Ns\Subdir;

class TheClass2
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
namespace Psr4Ns\Subdir;

class TheClass1
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php
namespace Psr4Ns\Subdir;

class TheClass2
{
}