├── .gitignore ├── .gitmodules ├── .npmignore ├── CONTRIBUTING ├── LICENSE ├── NOTICE ├── README.md ├── bin └── test ├── binding.gyp ├── deps ├── libxml2.gyp ├── libxq │ ├── CONTRIBUTING │ ├── LICENSE │ ├── Makefile.am │ ├── NOTICE │ ├── README.md │ ├── acinclude.m4 │ ├── configure.ac │ ├── libxq.gyp │ ├── libxq.h │ ├── m4 │ │ └── .gitkeep │ ├── node │ │ └── config.h │ ├── nodelist.c │ ├── search.c │ ├── tests │ │ ├── Makefile.am │ │ ├── check_search.c │ │ └── check_xq.c │ ├── traverse.c │ ├── xq.c │ └── xqutil.h └── xmlconfig │ ├── config.h │ └── libxml │ └── xmlversion.h ├── ext ├── CharacterData.cpp ├── CharacterData.h ├── Document.cpp ├── Document.h ├── Element.cpp ├── Element.h ├── Node.cpp ├── Node.h ├── utils.h ├── xQWrapper.cpp ├── xQWrapper.h └── xqjs.cpp ├── index.js ├── package.json └── test ├── document ├── character_data.js ├── document.js ├── element.js ├── node.js ├── parse.js └── zz_gc.js ├── xq_addNamespace.js ├── xq_arrayAccess.js ├── xq_attr.js ├── xq_available.js ├── xq_children.js ├── xq_closest.js ├── xq_constructor.js ├── xq_every.js ├── xq_filter.js ├── xq_find.js ├── xq_findIndex.js ├── xq_first.js ├── xq_invalidSelectors.js ├── xq_last.js ├── xq_length.js ├── xq_next.js ├── xq_not.js ├── xq_parent.js ├── xq_prev.js ├── xq_reduce.js ├── xq_reduceRight.js ├── xq_search.js ├── xq_some.js ├── xq_text.js └── xq_xml.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.lo 3 | *.la 4 | *.o 5 | .deps 6 | .libs 7 | Makefile 8 | Makefile.in 9 | aclocal.m4 10 | ar-lib 11 | autom4te.cache 12 | build 13 | compile 14 | #config.h 15 | config.guess 16 | config.h.in 17 | config.h.in~ 18 | config.log 19 | config.status 20 | config.sub 21 | configure 22 | depcomp 23 | install-sh 24 | libtool 25 | ltmain.sh 26 | missing 27 | m4/libtool.m4 28 | m4/ltoptions.m4 29 | m4/ltsugar.m4 30 | m4/ltversion.m4 31 | m4/lt~obsolete.m4 32 | stamp-h1 33 | test-driver 34 | tests/*.log 35 | tests/*.trs 36 | tests/Makefile 37 | tests/Makefile.in 38 | tests/check_search 39 | tests/check_xq 40 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps/libxml2"] 2 | path = deps/libxml2 3 | url = git://git.gnome.org/libxml2 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bin/test 2 | test 3 | deps/libxml2/doc 4 | deps/libxml2/example 5 | deps/libxml2/python 6 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | If you would like to contribute code to this project you can do so through 2 | GitHub by forking the repository and sending a pull request. 3 | 4 | Before Comcast accepts your code into the project you must sign the 5 | Comcast Contributor License Agreement (CLA). 6 | 7 | If you haven’t previously signed a Comcast CLA, we can e-mail you a PDF 8 | that you can sign and scan back to us. Please send us an e-mail or create 9 | a new GiHhub issue to request a PDF version of the CLA. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | xQ Library 2 | Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | 4 | This product includes software developed at Comcast (http://www.comcast.com/). 5 | -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node --expose-gc 2 | /** 3 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | var reporter = require('nodeunit').reporters.default; 18 | reporter.run([__dirname + '/../test', __dirname + '/../test/document']); 19 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | { 17 | "targets": [ 18 | { 19 | "target_name": "xqjs", 20 | "include_dirs": [ 21 | " 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | 31 | typedef enum { 32 | XQ_OK = 0, 33 | XQ_OUT_OF_MEMORY, 34 | XQ_ARGUMENT_OUT_OF_BOUNDS, 35 | XQ_XML_PARSER_ERROR, 36 | XQ_NO_TOKEN, // this is an internal status code 37 | XQ_INVALID_SEL_UNTERMINATED_STR, 38 | XQ_INVALID_SEL_UNEXPECTED_TOKEN, 39 | XQ_NO_MATCH, // this is an internal status code 40 | XQ_UNKNOWN_NS_PREFIX 41 | } xQStatusCode; 42 | 43 | typedef struct _xQNodeList { 44 | xmlNodePtr* list; 45 | unsigned long capacity; 46 | unsigned long size; 47 | } xQNodeList; 48 | 49 | xQStatusCode xQNodeList_alloc_init(xQNodeList** list, unsigned long size); 50 | xQStatusCode xQNodeList_init(xQNodeList* list, unsigned long size); 51 | xQStatusCode xQNodeList_free(xQNodeList* list, int freeList); 52 | xQStatusCode xQNodeList_insert(xQNodeList* list, xmlNodePtr node, unsigned long atIdx); 53 | xQStatusCode xQNodeList_remove(xQNodeList* list, unsigned long fromIdx, unsigned long count); 54 | xQStatusCode xQNodeList_assign(xQNodeList* toList, xQNodeList* fromList); 55 | #define xQNodeList_push(list, node) (xQNodeList_insert(list, node, (list)->size)) 56 | #define xQNodeList_clear(list) ((list)->size = 0) 57 | 58 | 59 | 60 | typedef struct _xQ { 61 | xmlDocPtr document; 62 | xQNodeList context; 63 | xmlHashTablePtr nsPrefixes; 64 | } xQ; 65 | 66 | xQStatusCode xQ_alloc_init(xQ** self); 67 | xQStatusCode xQ_alloc_initDoc(xQ** self, xmlDocPtr doc); 68 | xQStatusCode xQ_alloc_initFile(xQ** self, const char* filename, xmlDocPtr* doc); 69 | xQStatusCode xQ_alloc_initMemory(xQ** self, const char* buffer, int size, xmlDocPtr* doc); 70 | xQStatusCode xQ_alloc_initNodeList(xQ** self, xQNodeList* list); 71 | xQStatusCode xQ_init(xQ* self); 72 | xQStatusCode xQ_free(xQ* self, int freeXQ); 73 | xQStatusCode xQ_children(xQ* self, const xmlChar* selector, xQ** result); 74 | xQStatusCode xQ_closest(xQ* self, const xmlChar* selector, xQ** result); 75 | xQStatusCode xQ_find(xQ* self, const xmlChar* selector, xQ** result); 76 | xQStatusCode xQ_filter(xQ* self, const xmlChar* selector, xQ** result); 77 | xQStatusCode xQ_next(xQ* self, const xmlChar* selector, xQ** result); 78 | xQStatusCode xQ_nextAll(xQ* self, const xmlChar* selector, xQ** result); 79 | xQStatusCode xQ_nextUntil(xQ* self, const xmlChar* selector, xQ** result); 80 | xQStatusCode xQ_not(xQ* self, const xmlChar* selector, xQ** result); 81 | xQStatusCode xQ_parent(xQ* self, const xmlChar* selector, xQ** result); 82 | xQStatusCode xQ_parents(xQ* self, const xmlChar* selector, xQ** result); 83 | xQStatusCode xQ_parentsUntil(xQ* self, const xmlChar* selector, xQ** result); 84 | xQStatusCode xQ_prev(xQ* self, const xmlChar* selector, xQ** result); 85 | xQStatusCode xQ_prevAll(xQ* self, const xmlChar* selector, xQ** result); 86 | xQStatusCode xQ_prevUntil(xQ* self, const xmlChar* selector, xQ** result); 87 | xQStatusCode xQ_clear(xQ* self); 88 | unsigned long xQ_length(xQ* self); 89 | xmlChar* xQ_getText(xQ* self); 90 | xmlChar* xQ_getAttr(xQ* self, const char* name); 91 | xmlChar* xQ_getXml(xQ* self); 92 | xQStatusCode xQ_first(xQ* self, xQ** result); 93 | xQStatusCode xQ_last(xQ* self, xQ** result); 94 | xQStatusCode xQ_addNamespace(xQ* self, const xmlChar* prefix, const xmlChar* uri); 95 | const xmlChar* xQ_namespaceForPrefix(xQ* self, const xmlChar* prefix); 96 | 97 | 98 | 99 | typedef xQStatusCode (*xQSearchOp)(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 100 | typedef struct _xQSearchExpr xQSearchExpr; 101 | struct _xQSearchExpr { 102 | unsigned int argc; 103 | xmlChar** argv; 104 | xQSearchOp operation; 105 | xQSearchExpr* next; 106 | }; 107 | 108 | xQStatusCode xQSearchExpr_alloc_init(xQSearchExpr** self, const xmlChar* expr); 109 | xQStatusCode xQSearchExpr_alloc_initFilter(xQSearchExpr** self, const xmlChar* expr); 110 | xQStatusCode xQSearchExpr_free(xQSearchExpr* self); 111 | xQStatusCode xQSearchExpr_eval(xQSearchExpr* self, xQ* context, xmlNodePtr node, xQNodeList* outList); 112 | 113 | xQStatusCode _xQ_findDescendants(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 114 | xQStatusCode _xQ_findDescendantsByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 115 | xQStatusCode _xQ_findChildrenByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 116 | xQStatusCode _xQ_findNextSiblingByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 117 | xQStatusCode _xQ_filterAttributeEquals(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 118 | xQStatusCode _xQ_addToOutput(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 119 | xQStatusCode _xQ_filterByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList); 120 | 121 | extern const xmlChar* XQ_EMPTY_NAMESPACE; 122 | 123 | #ifdef __cplusplus 124 | } 125 | #endif 126 | 127 | #endif // __LIBXQ_H_INCLUDED__ 128 | -------------------------------------------------------------------------------- /deps/libxq/m4/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Comcast/xml-selector/0c8fbe7f609c61c53ba3c0faf2a5753bd8e5f72a/deps/libxq/m4/.gitkeep -------------------------------------------------------------------------------- /deps/libxq/node/config.h: -------------------------------------------------------------------------------- 1 | /** 2 | * GYP does not work well with autoconf, unfortunately. 3 | * 4 | * This is generated manually to have settings that will work with the 5 | * platforms node can be built on (and, yeah, that kind of defeats the 6 | * whole purpose of the autotools system). 7 | */ 8 | 9 | /* HAVE_INLINE Define to 1 if the inline keyword can be used with the C compliler. 10 | For now, assume this is true everywhere until it breaks */ 11 | #ifndef HAVE_INLINE 12 | #define HAVE_INLINE 1 13 | #endif 14 | -------------------------------------------------------------------------------- /deps/libxq/nodelist.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Nodelist implementation 19 | */ 20 | 21 | #include "libxq.h" 22 | 23 | #include 24 | #include 25 | 26 | 27 | // local (private) routines 28 | static xQStatusCode xQNodeList_grow(xQNodeList* list, unsigned long requiredCapacity); 29 | 30 | 31 | /** 32 | * Allocate and initialize a new node list 33 | * 34 | * The parameter list is assigned a pointer to the node list on success, 35 | * or 0 on error. 36 | * 37 | * Returns a 0 (XQ_OK) on success, an error code otherwise 38 | */ 39 | xQStatusCode xQNodeList_alloc_init(xQNodeList** list, unsigned long size) { 40 | xQStatusCode status = XQ_OK; 41 | 42 | *list = (xQNodeList*) malloc(sizeof(xQNodeList)); 43 | if (!*list) 44 | return XQ_OUT_OF_MEMORY; 45 | 46 | 47 | if (XQ_OK != (status = xQNodeList_init(*list, size))) { 48 | free(*list); 49 | *list = 0; 50 | } 51 | 52 | return status; 53 | } 54 | 55 | /** 56 | * Initialize a newly allocated node list 57 | * 58 | * Returns a 0 (XQ_OK) on success, an error code otherwise 59 | */ 60 | xQStatusCode xQNodeList_init(xQNodeList* list, unsigned long size) { 61 | xmlNodePtr* buff; 62 | 63 | list->list = 0; 64 | list->capacity = 0; 65 | list->size = 0; 66 | 67 | buff = (xmlNodePtr*) malloc(sizeof(xmlNodePtr) * size); 68 | if (!buff) 69 | return XQ_OUT_OF_MEMORY; 70 | 71 | list->list = buff; 72 | list->capacity = size; 73 | 74 | return XQ_OK; 75 | } 76 | 77 | /** 78 | * Free a node list previously allocated with xQNodeList_alloc_init 79 | * 80 | * Returns a 0 (XQ_OK) on success, an error code otherwise 81 | */ 82 | xQStatusCode xQNodeList_free(xQNodeList* list, int freeList) { 83 | if (list && list->list) 84 | free(list->list); 85 | if (freeList) 86 | free(list); 87 | 88 | return XQ_OK; 89 | } 90 | 91 | /** 92 | * Grow the capacity of the list to accommodate a minimum number of items 93 | * 94 | * Returns a 0 (XQ_OK) on success, an error code otherwise 95 | */ 96 | static xQStatusCode xQNodeList_grow(xQNodeList* list, unsigned long requiredCapacity) { 97 | unsigned long newCapacity; 98 | xmlNodePtr* buff; 99 | 100 | if (list->capacity >= requiredCapacity) 101 | return XQ_OK; 102 | 103 | newCapacity = list->capacity < 8 ? 8 : list->capacity; 104 | 105 | while (newCapacity < requiredCapacity && newCapacity >= list->capacity) 106 | newCapacity <<= 2; 107 | 108 | if (newCapacity < requiredCapacity) 109 | return XQ_ARGUMENT_OUT_OF_BOUNDS; 110 | 111 | buff = (xmlNodePtr*) realloc(list->list, sizeof(xmlNodePtr) * newCapacity); 112 | if (!buff) 113 | return XQ_OUT_OF_MEMORY; 114 | 115 | list->list = buff; 116 | list->capacity = newCapacity; 117 | 118 | return XQ_OK; 119 | } 120 | 121 | /** 122 | * Insert an item into a list at a given index 123 | * 124 | * Returns a 0 (XQ_OK) on success, an error code otherwise 125 | */ 126 | xQStatusCode xQNodeList_insert(xQNodeList* list, xmlNodePtr node, unsigned long atIdx) { 127 | xQStatusCode result = XQ_OK; 128 | 129 | if (atIdx > list->size) 130 | return XQ_ARGUMENT_OUT_OF_BOUNDS; 131 | 132 | if (list->capacity < list->size + 1) 133 | result = xQNodeList_grow(list, list->size + 1); 134 | 135 | if (result != XQ_OK) 136 | return result; 137 | 138 | if (atIdx != list->size) 139 | memmove(&(list->list[atIdx + 1]), &(list->list[atIdx]), sizeof(xmlNodePtr) * (list->size - atIdx)); 140 | 141 | list->list[atIdx] = node; 142 | list->size += 1; 143 | 144 | return XQ_OK; 145 | } 146 | 147 | /** 148 | * Remove 1 or more items from the list at a given index 149 | * 150 | * Returns a 0 (XQ_OK) on success, an error code otherwise 151 | */ 152 | xQStatusCode xQNodeList_remove(xQNodeList* list, unsigned long fromIdx, unsigned long count) { 153 | unsigned long endIdx = fromIdx + count; 154 | 155 | if (fromIdx >= list->size || endIdx > list->size) 156 | return XQ_ARGUMENT_OUT_OF_BOUNDS; 157 | 158 | if (endIdx < list->size) 159 | memmove(&(list->list[fromIdx]), &(list->list[endIdx]), sizeof(xmlNodePtr) * count); 160 | 161 | list->size -= count; 162 | 163 | return XQ_OK; 164 | } 165 | 166 | /** 167 | * Assign the contents of another list to this list 168 | * 169 | * Returns a 0 (XQ_OK) on success, an error code otherwise 170 | */ 171 | xQStatusCode xQNodeList_assign(xQNodeList* toList, xQNodeList* fromList) { 172 | xQStatusCode result = XQ_OK; 173 | 174 | if (toList->capacity < fromList->size) 175 | result = xQNodeList_grow(toList, fromList->size); 176 | 177 | if (result == XQ_OK) { 178 | memmove(toList->list, fromList->list, sizeof(xmlNodePtr) * fromList->size); 179 | toList->size = fromList->size; 180 | } 181 | 182 | return result; 183 | } 184 | -------------------------------------------------------------------------------- /deps/libxq/tests/Makefile.am: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | TESTS = check_search check_xq 17 | 18 | check_PROGRAMS = check_search check_xq 19 | 20 | check_search_SOURCES = check_search.c $(top_builddir)/libxq.h 21 | check_search_CFLAGS = @CHECK_CFLAGS@ @LIBXML_CFLAGS@ 22 | check_search_LDFLAGS = @LIBXML_LFLAGS@ 23 | check_search_LDADD = $(top_builddir)/libxq.la @CHECK_LIBS@ 24 | 25 | check_xq_SOURCES = check_xq.c $(top_builddir)/libxq.h 26 | check_xq_CFLAGS = @CHECK_CFLAGS@ @LIBXML_CFLAGS@ 27 | check_xq_LDFLAGS = @LIBXML_LFLAGS@ 28 | check_xq_LDADD = $(top_builddir)/libxq.la @CHECK_LIBS@ 29 | -------------------------------------------------------------------------------- /deps/libxq/tests/check_search.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | #include 19 | 20 | #define singleTestCase(suite, var, name, test) do { \ 21 | TCase* var = tcase_create(name); \ 22 | tcase_add_test(var, test); \ 23 | suite_add_tcase(s, var); \ 24 | } while(0) 25 | 26 | /** 27 | * Test the empty selector 28 | */ 29 | START_TEST (test_empty_selector) 30 | { 31 | xQSearchExpr* expr; 32 | xQStatusCode status; 33 | 34 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)""); 35 | 36 | ck_assert(status == XQ_OK); 37 | ck_assert(expr->operation == _xQ_addToOutput); 38 | ck_assert(expr->next == 0); 39 | 40 | xQSearchExpr_free(expr); 41 | } 42 | END_TEST 43 | 44 | /** 45 | * Test a single selector 46 | */ 47 | START_TEST (test_single_selector) 48 | { 49 | xQSearchExpr* expr; 50 | xQStatusCode status; 51 | 52 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem"); 53 | 54 | ck_assert(status == XQ_OK); 55 | ck_assert(expr->operation == _xQ_findDescendantsByName); 56 | ck_assert(expr->argc == 2); 57 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem") == 0); 58 | ck_assert(expr->argv[1] == 0); 59 | ck_assert(expr->next == 0); 60 | 61 | xQSearchExpr_free(expr); 62 | } 63 | END_TEST 64 | 65 | /** 66 | * Test a namespace selector 67 | */ 68 | START_TEST (test_ns_selector) 69 | { 70 | xQSearchExpr* expr; 71 | xQStatusCode status; 72 | 73 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"ns:elem"); 74 | 75 | ck_assert(status == XQ_OK); 76 | ck_assert(expr->operation == _xQ_findDescendantsByName); 77 | ck_assert(expr->argc == 2); 78 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem") == 0); 79 | ck_assert(xmlStrcmp(expr->argv[1], (xmlChar*)"ns") == 0); 80 | ck_assert(expr->next == 0); 81 | 82 | xQSearchExpr_free(expr); 83 | } 84 | END_TEST 85 | 86 | /** 87 | * Test a dual selector 88 | */ 89 | START_TEST (test_dual_selector) 90 | { 91 | xQSearchExpr* expr; 92 | xQStatusCode status; 93 | 94 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1 elem2"); 95 | 96 | ck_assert(status == XQ_OK); 97 | ck_assert(expr->operation == _xQ_findDescendantsByName); 98 | ck_assert(expr->argc == 2); 99 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 100 | ck_assert(expr->argv[1] == 0); 101 | ck_assert(expr->next != 0); 102 | 103 | ck_assert(expr->next->operation == _xQ_findDescendantsByName); 104 | ck_assert(expr->next->argc == 2); 105 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"elem2") == 0); 106 | ck_assert(expr->next->argv[1] == 0); 107 | ck_assert(expr->next->next == 0); 108 | 109 | xQSearchExpr_free(expr); 110 | } 111 | END_TEST 112 | 113 | /** 114 | * Test a dual selector with namespaces 115 | */ 116 | START_TEST (test_dual_ns_selector) 117 | { 118 | xQSearchExpr* expr; 119 | xQStatusCode status; 120 | 121 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"nsA:elem1 nsB:elem2"); 122 | 123 | ck_assert(status == XQ_OK); 124 | ck_assert(expr->operation == _xQ_findDescendantsByName); 125 | ck_assert(expr->argc == 2); 126 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 127 | ck_assert(xmlStrcmp(expr->argv[1], (xmlChar*)"nsA") == 0); 128 | ck_assert(expr->next != 0); 129 | 130 | ck_assert(expr->next->operation == _xQ_findDescendantsByName); 131 | ck_assert(expr->next->argc == 2); 132 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"elem2") == 0); 133 | ck_assert(xmlStrcmp(expr->next->argv[1], (xmlChar*)"nsB") == 0); 134 | ck_assert(expr->next->next == 0); 135 | 136 | xQSearchExpr_free(expr); 137 | } 138 | END_TEST 139 | 140 | /** 141 | * Test a wildcard selector 142 | */ 143 | START_TEST (test_wildcard_selector) 144 | { 145 | xQSearchExpr* expr; 146 | xQStatusCode status; 147 | 148 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"* elem"); 149 | 150 | ck_assert(status == XQ_OK); 151 | ck_assert(expr->operation == _xQ_findDescendants); 152 | ck_assert(expr->argc == 0); 153 | ck_assert(expr->next != 0); 154 | 155 | ck_assert(expr->next->operation == _xQ_findDescendantsByName); 156 | ck_assert(expr->next->argc == 2); 157 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"elem") == 0); 158 | ck_assert(expr->next->argv[1] == 0); 159 | ck_assert(expr->next->next == 0); 160 | 161 | xQSearchExpr_free(expr); 162 | } 163 | END_TEST 164 | 165 | /** 166 | * Test a + combinator 167 | */ 168 | START_TEST (test_plus_combinator) 169 | { 170 | xQSearchExpr* expr; 171 | xQStatusCode status; 172 | 173 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1 + elem2"); 174 | 175 | ck_assert(status == XQ_OK); 176 | ck_assert(expr->operation == _xQ_findDescendantsByName); 177 | ck_assert(expr->argc == 2); 178 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 179 | ck_assert(expr->argv[1] == 0); 180 | ck_assert(expr->next != 0); 181 | 182 | ck_assert(expr->next->operation == _xQ_findNextSiblingByName); 183 | ck_assert(expr->next->argc == 2); 184 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"elem2") == 0); 185 | ck_assert(expr->next->argv[1] == 0); 186 | ck_assert(expr->next->next == 0); 187 | 188 | xQSearchExpr_free(expr); 189 | } 190 | END_TEST 191 | 192 | /** 193 | * Test a > combinator 194 | */ 195 | START_TEST (test_gt_combinator) 196 | { 197 | xQSearchExpr* expr; 198 | xQStatusCode status; 199 | 200 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1 > elem2"); 201 | 202 | ck_assert(status == XQ_OK); 203 | ck_assert(expr->operation == _xQ_findDescendantsByName); 204 | ck_assert(expr->argc == 2); 205 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 206 | ck_assert(expr->argv[1] == 0); 207 | ck_assert(expr->next != 0); 208 | 209 | ck_assert(expr->next->operation == _xQ_findChildrenByName); 210 | ck_assert(expr->next->argc == 2); 211 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"elem2") == 0); 212 | ck_assert(expr->next->argv[1] == 0); 213 | ck_assert(expr->next->next == 0); 214 | 215 | xQSearchExpr_free(expr); 216 | } 217 | END_TEST 218 | 219 | /** 220 | * Test a single attribute condition 221 | */ 222 | START_TEST (test_single_attr) 223 | { 224 | xQSearchExpr* expr; 225 | xQStatusCode status; 226 | 227 | // string value 228 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1[attr=\"value\"]"); 229 | 230 | ck_assert(status == XQ_OK); 231 | ck_assert(expr->operation == _xQ_findDescendantsByName); 232 | ck_assert(expr->argc == 2); 233 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 234 | ck_assert(expr->argv[1] == 0); 235 | ck_assert(expr->next != 0); 236 | 237 | ck_assert(expr->next->operation == _xQ_filterAttributeEquals); 238 | ck_assert(expr->next->argc == 2); 239 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"attr") == 0); 240 | ck_assert(xmlStrcmp(expr->next->argv[1], (xmlChar*)"value") == 0); 241 | ck_assert(expr->next->next == 0); 242 | 243 | xQSearchExpr_free(expr); 244 | 245 | 246 | // ident value 247 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1[attr=value]"); 248 | 249 | ck_assert(status == XQ_OK); 250 | ck_assert(expr->operation == _xQ_findDescendantsByName); 251 | ck_assert(expr->argc == 2); 252 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 253 | ck_assert(expr->argv[1] == 0); 254 | ck_assert(expr->next != 0); 255 | 256 | ck_assert(expr->next->operation == _xQ_filterAttributeEquals); 257 | ck_assert(expr->next->argc == 2); 258 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"attr") == 0); 259 | ck_assert(xmlStrcmp(expr->next->argv[1], (xmlChar*)"value") == 0); 260 | ck_assert(expr->next->next == 0); 261 | 262 | xQSearchExpr_free(expr); 263 | } 264 | END_TEST 265 | 266 | /** 267 | * Test a single attribute condition followed by a combinator 268 | */ 269 | START_TEST (test_single_attr_combinator) 270 | { 271 | xQSearchExpr* expr; 272 | xQStatusCode status; 273 | 274 | // string value 275 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1[attr=\"value\"] + elem2"); 276 | 277 | ck_assert(status == XQ_OK); 278 | ck_assert(expr->operation == _xQ_findDescendantsByName); 279 | ck_assert(expr->argc == 2); 280 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 281 | ck_assert(expr->argv[1] == 0); 282 | ck_assert(expr->next != 0); 283 | 284 | ck_assert(expr->next->operation == _xQ_filterAttributeEquals); 285 | ck_assert(expr->next->argc == 2); 286 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"attr") == 0); 287 | ck_assert(xmlStrcmp(expr->next->argv[1], (xmlChar*)"value") == 0); 288 | ck_assert(expr->next->next != 0); 289 | 290 | ck_assert(expr->next->next->operation == _xQ_findNextSiblingByName); 291 | ck_assert(expr->next->next->argc == 2); 292 | ck_assert(xmlStrcmp(expr->next->next->argv[0], (xmlChar*)"elem2") == 0); 293 | ck_assert(expr->next->next->argv[1] == 0); 294 | ck_assert(expr->next->next->next == 0); 295 | 296 | xQSearchExpr_free(expr); 297 | } 298 | END_TEST 299 | 300 | /** 301 | * Test a dual attribute condition 302 | */ 303 | START_TEST (test_dual_attr) 304 | { 305 | xQSearchExpr* expr; 306 | xQStatusCode status; 307 | 308 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem1[attr=\"value\"][attr2=\"value2\"]"); 309 | 310 | ck_assert(status == XQ_OK); 311 | ck_assert(expr->operation == _xQ_findDescendantsByName); 312 | ck_assert(expr->argc == 2); 313 | ck_assert(xmlStrcmp(expr->argv[0], (xmlChar*)"elem1") == 0); 314 | ck_assert(expr->argv[1] == 0); 315 | ck_assert(expr->next != 0); 316 | 317 | ck_assert(expr->next->operation == _xQ_filterAttributeEquals); 318 | ck_assert(expr->next->argc == 2); 319 | ck_assert(xmlStrcmp(expr->next->argv[0], (xmlChar*)"attr") == 0); 320 | ck_assert(xmlStrcmp(expr->next->argv[1], (xmlChar*)"value") == 0); 321 | ck_assert(expr->next->next != 0); 322 | 323 | ck_assert(expr->next->next->operation == _xQ_filterAttributeEquals); 324 | ck_assert(expr->next->next->argc == 2); 325 | ck_assert(xmlStrcmp(expr->next->next->argv[0], (xmlChar*)"attr2") == 0); 326 | ck_assert(xmlStrcmp(expr->next->next->argv[1], (xmlChar*)"value2") == 0); 327 | ck_assert(expr->next->next->next == 0); 328 | 329 | xQSearchExpr_free(expr); 330 | } 331 | END_TEST 332 | 333 | /** 334 | * Test invalid expressions 335 | */ 336 | START_TEST (test_invalid_expressions) 337 | { 338 | xQSearchExpr* expr; 339 | xQStatusCode status; 340 | 341 | // string 342 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"'elem'"); 343 | ck_assert(status != XQ_OK); 344 | ck_assert(expr == 0); 345 | 346 | // + empty 347 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"+"); 348 | ck_assert(status != XQ_OK); 349 | ck_assert(expr == 0); 350 | 351 | // > empty 352 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)">"); 353 | ck_assert(status != XQ_OK); 354 | ck_assert(expr == 0); 355 | 356 | // = 357 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"= elem"); 358 | ck_assert(status != XQ_OK); 359 | ck_assert(expr == 0); 360 | 361 | // incomplete attrib 362 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem[foo"); 363 | ck_assert(status != XQ_OK); 364 | ck_assert(expr == 0); 365 | 366 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem[foo="); 367 | ck_assert(status != XQ_OK); 368 | ck_assert(expr == 0); 369 | 370 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem[foo=bar"); 371 | ck_assert(status != XQ_OK); 372 | ck_assert(expr == 0); 373 | 374 | // invalid attrib 375 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem[foo 'bar']"); 376 | ck_assert(status != XQ_OK); 377 | ck_assert(expr == 0); 378 | 379 | // unterminated string 380 | status = xQSearchExpr_alloc_init(&expr, (xmlChar*)"elem[foo=\"bar]"); 381 | ck_assert(status == XQ_INVALID_SEL_UNTERMINATED_STR); 382 | ck_assert(expr == 0); 383 | 384 | } 385 | END_TEST 386 | 387 | 388 | 389 | /** 390 | * Test suite 391 | */ 392 | Suite* search_suite() { 393 | Suite* s = suite_create("xQ search"); 394 | 395 | singleTestCase(s, tc_empty, "empty", test_empty_selector); 396 | singleTestCase(s, tc_single, "single", test_single_selector); 397 | singleTestCase(s, tc_ns_single, "namespace", test_ns_selector); 398 | singleTestCase(s, tc_dual, "dual", test_dual_selector); 399 | singleTestCase(s, tc_ns_dual, "dual namespace", test_dual_ns_selector); 400 | singleTestCase(s, tc_wildcard, "wildcard", test_wildcard_selector); 401 | 402 | singleTestCase(s, tc_plus_combi, "+ combinator", test_plus_combinator); 403 | singleTestCase(s, tc_gt_combi, "> combinator", test_gt_combinator); 404 | 405 | singleTestCase(s, tc_single_attr, "single attrib", test_single_attr); 406 | singleTestCase(s, tc_single_attr_combi, "single attrib +", test_single_attr_combinator); 407 | singleTestCase(s, tc_dual_attr, "dual attrib", test_dual_attr); 408 | 409 | singleTestCase(s, tc_invalid_expr, "invalid expressions", test_invalid_expressions); 410 | 411 | return s; 412 | } 413 | 414 | 415 | int main() { 416 | int numFailed; 417 | Suite* s = search_suite(); 418 | SRunner *sr = srunner_create(s); 419 | 420 | srunner_run_all(sr, CK_NORMAL); 421 | 422 | numFailed = srunner_ntests_failed(sr); 423 | 424 | srunner_free(sr); 425 | 426 | return (numFailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 427 | } 428 | -------------------------------------------------------------------------------- /deps/libxq/tests/check_xq.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | 22 | #define singleTestCase(suite, var, name, test) do { \ 23 | TCase* var = tcase_create(name); \ 24 | tcase_add_test(var, test); \ 25 | suite_add_tcase(s, var); \ 26 | } while(0) 27 | 28 | /** 29 | * Test addNamespace/namespaceForPrefix 30 | */ 31 | START_TEST (test_ns_prefixes) 32 | { 33 | xQ* x; 34 | xQStatusCode status; 35 | 36 | status = xQ_alloc_init(&x); 37 | ck_assert(status == XQ_OK); 38 | 39 | ck_assert(xQ_namespaceForPrefix(x, (xmlChar*)"nsA") == 0); 40 | 41 | status = xQ_addNamespace(x, (xmlChar*)"nsA", (xmlChar*)"http://csv.comcast.com/A"); 42 | ck_assert(status == XQ_OK); 43 | 44 | status = xQ_addNamespace(x, (xmlChar*)"nsB", (xmlChar*)"http://csv.comcast.com/B"); 45 | ck_assert(status == XQ_OK); 46 | 47 | ck_assert(xmlStrcmp(xQ_namespaceForPrefix(x, (xmlChar*)"nsA"), (xmlChar*)"http://csv.comcast.com/A") == 0); 48 | ck_assert(xmlStrcmp(xQ_namespaceForPrefix(x, (xmlChar*)"nsB"), (xmlChar*)"http://csv.comcast.com/B") == 0); 49 | ck_assert(xQ_namespaceForPrefix(x, (xmlChar*)"nsC") == 0); 50 | 51 | xQ_free(x, 1); 52 | } 53 | END_TEST 54 | 55 | /** 56 | * Test find with namespace 57 | */ 58 | START_TEST (test_ns_find) 59 | { 60 | xQ* x; 61 | xQ* x2; 62 | xQStatusCode status; 63 | const char* xml = "AB"; 64 | int xmlLen = strlen(xml); 65 | xmlDocPtr doc; 66 | xmlChar* txt; 67 | 68 | status = xQ_alloc_initMemory(&x, xml, xmlLen, &doc); 69 | ck_assert(status == XQ_OK); 70 | 71 | status = xQ_addNamespace(x, (xmlChar*)"nsA", (xmlChar*)"http://csv.comcast.com/A"); 72 | ck_assert(status == XQ_OK); 73 | 74 | status = xQ_addNamespace(x, (xmlChar*)"nsB", (xmlChar*)"http://csv.comcast.com/B"); 75 | ck_assert(status == XQ_OK); 76 | 77 | 78 | status = xQ_find(x, (xmlChar*)"nsA:item", &x2); 79 | 80 | ck_assert(status == XQ_OK); 81 | ck_assert(xQ_length(x2) == 1); 82 | ck_assert(xmlStrcmp((txt = xQ_getText(x2)), (xmlChar*)"A") == 0); 83 | 84 | xmlFree(txt); 85 | xQ_free(x2, 1); 86 | 87 | 88 | status = xQ_find(x, (xmlChar*)"nsB:item", &x2); 89 | 90 | ck_assert(status == XQ_OK); 91 | ck_assert(xQ_length(x2) == 1); 92 | ck_assert(xmlStrcmp((txt = xQ_getText(x2)), (xmlChar*)"B") == 0); 93 | 94 | xmlFree(txt); 95 | xQ_free(x2, 1); 96 | 97 | 98 | status = xQ_find(x, (xmlChar*)"item", &x2); 99 | 100 | ck_assert(status == XQ_OK); 101 | ck_assert(xQ_length(x2) == 2); 102 | ck_assert(xmlStrcmp((txt = xQ_getText(x2)), (xmlChar*)"A") == 0); 103 | 104 | xmlFree(txt); 105 | xQ_free(x2, 1); 106 | 107 | 108 | status = xQ_find(x, (xmlChar*)"nsC:item", &x2); 109 | ck_assert(status == XQ_UNKNOWN_NS_PREFIX); 110 | 111 | xQ_free(x, 1); 112 | 113 | xmlFreeDoc(doc); 114 | } 115 | END_TEST 116 | 117 | /** 118 | * Test xml 119 | */ 120 | START_TEST (test_xml_no_children) 121 | { 122 | xQ* x; 123 | xQ* x2; 124 | xQStatusCode status; 125 | const char* xml = ""; 126 | int xmlLen = strlen(xml); 127 | xmlDocPtr doc; 128 | xmlChar* txt; 129 | 130 | status = xQ_alloc_initMemory(&x, xml, xmlLen, &doc); 131 | ck_assert(status == XQ_OK); 132 | 133 | status = xQ_find(x, (xmlChar*)"hello", &x2); 134 | 135 | ck_assert(status == XQ_OK); 136 | ck_assert(xQ_length(x2) == 1); 137 | ck_assert(xmlStrcmp((txt = xQ_getXml(x2)), (xmlChar*)"") == 0); 138 | 139 | xmlFree(txt); 140 | xQ_free(x2, 1); 141 | 142 | xQ_free(x, 1); 143 | 144 | xmlFreeDoc(doc); 145 | } 146 | END_TEST 147 | 148 | 149 | 150 | /** 151 | * Test suite 152 | */ 153 | Suite* search_suite() { 154 | Suite* s = suite_create("xQ"); 155 | 156 | singleTestCase(s, tc_ns_prefixes, "namespace prefixes", test_ns_prefixes); 157 | 158 | singleTestCase(s, tc_ns_find, "find with namespace", test_ns_find); 159 | 160 | singleTestCase(s, tc_xml_no_children, "xml without children", test_xml_no_children); 161 | 162 | return s; 163 | } 164 | 165 | 166 | int main() { 167 | int numFailed; 168 | Suite* s = search_suite(); 169 | SRunner *sr = srunner_create(s); 170 | 171 | srunner_run_all(sr, CK_NORMAL); 172 | 173 | numFailed = srunner_ntests_failed(sr); 174 | 175 | srunner_free(sr); 176 | 177 | return (numFailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 178 | } 179 | -------------------------------------------------------------------------------- /deps/libxq/traverse.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Tree traversal routines 19 | */ 20 | 21 | #include "libxq.h" 22 | 23 | #include 24 | 25 | // namespace macros 26 | #define nsLookup(ctx,ns) \ 27 | if ((ns) && ((ns) != XQ_EMPTY_NAMESPACE)) { \ 28 | if (!((ns) = xQ_namespaceForPrefix((ctx), (ns)))) \ 29 | return XQ_UNKNOWN_NS_PREFIX; \ 30 | } 31 | 32 | #define nsMatch(node,nsuri) \ 33 | ( (!(nsuri)) || \ 34 | ((nsuri) == XQ_EMPTY_NAMESPACE && (!(node)->ns)) || \ 35 | ((node)->ns && (xmlStrcmp((node)->ns->href, (nsuri)) == 0)) ) 36 | 37 | /** 38 | * Search all decendants of node for elements and populate the output 39 | * list with the results. 40 | * 41 | * Returns a 0 (XQ_OK) on success, an error code otherwise 42 | */ 43 | xQStatusCode _xQ_findDescendants(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 44 | xQStatusCode result = XQ_OK; 45 | xmlNodePtr cur = node ? node->children : node; 46 | 47 | while (cur && result == XQ_OK) { 48 | 49 | if (cur->type == XML_ELEMENT_NODE) { 50 | result = xQNodeList_push(outList, cur); 51 | 52 | if (cur->children && result == XQ_OK) 53 | result = _xQ_findDescendants(context, args, cur, outList); 54 | } 55 | 56 | cur = cur->next; 57 | } 58 | 59 | return result; 60 | } 61 | 62 | /** 63 | * Search all decendants of node for elements matching name and populate 64 | * the output list with the results. 65 | * 66 | * Returns a 0 (XQ_OK) on success, an error code otherwise 67 | */ 68 | xQStatusCode _xQ_findDescendantsByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 69 | const xmlChar* name = args[0]; 70 | const xmlChar* ns = args[1]; 71 | xQStatusCode result = XQ_OK; 72 | xmlNodePtr cur = node ? node->children : node; 73 | 74 | nsLookup(context, ns); 75 | 76 | while (cur && result == XQ_OK) { 77 | 78 | if (cur->type == XML_ELEMENT_NODE) { 79 | if ( (xmlStrcmp(name, cur->name) == 0) && nsMatch(cur, ns) ) 80 | 81 | result = xQNodeList_push(outList, cur); 82 | 83 | if (cur->children && result == XQ_OK) 84 | result = _xQ_findDescendantsByName(context, args, cur, outList); 85 | } 86 | 87 | cur = cur->next; 88 | } 89 | 90 | return result; 91 | } 92 | 93 | /** 94 | * Search immediate children of node for elements matching name and populate 95 | * the output list with the results. 96 | * 97 | * Returns a 0 (XQ_OK) on success, an error code otherwise 98 | */ 99 | xQStatusCode _xQ_findChildrenByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 100 | const xmlChar* name = args[0]; 101 | const xmlChar* ns = args[1]; 102 | xQStatusCode result = XQ_OK; 103 | xmlNodePtr cur = node ? node->children : node; 104 | 105 | nsLookup(context, ns); 106 | 107 | while (cur && result == XQ_OK) { 108 | 109 | if (cur->type == XML_ELEMENT_NODE) { 110 | if ( (xmlStrcmp(name, cur->name) == 0) && nsMatch(cur, ns) ) 111 | result = xQNodeList_push(outList, cur); 112 | } 113 | 114 | cur = cur->next; 115 | } 116 | 117 | return result; 118 | } 119 | 120 | /** 121 | * Examine next sibling of node for a matching name and the sibling to 122 | * the output list if it matches. 123 | * 124 | * Returns a 0 (XQ_OK) on success, an error code otherwise 125 | */ 126 | xQStatusCode _xQ_findNextSiblingByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 127 | const xmlChar* name = args[0]; 128 | const xmlChar* ns = args[1]; 129 | xQStatusCode result = XQ_OK; 130 | xmlNodePtr sibling; 131 | 132 | nsLookup(context, ns); 133 | 134 | if (node->type == XML_ELEMENT_NODE && (sibling = xmlNextElementSibling(node))) { 135 | if ( (xmlStrcmp(name, sibling->name) == 0) && nsMatch(sibling, ns) ) 136 | result = xQNodeList_push(outList, sibling); 137 | } 138 | 139 | return result; 140 | } 141 | 142 | /** 143 | * Copy node to the output list 144 | * 145 | * Returns a 0 (XQ_OK) on success, an error code otherwise 146 | */ 147 | xQStatusCode _xQ_addToOutput(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 148 | return xQNodeList_push(outList, node); 149 | } 150 | 151 | /** 152 | * Add the node to the output list only if it has an attribute with an 153 | * exact value. 154 | * 155 | * Returns a 0 (XQ_OK) on success, an error code otherwise 156 | */ 157 | xQStatusCode _xQ_filterAttributeEquals(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 158 | const xmlChar* name = args[0]; 159 | const xmlChar* value = args[1]; 160 | xmlChar* thisValue; 161 | xQStatusCode result = XQ_OK; 162 | 163 | if (node) { 164 | thisValue = xmlGetProp(node, name); 165 | if (thisValue) { 166 | 167 | if (xmlStrcmp(thisValue, value) == 0) 168 | result = xQNodeList_push(outList, node); 169 | 170 | xmlFree(thisValue); 171 | } 172 | } 173 | 174 | return result; 175 | } 176 | 177 | /** 178 | * Add the node to the output list only if its name matches a given value. 179 | * 180 | * Returns a 0 (XQ_OK) on success, an error code otherwise 181 | */ 182 | xQStatusCode _xQ_filterByName(xQ* context, xmlChar** args, xmlNodePtr node, xQNodeList* outList) { 183 | const xmlChar* name = args[0]; 184 | const xmlChar* ns = args[1]; 185 | xQStatusCode result = XQ_OK; 186 | 187 | nsLookup(context, ns); 188 | 189 | if (node) { 190 | 191 | if (node->type == XML_ELEMENT_NODE) { 192 | if ( (xmlStrcmp(name, node->name) == 0) && nsMatch(node, ns) ) 193 | result = xQNodeList_push(outList, node); 194 | 195 | } 196 | 197 | } 198 | 199 | return result; 200 | } 201 | -------------------------------------------------------------------------------- /deps/libxq/xqutil.h: -------------------------------------------------------------------------------- 1 | #ifndef __XQUTIL_H_INCLUDED__ 2 | #define __XQUTIL_H_INCLUDED__ 3 | /** 4 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | #include "config.h" 20 | 21 | #ifdef HAVE_INLINE 22 | #define XQINLINE inline 23 | #else 24 | #define XQINLINE 25 | #endif 26 | 27 | 28 | #endif // __XQUTIL_H_INCLUDED__ 29 | -------------------------------------------------------------------------------- /deps/xmlconfig/config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.ac by autoheader. */ 3 | 4 | /* Type cast for the gethostbyname() argument */ 5 | #define GETHOSTBYNAME_ARG_CAST /**/ 6 | 7 | /* Define to 1 if you have the header file. */ 8 | /* #undef HAVE_ANSIDECL_H */ 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_ARPA_INET_H 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_ARPA_NAMESER_H 1 15 | 16 | /* Whether struct sockaddr::__ss_family exists */ 17 | /* #undef HAVE_BROKEN_SS_FAMILY */ 18 | 19 | /* Define to 1 if you have the `class' function. */ 20 | /* #undef HAVE_CLASS */ 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #define HAVE_CTYPE_H 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_DIRENT_H 1 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #define HAVE_DLFCN_H 1 30 | 31 | /* Have dlopen based dso */ 32 | #define HAVE_DLOPEN /**/ 33 | 34 | /* Define to 1 if you have the header file. */ 35 | /* #undef HAVE_DL_H */ 36 | 37 | /* Define to 1 if you have the header file. */ 38 | #define HAVE_ERRNO_H 1 39 | 40 | /* Define to 1 if you have the header file. */ 41 | #define HAVE_FCNTL_H 1 42 | 43 | /* Define to 1 if you have the `finite' function. */ 44 | #define HAVE_FINITE 1 45 | 46 | /* Define to 1 if you have the header file. */ 47 | #define HAVE_FLOAT_H 1 48 | 49 | /* Define to 1 if you have the `fpclass' function. */ 50 | /* #undef HAVE_FPCLASS */ 51 | 52 | /* Define to 1 if you have the `fprintf' function. */ 53 | #define HAVE_FPRINTF 1 54 | 55 | /* Define to 1 if you have the `fp_class' function. */ 56 | /* #undef HAVE_FP_CLASS */ 57 | 58 | /* Define to 1 if you have the header file. */ 59 | /* #undef HAVE_FP_CLASS_H */ 60 | 61 | /* Define to 1 if you have the `ftime' function. */ 62 | #define HAVE_FTIME 1 63 | 64 | /* Define if getaddrinfo is there */ 65 | #define HAVE_GETADDRINFO /**/ 66 | 67 | /* Define to 1 if you have the `gettimeofday' function. */ 68 | #define HAVE_GETTIMEOFDAY 1 69 | 70 | /* Define to 1 if you have the header file. */ 71 | /* #undef HAVE_IEEEFP_H */ 72 | 73 | /* Define to 1 if you have the header file. */ 74 | #define HAVE_INTTYPES_H 1 75 | 76 | /* Define to 1 if you have the `isascii' function. */ 77 | #define HAVE_ISASCII 1 78 | 79 | /* Define if isinf is there */ 80 | #define HAVE_ISINF /**/ 81 | 82 | /* Define if isnan is there */ 83 | #define HAVE_ISNAN /**/ 84 | 85 | /* Define to 1 if you have the `isnand' function. */ 86 | /* #undef HAVE_ISNAND */ 87 | 88 | /* Define if history library is there (-lhistory) */ 89 | /* #undef HAVE_LIBHISTORY */ 90 | 91 | /* Have compression library */ 92 | /* #undef HAVE_LIBLZMA */ 93 | 94 | /* Define if pthread library is there (-lpthread) */ 95 | /* #undef HAVE_LIBPTHREAD */ 96 | 97 | /* Define if readline library is there (-lreadline) */ 98 | /* #undef HAVE_LIBREADLINE */ 99 | 100 | /* Have compression library */ 101 | #define HAVE_LIBZ 1 102 | 103 | /* Define to 1 if you have the header file. */ 104 | #define HAVE_LIMITS_H 1 105 | 106 | /* Define to 1 if you have the `localtime' function. */ 107 | #define HAVE_LOCALTIME 1 108 | 109 | /* Define to 1 if you have the header file. */ 110 | /* #undef HAVE_LZMA_H */ 111 | 112 | /* Define to 1 if you have the header file. */ 113 | /* #undef HAVE_MALLOC_H */ 114 | 115 | /* Define to 1 if you have the header file. */ 116 | #define HAVE_MATH_H 1 117 | 118 | /* Define to 1 if you have the header file. */ 119 | #define HAVE_MEMORY_H 1 120 | 121 | /* Define to 1 if you have the `mmap' function. */ 122 | #define HAVE_MMAP 1 123 | 124 | /* Define to 1 if you have the `munmap' function. */ 125 | #define HAVE_MUNMAP 1 126 | 127 | /* mmap() is no good without munmap() */ 128 | #if defined(HAVE_MMAP) && !defined(HAVE_MUNMAP) 129 | # undef /**/ HAVE_MMAP 130 | #endif 131 | 132 | /* Define to 1 if you have the header file. */ 133 | /* #undef HAVE_NAN_H */ 134 | 135 | /* Define to 1 if you have the header file, and it defines `DIR'. */ 136 | /* #undef HAVE_NDIR_H */ 137 | 138 | /* Define to 1 if you have the header file. */ 139 | #define HAVE_NETDB_H 1 140 | 141 | /* Define to 1 if you have the header file. */ 142 | #define HAVE_NETINET_IN_H 1 143 | 144 | /* Define to 1 if you have the header file. */ 145 | #define HAVE_POLL_H 1 146 | 147 | /* Define to 1 if you have the `printf' function. */ 148 | #define HAVE_PRINTF 1 149 | 150 | /* Define if is there */ 151 | /* #undef HAVE_PTHREAD_H */ 152 | 153 | /* Define to 1 if you have the `putenv' function. */ 154 | #define HAVE_PUTENV 1 155 | 156 | /* Define to 1 if you have the `rand' function. */ 157 | #define HAVE_RAND 1 158 | 159 | /* Define to 1 if you have the `rand_r' function. */ 160 | #define HAVE_RAND_R 1 161 | 162 | /* Define to 1 if you have the header file. */ 163 | #define HAVE_RESOLV_H 1 164 | 165 | /* Have shl_load based dso */ 166 | /* #undef HAVE_SHLLOAD */ 167 | 168 | /* Define to 1 if you have the `signal' function. */ 169 | #define HAVE_SIGNAL 1 170 | 171 | /* Define to 1 if you have the header file. */ 172 | #define HAVE_SIGNAL_H 1 173 | 174 | /* Define to 1 if you have the `snprintf' function. */ 175 | #define HAVE_SNPRINTF 1 176 | 177 | /* Define to 1 if you have the `sprintf' function. */ 178 | #define HAVE_SPRINTF 1 179 | 180 | /* Define to 1 if you have the `srand' function. */ 181 | #define HAVE_SRAND 1 182 | 183 | /* Define to 1 if you have the `sscanf' function. */ 184 | #define HAVE_SSCANF 1 185 | 186 | /* Define to 1 if you have the `stat' function. */ 187 | #define HAVE_STAT 1 188 | 189 | /* Define to 1 if you have the header file. */ 190 | #define HAVE_STDARG_H 1 191 | 192 | /* Define to 1 if you have the header file. */ 193 | #define HAVE_STDINT_H 1 194 | 195 | /* Define to 1 if you have the header file. */ 196 | #define HAVE_STDLIB_H 1 197 | 198 | /* Define to 1 if you have the `strdup' function. */ 199 | #define HAVE_STRDUP 1 200 | 201 | /* Define to 1 if you have the `strerror' function. */ 202 | #define HAVE_STRERROR 1 203 | 204 | /* Define to 1 if you have the `strftime' function. */ 205 | #define HAVE_STRFTIME 1 206 | 207 | /* Define to 1 if you have the header file. */ 208 | #define HAVE_STRINGS_H 1 209 | 210 | /* Define to 1 if you have the header file. */ 211 | #define HAVE_STRING_H 1 212 | 213 | /* Define to 1 if you have the `strndup' function. */ 214 | #define HAVE_STRNDUP 1 215 | 216 | /* Define to 1 if you have the header file, and it defines `DIR'. 217 | */ 218 | /* #undef HAVE_SYS_DIR_H */ 219 | 220 | /* Define to 1 if you have the header file. */ 221 | #define HAVE_SYS_MMAN_H 1 222 | 223 | /* Define to 1 if you have the header file, and it defines `DIR'. 224 | */ 225 | /* #undef HAVE_SYS_NDIR_H */ 226 | 227 | /* Define to 1 if you have the header file. */ 228 | #define HAVE_SYS_SELECT_H 1 229 | 230 | /* Define to 1 if you have the header file. */ 231 | #define HAVE_SYS_SOCKET_H 1 232 | 233 | /* Define to 1 if you have the header file. */ 234 | #define HAVE_SYS_STAT_H 1 235 | 236 | /* Define to 1 if you have the header file. */ 237 | #define HAVE_SYS_TIMEB_H 1 238 | 239 | /* Define to 1 if you have the header file. */ 240 | #define HAVE_SYS_TIME_H 1 241 | 242 | /* Define to 1 if you have the header file. */ 243 | #define HAVE_SYS_TYPES_H 1 244 | 245 | /* Define to 1 if you have the `time' function. */ 246 | #define HAVE_TIME 1 247 | 248 | /* Define to 1 if you have the header file. */ 249 | #define HAVE_TIME_H 1 250 | 251 | /* Define to 1 if you have the header file. */ 252 | #define HAVE_UNISTD_H 1 253 | 254 | /* Whether va_copy() is available */ 255 | #define HAVE_VA_COPY 1 256 | 257 | /* Define to 1 if you have the `vfprintf' function. */ 258 | #define HAVE_VFPRINTF 1 259 | 260 | /* Define to 1 if you have the `vsnprintf' function. */ 261 | #define HAVE_VSNPRINTF 1 262 | 263 | /* Define to 1 if you have the `vsprintf' function. */ 264 | #define HAVE_VSPRINTF 1 265 | 266 | /* Define to 1 if you have the header file. */ 267 | /* #undef HAVE_ZLIB_H */ 268 | 269 | /* Define to 1 if you have the `_stat' function. */ 270 | /* #undef HAVE__STAT */ 271 | 272 | /* Whether __va_copy() is available */ 273 | /* #undef HAVE___VA_COPY */ 274 | 275 | /* Define as const if the declaration of iconv() needs const. */ 276 | #define ICONV_CONST 277 | 278 | /* Define to the sub-directory where libtool stores uninstalled libraries. */ 279 | #define LT_OBJDIR ".libs/" 280 | 281 | /* Name of package */ 282 | #define PACKAGE "libxml2" 283 | 284 | /* Define to the address where bug reports for this package should be sent. */ 285 | #define PACKAGE_BUGREPORT "" 286 | 287 | /* Define to the full name of this package. */ 288 | #define PACKAGE_NAME "" 289 | 290 | /* Define to the full name and version of this package. */ 291 | #define PACKAGE_STRING "" 292 | 293 | /* Define to the one symbol short name of this package. */ 294 | #define PACKAGE_TARNAME "" 295 | 296 | /* Define to the home page for this package. */ 297 | #define PACKAGE_URL "" 298 | 299 | /* Define to the version of this package. */ 300 | #define PACKAGE_VERSION "" 301 | 302 | /* Type cast for the send() function 2nd arg */ 303 | #define SEND_ARG2_CAST /**/ 304 | 305 | /* Define to 1 if you have the ANSI C header files. */ 306 | #define STDC_HEADERS 1 307 | 308 | /* Support for IPv6 */ 309 | #define SUPPORT_IP6 /**/ 310 | 311 | /* Define if va_list is an array type */ 312 | #define VA_LIST_IS_ARRAY 1 313 | 314 | /* Version number of package */ 315 | #define VERSION "2.9.2" 316 | 317 | /* Determine what socket length (socklen_t) data type is */ 318 | #define XML_SOCKLEN_T socklen_t 319 | 320 | /* Define for Solaris 2.5.1 so the uint32_t typedef from , 321 | , or is not used. If the typedef were allowed, the 322 | #define below would cause a syntax error. */ 323 | /* #undef _UINT32_T */ 324 | 325 | /* Using the Win32 Socket implementation */ 326 | /* #undef _WINSOCKAPI_ */ 327 | 328 | /* ss_family is not defined here, use __ss_family instead */ 329 | /* #undef ss_family */ 330 | 331 | /* Define to the type of an unsigned integer type of width exactly 32 bits if 332 | such a type exists and the standard includes do not define it. */ 333 | /* #undef uint32_t */ 334 | -------------------------------------------------------------------------------- /deps/xmlconfig/libxml/xmlversion.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Summary: compile-time version informations 3 | * Description: compile-time version informations for the XML library 4 | * 5 | * Copy: See Copyright for the status of this software. 6 | * 7 | * Author: Daniel Veillard 8 | */ 9 | 10 | #ifndef __XML_VERSION_H__ 11 | #define __XML_VERSION_H__ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | /* 20 | * use those to be sure nothing nasty will happen if 21 | * your library and includes mismatch 22 | */ 23 | #ifndef LIBXML2_COMPILING_MSCCDEF 24 | XMLPUBFUN void XMLCALL xmlCheckVersion(int version); 25 | #endif /* LIBXML2_COMPILING_MSCCDEF */ 26 | 27 | /** 28 | * LIBXML_DOTTED_VERSION: 29 | * 30 | * the version string like "1.2.3" 31 | */ 32 | #define LIBXML_DOTTED_VERSION "2.9.2" 33 | 34 | /** 35 | * LIBXML_VERSION: 36 | * 37 | * the version number: 1.2.3 value is 10203 38 | */ 39 | #define LIBXML_VERSION 20902 40 | 41 | /** 42 | * LIBXML_VERSION_STRING: 43 | * 44 | * the version number string, 1.2.3 value is "10203" 45 | */ 46 | #define LIBXML_VERSION_STRING "20902" 47 | 48 | /** 49 | * LIBXML_VERSION_EXTRA: 50 | * 51 | * extra version information, used to show a CVS compilation 52 | */ 53 | #define LIBXML_VERSION_EXTRA "" 54 | 55 | /** 56 | * LIBXML_TEST_VERSION: 57 | * 58 | * Macro to check that the libxml version in use is compatible with 59 | * the version the software has been compiled against 60 | */ 61 | #define LIBXML_TEST_VERSION xmlCheckVersion(20902); 62 | 63 | #ifndef VMS 64 | #if 0 65 | /** 66 | * WITH_TRIO: 67 | * 68 | * defined if the trio support need to be configured in 69 | */ 70 | #define WITH_TRIO 71 | #else 72 | /** 73 | * WITHOUT_TRIO: 74 | * 75 | * defined if the trio support should not be configured in 76 | */ 77 | #define WITHOUT_TRIO 78 | #endif 79 | #else /* VMS */ 80 | /** 81 | * WITH_TRIO: 82 | * 83 | * defined if the trio support need to be configured in 84 | */ 85 | #define WITH_TRIO 1 86 | #endif /* VMS */ 87 | 88 | /** 89 | * LIBXML_THREAD_ENABLED: 90 | * 91 | * Whether the thread support is configured in 92 | */ 93 | #if 1 94 | #if defined(_REENTRANT) || defined(__MT__) || \ 95 | (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L)) 96 | #define LIBXML_THREAD_ENABLED 97 | #endif 98 | #endif 99 | 100 | /** 101 | * LIBXML_THREAD_ALLOC_ENABLED: 102 | * 103 | * Whether the allocation hooks are per-thread 104 | */ 105 | #if 0 106 | #define LIBXML_THREAD_ALLOC_ENABLED 107 | #endif 108 | 109 | /** 110 | * LIBXML_TREE_ENABLED: 111 | * 112 | * Whether the DOM like tree manipulation API support is configured in 113 | */ 114 | #if 1 115 | #define LIBXML_TREE_ENABLED 116 | #endif 117 | 118 | /** 119 | * LIBXML_OUTPUT_ENABLED: 120 | * 121 | * Whether the serialization/saving support is configured in 122 | */ 123 | #if 1 124 | #define LIBXML_OUTPUT_ENABLED 125 | #endif 126 | 127 | /** 128 | * LIBXML_PUSH_ENABLED: 129 | * 130 | * Whether the push parsing interfaces are configured in 131 | */ 132 | #if 1 133 | #define LIBXML_PUSH_ENABLED 134 | #endif 135 | 136 | /** 137 | * LIBXML_READER_ENABLED: 138 | * 139 | * Whether the xmlReader parsing interface is configured in 140 | */ 141 | #if 1 142 | #define LIBXML_READER_ENABLED 143 | #endif 144 | 145 | /** 146 | * LIBXML_PATTERN_ENABLED: 147 | * 148 | * Whether the xmlPattern node selection interface is configured in 149 | */ 150 | #if 1 151 | #define LIBXML_PATTERN_ENABLED 152 | #endif 153 | 154 | /** 155 | * LIBXML_WRITER_ENABLED: 156 | * 157 | * Whether the xmlWriter saving interface is configured in 158 | */ 159 | #if 1 160 | #define LIBXML_WRITER_ENABLED 161 | #endif 162 | 163 | /** 164 | * LIBXML_SAX1_ENABLED: 165 | * 166 | * Whether the older SAX1 interface is configured in 167 | */ 168 | #if 1 169 | #define LIBXML_SAX1_ENABLED 170 | #endif 171 | 172 | /** 173 | * LIBXML_FTP_ENABLED: 174 | * 175 | * Whether the FTP support is configured in 176 | */ 177 | #if 1 178 | #define LIBXML_FTP_ENABLED 179 | #endif 180 | 181 | /** 182 | * LIBXML_HTTP_ENABLED: 183 | * 184 | * Whether the HTTP support is configured in 185 | */ 186 | #if 1 187 | #define LIBXML_HTTP_ENABLED 188 | #endif 189 | 190 | /** 191 | * LIBXML_VALID_ENABLED: 192 | * 193 | * Whether the DTD validation support is configured in 194 | */ 195 | #if 1 196 | #define LIBXML_VALID_ENABLED 197 | #endif 198 | 199 | /** 200 | * LIBXML_HTML_ENABLED: 201 | * 202 | * Whether the HTML support is configured in 203 | */ 204 | #if 1 205 | #define LIBXML_HTML_ENABLED 206 | #endif 207 | 208 | /** 209 | * LIBXML_LEGACY_ENABLED: 210 | * 211 | * Whether the deprecated APIs are compiled in for compatibility 212 | */ 213 | #if 1 214 | #define LIBXML_LEGACY_ENABLED 215 | #endif 216 | 217 | /** 218 | * LIBXML_C14N_ENABLED: 219 | * 220 | * Whether the Canonicalization support is configured in 221 | */ 222 | #if 1 223 | #define LIBXML_C14N_ENABLED 224 | #endif 225 | 226 | /** 227 | * LIBXML_CATALOG_ENABLED: 228 | * 229 | * Whether the Catalog support is configured in 230 | */ 231 | #if 1 232 | #define LIBXML_CATALOG_ENABLED 233 | #endif 234 | 235 | /** 236 | * LIBXML_DOCB_ENABLED: 237 | * 238 | * Whether the SGML Docbook support is configured in 239 | */ 240 | #if 1 241 | #define LIBXML_DOCB_ENABLED 242 | #endif 243 | 244 | /** 245 | * LIBXML_XPATH_ENABLED: 246 | * 247 | * Whether XPath is configured in 248 | */ 249 | #if 1 250 | #define LIBXML_XPATH_ENABLED 251 | #endif 252 | 253 | /** 254 | * LIBXML_XPTR_ENABLED: 255 | * 256 | * Whether XPointer is configured in 257 | */ 258 | #if 1 259 | #define LIBXML_XPTR_ENABLED 260 | #endif 261 | 262 | /** 263 | * LIBXML_XINCLUDE_ENABLED: 264 | * 265 | * Whether XInclude is configured in 266 | */ 267 | #if 1 268 | #define LIBXML_XINCLUDE_ENABLED 269 | #endif 270 | 271 | /** 272 | * LIBXML_ICONV_ENABLED: 273 | * 274 | * Whether iconv support is available 275 | */ 276 | #if 1 277 | #define LIBXML_ICONV_ENABLED 278 | #endif 279 | 280 | /** 281 | * LIBXML_ICU_ENABLED: 282 | * 283 | * Whether icu support is available 284 | */ 285 | #if 0 286 | #define LIBXML_ICU_ENABLED 287 | #endif 288 | 289 | /** 290 | * LIBXML_ISO8859X_ENABLED: 291 | * 292 | * Whether ISO-8859-* support is made available in case iconv is not 293 | */ 294 | #if 1 295 | #define LIBXML_ISO8859X_ENABLED 296 | #endif 297 | 298 | /** 299 | * LIBXML_DEBUG_ENABLED: 300 | * 301 | * Whether Debugging module is configured in 302 | */ 303 | #if 1 304 | #define LIBXML_DEBUG_ENABLED 305 | #endif 306 | 307 | /** 308 | * DEBUG_MEMORY_LOCATION: 309 | * 310 | * Whether the memory debugging is configured in 311 | */ 312 | #if 0 313 | #define DEBUG_MEMORY_LOCATION 314 | #endif 315 | 316 | /** 317 | * LIBXML_DEBUG_RUNTIME: 318 | * 319 | * Whether the runtime debugging is configured in 320 | */ 321 | #if 0 322 | #define LIBXML_DEBUG_RUNTIME 323 | #endif 324 | 325 | /** 326 | * LIBXML_UNICODE_ENABLED: 327 | * 328 | * Whether the Unicode related interfaces are compiled in 329 | */ 330 | #if 1 331 | #define LIBXML_UNICODE_ENABLED 332 | #endif 333 | 334 | /** 335 | * LIBXML_REGEXP_ENABLED: 336 | * 337 | * Whether the regular expressions interfaces are compiled in 338 | */ 339 | #if 1 340 | #define LIBXML_REGEXP_ENABLED 341 | #endif 342 | 343 | /** 344 | * LIBXML_AUTOMATA_ENABLED: 345 | * 346 | * Whether the automata interfaces are compiled in 347 | */ 348 | #if 1 349 | #define LIBXML_AUTOMATA_ENABLED 350 | #endif 351 | 352 | /** 353 | * LIBXML_EXPR_ENABLED: 354 | * 355 | * Whether the formal expressions interfaces are compiled in 356 | */ 357 | #if 1 358 | #define LIBXML_EXPR_ENABLED 359 | #endif 360 | 361 | /** 362 | * LIBXML_SCHEMAS_ENABLED: 363 | * 364 | * Whether the Schemas validation interfaces are compiled in 365 | */ 366 | #if 1 367 | #define LIBXML_SCHEMAS_ENABLED 368 | #endif 369 | 370 | /** 371 | * LIBXML_SCHEMATRON_ENABLED: 372 | * 373 | * Whether the Schematron validation interfaces are compiled in 374 | */ 375 | #if 1 376 | #define LIBXML_SCHEMATRON_ENABLED 377 | #endif 378 | 379 | /** 380 | * LIBXML_MODULES_ENABLED: 381 | * 382 | * Whether the module interfaces are compiled in 383 | */ 384 | #if 1 385 | #define LIBXML_MODULES_ENABLED 386 | /** 387 | * LIBXML_MODULE_EXTENSION: 388 | * 389 | * the string suffix used by dynamic modules (usually shared libraries) 390 | */ 391 | #define LIBXML_MODULE_EXTENSION ".so" 392 | #endif 393 | 394 | /** 395 | * LIBXML_ZLIB_ENABLED: 396 | * 397 | * Whether the Zlib support is compiled in 398 | */ 399 | #if 1 400 | #define LIBXML_ZLIB_ENABLED 401 | #endif 402 | 403 | /** 404 | * LIBXML_LZMA_ENABLED: 405 | * 406 | * Whether the Lzma support is compiled in 407 | */ 408 | #if 0 409 | #define LIBXML_LZMA_ENABLED 410 | #endif 411 | 412 | #ifdef __GNUC__ 413 | #ifdef HAVE_ANSIDECL_H 414 | #include 415 | #endif 416 | 417 | /** 418 | * ATTRIBUTE_UNUSED: 419 | * 420 | * Macro used to signal to GCC unused function parameters 421 | */ 422 | 423 | #ifndef ATTRIBUTE_UNUSED 424 | # if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7))) 425 | # define ATTRIBUTE_UNUSED __attribute__((unused)) 426 | # else 427 | # define ATTRIBUTE_UNUSED 428 | # endif 429 | #endif 430 | 431 | /** 432 | * LIBXML_ATTR_ALLOC_SIZE: 433 | * 434 | * Macro used to indicate to GCC this is an allocator function 435 | */ 436 | 437 | #ifndef LIBXML_ATTR_ALLOC_SIZE 438 | # if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) 439 | # define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x))) 440 | # else 441 | # define LIBXML_ATTR_ALLOC_SIZE(x) 442 | # endif 443 | #else 444 | # define LIBXML_ATTR_ALLOC_SIZE(x) 445 | #endif 446 | 447 | /** 448 | * LIBXML_ATTR_FORMAT: 449 | * 450 | * Macro used to indicate to GCC the parameter are printf like 451 | */ 452 | 453 | #ifndef LIBXML_ATTR_FORMAT 454 | # if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3))) 455 | # define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args))) 456 | # else 457 | # define LIBXML_ATTR_FORMAT(fmt,args) 458 | # endif 459 | #else 460 | # define LIBXML_ATTR_FORMAT(fmt,args) 461 | #endif 462 | 463 | #else /* ! __GNUC__ */ 464 | /** 465 | * ATTRIBUTE_UNUSED: 466 | * 467 | * Macro used to signal to GCC unused function parameters 468 | */ 469 | #define ATTRIBUTE_UNUSED 470 | /** 471 | * LIBXML_ATTR_ALLOC_SIZE: 472 | * 473 | * Macro used to indicate to GCC this is an allocator function 474 | */ 475 | #define LIBXML_ATTR_ALLOC_SIZE(x) 476 | /** 477 | * LIBXML_ATTR_FORMAT: 478 | * 479 | * Macro used to indicate to GCC the parameter are printf like 480 | */ 481 | #define LIBXML_ATTR_FORMAT(fmt,args) 482 | #endif /* __GNUC__ */ 483 | 484 | #ifdef __cplusplus 485 | } 486 | #endif /* __cplusplus */ 487 | #endif 488 | 489 | 490 | -------------------------------------------------------------------------------- /ext/CharacterData.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "CharacterData.h" 17 | #include "utils.h" 18 | 19 | namespace xmlselector { 20 | 21 | 22 | v8::Persistent CharacterData::constructor; 23 | 24 | /** 25 | * Class initialization and exports 26 | */ 27 | void CharacterData::Init(v8::Handle exports) { 28 | // create a constructor function 29 | v8::Local tpl = NanNew(New); 30 | 31 | tpl->SetClassName(NanNew("CharacterData")); 32 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 33 | 34 | // inherits from Node 35 | tpl->Inherit(NanNew(Node::constructor_template)); 36 | 37 | tpl->PrototypeTemplate()->SetAccessor(NanNew("data"), Data); 38 | tpl->PrototypeTemplate()->SetAccessor(NanNew("length"), Length); 39 | 40 | // export it 41 | NanAssignPersistent(constructor, tpl->GetFunction()); 42 | exports->Set(NanNew("CharacterData"), tpl->GetFunction()); 43 | } 44 | 45 | /** 46 | * Constructor 47 | */ 48 | CharacterData::CharacterData(xmlNodePtr n) : Node(n) { 49 | } 50 | 51 | /** 52 | * Destructor 53 | */ 54 | CharacterData::~CharacterData() { 55 | } 56 | 57 | /** 58 | * `new CharacterData` 59 | */ 60 | NAN_METHOD(CharacterData::New) { 61 | NanScope(); 62 | 63 | // must be invoked as `new CharacterData()` 64 | if ( (! args.IsConstructCall()) || (! (args.Length() == 0)) ) 65 | ThrowEx("CharacterData constructor called incorrectly"); 66 | 67 | CharacterData* obj = new CharacterData((xmlNodePtr)0); 68 | assertPointerValid(obj); 69 | 70 | obj->Wrap(args.This()); 71 | 72 | NanReturnThis(); 73 | } 74 | 75 | /** 76 | * data - read/write attribute - DOM Level 1 77 | */ 78 | NAN_PROPERTY_GETTER(CharacterData::Data) { 79 | NanScope(); 80 | 81 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 82 | assertGotWrapper(obj); 83 | assertHasNode(obj); 84 | 85 | xmlChar* content = xmlNodeGetContent(obj->node()); 86 | 87 | if (!content) 88 | NanReturnNull(); 89 | 90 | v8::Local data = NewUtf8Handle((char*)content); 91 | 92 | xmlFree(content); 93 | 94 | NanReturnValue(data); 95 | } 96 | 97 | /** 98 | * length - readonly attribute - DOM Level 1 99 | */ 100 | NAN_PROPERTY_GETTER(CharacterData::Length) { 101 | NanScope(); 102 | 103 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 104 | assertGotWrapper(obj); 105 | 106 | if (!obj->node()) 107 | NanReturnValue(NanNew(0)); 108 | 109 | if (((obj->node()->type == XML_TEXT_NODE) || 110 | (obj->node()->type == XML_CDATA_SECTION_NODE) || 111 | (obj->node()->type == XML_COMMENT_NODE)) && 112 | (obj->node()->content) ) 113 | NanReturnValue(NanNew(xmlUTF8Strlen(obj->node()->content))); 114 | 115 | NanReturnValue(NanNew(0)); 116 | } 117 | 118 | 119 | } // namespace xmlselector 120 | -------------------------------------------------------------------------------- /ext/CharacterData.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __XMLSELECTOR_CHARACTERDATA_H_INCLUDED__ 17 | #define __XMLSELECTOR_CHARACTERDATA_H_INCLUDED__ 18 | 19 | #include "Node.h" 20 | 21 | namespace xmlselector { 22 | 23 | class CharacterData : public Node { 24 | public: 25 | static void Init(v8::Handle exports); 26 | 27 | static v8::Persistent constructor; 28 | 29 | protected: 30 | 31 | explicit CharacterData(xmlNodePtr n); 32 | virtual ~CharacterData(); 33 | 34 | static NAN_METHOD(New); 35 | 36 | static NAN_PROPERTY_GETTER(Data); 37 | static NAN_PROPERTY_GETTER(Length); 38 | 39 | }; 40 | 41 | } // namespace xmlselector 42 | 43 | #endif // __XMLSELECTOR_CHARACTERDATA_H_INCLUDED__ -------------------------------------------------------------------------------- /ext/Document.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | 18 | #include "Document.h" 19 | #include "utils.h" 20 | 21 | #include 22 | 23 | namespace xmlselector { 24 | 25 | 26 | v8::Persistent Document::constructor; 27 | 28 | /** 29 | * Class initialization and exports 30 | */ 31 | void Document::Init(v8::Handle exports) { 32 | // create a constructor function 33 | v8::Local tpl = NanNew(New); 34 | 35 | tpl->SetClassName(NanNew("Document")); 36 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 37 | 38 | // inherits from Node 39 | tpl->Inherit(NanNew(Node::constructor_template)); 40 | 41 | tpl->PrototypeTemplate()->SetAccessor(NanNew("documentElement"), DocumentElement); 42 | 43 | // export it 44 | NanAssignPersistent(constructor, tpl->GetFunction()); 45 | exports->Set(NanNew("Document"), tpl->GetFunction()); 46 | 47 | // export standalone functions 48 | exports->Set(NanNew("parseFromString"), FUNCTION_VALUE(ParseFromString)); 49 | } 50 | 51 | /** 52 | * Constructor 53 | */ 54 | Document::Document(xmlDocPtr doc) : Node((xmlNodePtr)doc) { 55 | } 56 | 57 | /** 58 | * Destructor 59 | */ 60 | Document::~Document() { 61 | if (doc()) { 62 | xmlDocPtr d = doc(); 63 | cleanTree((xmlNodePtr)d); 64 | xmlFreeDoc(d); 65 | } 66 | } 67 | 68 | /** 69 | * Cleans the tree of javascript references before deletion 70 | */ 71 | void Document::cleanTree(xmlNodePtr n) { 72 | if (n->_private) { 73 | ((Node*)n->_private)->node(0); 74 | n->_private = 0; 75 | } 76 | 77 | if (n->next) cleanTree(n->next); 78 | if (n->children) cleanTree(n->children); 79 | } 80 | 81 | /** 82 | * `new Document` 83 | */ 84 | NAN_METHOD(Document::New) { 85 | NanScope(); 86 | 87 | // must be invoked as `new Document()` 88 | if ( (! args.IsConstructCall()) || (! (args.Length() == 0)) ) 89 | ThrowEx("Document constructor called incorrectly"); 90 | 91 | Document* obj = new Document((xmlDocPtr)0); 92 | assertPointerValid(obj); 93 | 94 | obj->Wrap(args.This()); 95 | 96 | NanReturnThis(); 97 | } 98 | 99 | /** 100 | * Error handling routing for parsing 101 | */ 102 | void parseErrorHandler(void *ctx, const char *msg, ...) { 103 | va_list args; 104 | v8::Array* errors = (v8::Array*)ctx; 105 | 106 | // determine the size of the message 107 | va_start(args, msg); 108 | 109 | int strSize = vsnprintf(0, 0, msg, args); 110 | if (strSize < 1) strSize = 1024; 111 | 112 | va_end(args); 113 | 114 | // allocate memory for the formatted message 115 | char* str = new char[strSize + 1]; 116 | if (!str) return; 117 | str[0] = 0; 118 | 119 | // format it 120 | va_start(args, msg); 121 | 122 | vsnprintf(str, strSize + 1, msg, args); 123 | 124 | va_end(args); 125 | 126 | str[strSize] = 0; 127 | 128 | errors->Set(errors->Length(), NanNew(str)); 129 | 130 | delete[] str; 131 | } 132 | 133 | /** 134 | * Parse an XML document from a string 135 | */ 136 | NAN_METHOD(Document::ParseFromString) { 137 | NanScope(); 138 | 139 | v8::String::Utf8Value xmlStr(args[0]->ToString()); 140 | 141 | v8::Local errors = NanNew(); 142 | xmlSetGenericErrorFunc(*errors, parseErrorHandler); 143 | 144 | xmlDocPtr doc = xmlParseMemory((const char*) *xmlStr, xmlStr.length()); 145 | 146 | xmlSetGenericErrorFunc(0, 0); 147 | 148 | if (!doc) { 149 | v8::Local errStr; 150 | 151 | if (errors->Length() < 1) 152 | errStr = NanNew("Invalid XML"); 153 | else 154 | errStr = errors->Get(0)->ToString(); 155 | 156 | for (uint32_t i = 1; i < errors->Length(); i++) 157 | errStr = v8::String::Concat(errStr, errors->Get(i)->ToString()); 158 | 159 | ThrowEx(v8::Exception::Error(errStr)); 160 | } 161 | 162 | v8::Local retObj = NanNew(constructor)->NewInstance(); 163 | if (retObj.IsEmpty()) { 164 | xmlFreeDoc(doc); 165 | NanReturnValue(retObj); 166 | } 167 | 168 | Document* obj = node::ObjectWrap::Unwrap(retObj); 169 | if (!obj) { 170 | xmlFreeDoc(doc); 171 | NanReturnValue(retObj); 172 | } 173 | 174 | obj->doc(doc); 175 | doc->_private = obj; 176 | 177 | NanReturnValue(retObj); 178 | } 179 | 180 | /** 181 | * documentElement - readonly attribute - DOM Level 1 182 | */ 183 | NAN_PROPERTY_GETTER(Document::DocumentElement) { 184 | NanScope(); 185 | 186 | Document* obj = node::ObjectWrap::Unwrap(args.This()); 187 | assertGotWrapper(obj); 188 | assertHasNode(obj); 189 | 190 | xmlNodePtr n = obj->doc()->children; 191 | 192 | while (n) { 193 | if (n->type == XML_ELEMENT_NODE) 194 | NanReturnValue(Node::New(n)); 195 | 196 | n = n->next; 197 | } 198 | 199 | NanReturnNull(); 200 | } 201 | 202 | 203 | } // namespace xmlselector 204 | -------------------------------------------------------------------------------- /ext/Document.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __XMLSELECTOR_DOCUMENT_H_INCLUDED__ 17 | #define __XMLSELECTOR_DOCUMENT_H_INCLUDED__ 18 | 19 | #include "Node.h" 20 | 21 | namespace xmlselector { 22 | 23 | class Document : public Node { 24 | public: 25 | static void Init(v8::Handle exports); 26 | 27 | static v8::Persistent constructor; 28 | 29 | xmlDocPtr doc() { return (xmlDocPtr) _node; } 30 | 31 | protected: 32 | 33 | explicit Document(xmlDocPtr doc); 34 | virtual ~Document(); 35 | 36 | static NAN_METHOD(New); 37 | static NAN_METHOD(ParseFromString); 38 | 39 | static NAN_PROPERTY_GETTER(DocumentElement); 40 | 41 | void doc(xmlDocPtr newDoc) { node((xmlNodePtr) newDoc); } 42 | void cleanTree(xmlNodePtr n); 43 | 44 | }; 45 | 46 | } // namespace xmlselector 47 | 48 | #endif // __XMLSELECTOR_DOCUMENT_H_INCLUDED__ -------------------------------------------------------------------------------- /ext/Element.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "Element.h" 17 | #include "utils.h" 18 | 19 | namespace xmlselector { 20 | 21 | 22 | v8::Persistent Element::constructor; 23 | 24 | /** 25 | * Class initialization and exports 26 | */ 27 | void Element::Init(v8::Handle exports) { 28 | // create a constructor function 29 | v8::Local tpl = NanNew(New); 30 | 31 | tpl->SetClassName(NanNew("Element")); 32 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 33 | 34 | // inherits from Node 35 | tpl->Inherit(NanNew(Node::constructor_template)); 36 | 37 | NanSetPrototypeTemplate(tpl, "getAttribute", FUNCTION_VALUE(GetAttribute)); 38 | 39 | tpl->PrototypeTemplate()->SetAccessor(NanNew("tagName"), TagName); 40 | 41 | // export it 42 | NanAssignPersistent(constructor, tpl->GetFunction()); 43 | exports->Set(NanNew("Element"), tpl->GetFunction()); 44 | } 45 | 46 | /** 47 | * Constructor 48 | */ 49 | Element::Element(xmlElementPtr elem) : Node((xmlNodePtr)elem) { 50 | } 51 | 52 | /** 53 | * Destructor 54 | */ 55 | Element::~Element() { 56 | } 57 | 58 | /** 59 | * `new Element` 60 | */ 61 | NAN_METHOD(Element::New) { 62 | NanScope(); 63 | 64 | // must be invoked as `new Element()` 65 | if ( (! args.IsConstructCall()) || (! (args.Length() == 0)) ) 66 | ThrowEx("Element constructor called incorrectly"); 67 | 68 | Element* obj = new Element((xmlElementPtr)0); 69 | assertPointerValid(obj); 70 | 71 | obj->Wrap(args.This()); 72 | 73 | NanReturnThis(); 74 | } 75 | 76 | /** 77 | * getAttribute(name) - returns String - DOM Level 1 78 | */ 79 | NAN_METHOD(Element::GetAttribute) { 80 | NanScope(); 81 | 82 | Element* obj = node::ObjectWrap::Unwrap(args.This()); 83 | assertGotWrapper(obj); 84 | 85 | if (!obj->node()) 86 | NanReturnEmptyString(); 87 | 88 | v8::String::Utf8Value name(args[0]->ToString()); 89 | 90 | xmlChar* value = xmlGetProp(obj->node(), (const xmlChar*)*name); 91 | 92 | if (!value) 93 | NanReturnEmptyString(); 94 | 95 | v8::Local str = NewUtf8Handle((char*)value); 96 | 97 | xmlFree(value); 98 | 99 | NanReturnValue(str); 100 | } 101 | 102 | /** 103 | * tagName - readonly attribute - DOM Level 1 104 | */ 105 | NAN_PROPERTY_GETTER(Element::TagName) { 106 | NanScope(); 107 | 108 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 109 | assertGotWrapper(obj); 110 | assertHasNode(obj); 111 | 112 | if (!obj->node()->name) 113 | NanReturnNull(); 114 | else 115 | NanReturnValue(NewUtf8Handle((const char*)obj->node()->name)); 116 | } 117 | 118 | 119 | } // namespace xmlselector 120 | -------------------------------------------------------------------------------- /ext/Element.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __XMLSELECTOR_ELEMENT_H_INCLUDED__ 17 | #define __XMLSELECTOR_ELEMENT_H_INCLUDED__ 18 | 19 | #include "Node.h" 20 | 21 | namespace xmlselector { 22 | 23 | class Element : public Node { 24 | public: 25 | static void Init(v8::Handle exports); 26 | 27 | static v8::Persistent constructor; 28 | 29 | xmlElementPtr elem() { return (xmlElementPtr) _node; } 30 | 31 | protected: 32 | 33 | explicit Element(xmlElementPtr elem); 34 | virtual ~Element(); 35 | 36 | static NAN_METHOD(New); 37 | static NAN_METHOD(GetAttribute); 38 | 39 | static NAN_PROPERTY_GETTER(TagName); 40 | 41 | void elem(xmlElementPtr newElem) { node((xmlNodePtr) newElem); } 42 | 43 | }; 44 | 45 | } // namespace xmlselector 46 | 47 | #endif // __XMLSELECTOR_ELEMENT_H_INCLUDED__ -------------------------------------------------------------------------------- /ext/Node.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include "Node.h" 17 | #include "Element.h" 18 | #include "CharacterData.h" 19 | #include "utils.h" 20 | 21 | namespace xmlselector { 22 | 23 | 24 | v8::Persistent Node::constructor_template; 25 | v8::Persistent Node::constructor; 26 | 27 | /** 28 | * Class initialization and exports 29 | */ 30 | void Node::Init(v8::Handle exports) { 31 | // create a constructor function 32 | v8::Local tpl = NanNew(New); 33 | 34 | tpl->SetClassName(NanNew("Node")); 35 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 36 | 37 | NanSetPrototypeTemplate(tpl, "hasChildNodes", FUNCTION_VALUE(HasChildNodes)); 38 | 39 | tpl->PrototypeTemplate()->SetAccessor(NanNew("nodeType"), NodeType); 40 | tpl->PrototypeTemplate()->SetAccessor(NanNew("nodeName"), NodeName); 41 | tpl->PrototypeTemplate()->SetAccessor(NanNew("firstChild"), FirstChild); 42 | tpl->PrototypeTemplate()->SetAccessor(NanNew("lastChild"), LastChild); 43 | tpl->PrototypeTemplate()->SetAccessor(NanNew("parentNode"), ParentNode); 44 | tpl->PrototypeTemplate()->SetAccessor(NanNew("nextSibling"), NextSibling); 45 | tpl->PrototypeTemplate()->SetAccessor(NanNew("previousSibling"), PreviousSibling); 46 | tpl->PrototypeTemplate()->SetAccessor(NanNew("ownerDocument"), OwnerDocument); 47 | 48 | // export it 49 | NanAssignPersistent(constructor_template, tpl); 50 | NanAssignPersistent(constructor, tpl->GetFunction()); 51 | exports->Set(NanNew("Node"), tpl->GetFunction()); 52 | } 53 | 54 | /** 55 | * Constructor 56 | */ 57 | Node::Node(xmlNodePtr n) : _node(n) { 58 | } 59 | 60 | /** 61 | * Destructor 62 | */ 63 | Node::~Node() { 64 | if (_node && _node->_private) 65 | _node->_private = 0; 66 | } 67 | 68 | /** 69 | * Return the corresponding Javascript object for an XML node 70 | */ 71 | v8::Local Node::New(xmlNodePtr n) { 72 | NanEscapableScope(); 73 | 74 | if (n->_private) 75 | return NanEscapeScope(NanObjectWrapHandle( ((Node*)n->_private) )); 76 | 77 | switch (n->type) { 78 | case XML_ELEMENT_NODE: 79 | return NanEscapeScope(wrapNode(n, Element::constructor)); 80 | case XML_TEXT_NODE: 81 | case XML_CDATA_SECTION_NODE: 82 | case XML_COMMENT_NODE: 83 | return NanEscapeScope(wrapNode(n, CharacterData::constructor)); 84 | default: 85 | return NanEscapeScope(wrapNode(n, Node::constructor)); 86 | } 87 | } 88 | 89 | /** 90 | * Handles creating a new Javascript object to wrap an XML node 91 | */ 92 | v8::Local Node::wrapNode(xmlNodePtr n, v8::Persistent& ctor) { 93 | v8::Local retObj = NanNew(ctor)->NewInstance(); 94 | if (retObj.IsEmpty()) return retObj; 95 | 96 | Node* obj = node::ObjectWrap::Unwrap(retObj); 97 | if (!obj) 98 | return retObj; 99 | 100 | obj->node(n); 101 | n->_private = obj; 102 | 103 | // ensures the document remains in scope as long as some if its contents are referenced 104 | if ( n->doc && ( ((xmlNodePtr)n->doc) != n ) ) 105 | retObj->SetHiddenValue(NanNew("_doc"), Node::New((xmlNodePtr)n->doc)); 106 | 107 | return retObj; 108 | } 109 | 110 | /** 111 | * `new Node` 112 | */ 113 | NAN_METHOD(Node::New) { 114 | NanScope(); 115 | 116 | // must be invoked as `new Node()` 117 | if ( (! args.IsConstructCall()) || (! (args.Length() == 0)) ) 118 | ThrowEx("Node constructor called incorrectly"); 119 | 120 | Node* obj = new Node((xmlNodePtr)0); 121 | assertPointerValid(obj); 122 | 123 | obj->Wrap(args.This()); 124 | 125 | NanReturnThis(); 126 | } 127 | 128 | /** 129 | * hasChildNodes() - returns boolean - DOM Level 1 130 | */ 131 | NAN_METHOD(Node::HasChildNodes) { 132 | NanScope(); 133 | 134 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 135 | assertGotWrapper(obj); 136 | 137 | if (obj->node() && obj->node()->children) 138 | NanReturnValue(NanTrue()); 139 | else 140 | NanReturnValue(NanFalse()); 141 | } 142 | 143 | /** 144 | * nodeType - readonly attribute - DOM Level 1 145 | */ 146 | NAN_PROPERTY_GETTER(Node::NodeType) { 147 | NanScope(); 148 | 149 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 150 | assertGotWrapper(obj); 151 | assertHasNode(obj); 152 | 153 | NanReturnValue(NanNew((int)obj->node()->type)); 154 | } 155 | 156 | /** 157 | * nodeName - readonly attribute - DOM Level 1 158 | */ 159 | NAN_PROPERTY_GETTER(Node::NodeName) { 160 | NanScope(); 161 | 162 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 163 | assertGotWrapper(obj); 164 | assertHasNode(obj); 165 | 166 | if (!obj->node()->name) 167 | NanReturnNull(); 168 | else 169 | NanReturnValue(NewUtf8Handle((const char*)obj->node()->name)); 170 | } 171 | 172 | /** 173 | * firstChild - readonly attribute - DOM Level 1 174 | */ 175 | NAN_PROPERTY_GETTER(Node::FirstChild) { 176 | NanScope(); 177 | 178 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 179 | assertGotWrapper(obj); 180 | assertHasNode(obj); 181 | 182 | if (!obj->node()->children) 183 | NanReturnNull(); 184 | else 185 | NanReturnValue(New(obj->node()->children)); 186 | } 187 | 188 | /** 189 | * lastChild - readonly attribute - DOM Level 1 190 | */ 191 | NAN_PROPERTY_GETTER(Node::LastChild) { 192 | NanScope(); 193 | 194 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 195 | assertGotWrapper(obj); 196 | assertHasNode(obj); 197 | 198 | if (!obj->node()->last) 199 | NanReturnNull(); 200 | else 201 | NanReturnValue(New(obj->node()->last)); 202 | } 203 | 204 | /** 205 | * parentNode - readonly attribute - DOM Level 1 206 | */ 207 | NAN_PROPERTY_GETTER(Node::ParentNode) { 208 | NanScope(); 209 | 210 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 211 | assertGotWrapper(obj); 212 | assertHasNode(obj); 213 | 214 | if (!obj->node()->parent) 215 | NanReturnNull(); 216 | else 217 | NanReturnValue(New(obj->node()->parent)); 218 | } 219 | 220 | /** 221 | * nextSibling - readonly attribute - DOM Level 1 222 | */ 223 | NAN_PROPERTY_GETTER(Node::NextSibling) { 224 | NanScope(); 225 | 226 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 227 | assertGotWrapper(obj); 228 | assertHasNode(obj); 229 | 230 | if (!obj->node()->next) 231 | NanReturnNull(); 232 | else 233 | NanReturnValue(New(obj->node()->next)); 234 | } 235 | 236 | /** 237 | * previousSibling - readonly attribute - DOM Level 1 238 | */ 239 | NAN_PROPERTY_GETTER(Node::PreviousSibling) { 240 | NanScope(); 241 | 242 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 243 | assertGotWrapper(obj); 244 | assertHasNode(obj); 245 | 246 | if (!obj->node()->prev) 247 | NanReturnNull(); 248 | else 249 | NanReturnValue(New(obj->node()->prev)); 250 | } 251 | 252 | /** 253 | * ownerDocument - readonly attribute - DOM Level 1 254 | */ 255 | NAN_PROPERTY_GETTER(Node::OwnerDocument) { 256 | NanScope(); 257 | 258 | Node* obj = node::ObjectWrap::Unwrap(args.This()); 259 | assertGotWrapper(obj); 260 | assertHasNode(obj); 261 | 262 | if ( (!obj->node()->doc) || 263 | (obj->node()->type == XML_DOCUMENT_NODE && obj->node()->doc == (xmlDocPtr)obj->node()) ) 264 | NanReturnNull(); 265 | else 266 | NanReturnValue(New((xmlNodePtr)obj->node()->doc)); 267 | } 268 | 269 | 270 | } // namespace xmlselector 271 | -------------------------------------------------------------------------------- /ext/Node.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __XMLSELECTOR_NODE_H_INCLUDED__ 17 | #define __XMLSELECTOR_NODE_H_INCLUDED__ 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | namespace xmlselector { 25 | 26 | class Node : public node::ObjectWrap { 27 | public: 28 | static void Init(v8::Handle exports); 29 | 30 | static v8::Persistent constructor_template; 31 | static v8::Persistent constructor; 32 | 33 | static v8::Local New(xmlNodePtr n); 34 | 35 | xmlNodePtr node() { return _node; } 36 | void node(xmlNodePtr newNode) { _node = newNode; } 37 | 38 | protected: 39 | 40 | explicit Node(xmlNodePtr doc); 41 | virtual ~Node(); 42 | 43 | static v8::Local wrapNode(xmlNodePtr n, v8::Persistent& ctor); 44 | 45 | static NAN_METHOD(New); 46 | static NAN_METHOD(HasChildNodes); 47 | 48 | static NAN_PROPERTY_GETTER(NodeType); 49 | static NAN_PROPERTY_GETTER(NodeName); 50 | static NAN_PROPERTY_GETTER(FirstChild); 51 | static NAN_PROPERTY_GETTER(LastChild); 52 | static NAN_PROPERTY_GETTER(ParentNode); 53 | static NAN_PROPERTY_GETTER(NextSibling); 54 | static NAN_PROPERTY_GETTER(PreviousSibling); 55 | static NAN_PROPERTY_GETTER(OwnerDocument); 56 | 57 | xmlNodePtr _node; 58 | }; 59 | 60 | } // namespace xmlselector 61 | 62 | #endif // __XMLSELECTOR_NODE_H_INCLUDED__ -------------------------------------------------------------------------------- /ext/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __XMLSELECTOR_UTILS_H_INCLUDED__ 17 | #define __XMLSELECTOR_UTILS_H_INCLUDED__ 18 | 19 | #if (NODE_MODULE_VERSION > NODE_0_10_MODULE_VERSION) 20 | 21 | #define VEIGHT_ISOLATE_ARG v8::Isolate::GetCurrent(), 22 | 23 | #define ThrowEx(msg) do { NanThrowError(msg); return; } while (0); 24 | #define ReThrowEx(blk) do { blk.ReThrow(); return; } while (0); 25 | 26 | #define NewUtf8Handle(str) \ 27 | v8::String::NewFromUtf8(VEIGHT_ISOLATE_ARG (str)) 28 | 29 | #else 30 | 31 | #define VEIGHT_ISOLATE_ARG 32 | 33 | #define ThrowEx(msg) NanThrowError(msg) 34 | #define ReThrowEx(blk) return blk.ReThrow(); 35 | 36 | #define NewUtf8Handle(str) \ 37 | NanNew((str)) 38 | 39 | #endif 40 | 41 | #define assertPointerValid(ptr) \ 42 | if (!(ptr)) ThrowEx("Out of memory"); 43 | 44 | #define assertGotWrapper(ptr) \ 45 | if (!(ptr)) ThrowEx("Method invoked in an incorrect context"); 46 | 47 | #define assertHasNode(obj) \ 48 | if (!(obj)->node()) NanReturnNull(); 49 | 50 | #define FUNCTION_VALUE(f) \ 51 | NanNew(f)->GetFunction() 52 | 53 | #endif // __XMLSELECTOR_UTILS_H_INCLUDED__ 54 | -------------------------------------------------------------------------------- /ext/xQWrapper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __XQWRAPPER_H_INCLUDED__ 17 | #define __XQWRAPPER_H_INCLUDED__ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | class xQWrapper : public node::ObjectWrap { 24 | public: 25 | static void Init(v8::Handle exports); 26 | 27 | static v8::Local New(xQ* xq); 28 | 29 | protected: 30 | xQWrapper() : _xq(0) { }; 31 | xQWrapper(xQ* val) : _xq(val) { }; 32 | ~xQWrapper(); 33 | 34 | void shadowNodeList(v8::Local wrapper); 35 | 36 | static NAN_METHOD(New); 37 | static NAN_METHOD(AddNamespace); 38 | static NAN_METHOD(Attr); 39 | static NAN_METHOD(Children); 40 | static NAN_METHOD(Closest); 41 | static NAN_METHOD(Filter); 42 | static NAN_METHOD(Find); 43 | static NAN_METHOD(FindIndex); 44 | static NAN_METHOD(First); 45 | static NAN_METHOD(ForEach); 46 | static NAN_METHOD(Last); 47 | static NAN_PROPERTY_GETTER(GetLength); 48 | static NAN_METHOD(Next); 49 | static NAN_METHOD(NextAll); 50 | static NAN_METHOD(NextUntil); 51 | static NAN_METHOD(Not); 52 | static NAN_METHOD(Parent); 53 | static NAN_METHOD(Parents); 54 | static NAN_METHOD(ParentsUntil); 55 | static NAN_METHOD(Prev); 56 | static NAN_METHOD(PrevAll); 57 | static NAN_METHOD(PrevUntil); 58 | static NAN_METHOD(Text); 59 | static NAN_METHOD(Xml); 60 | 61 | static NAN_INDEX_GETTER(GetIndex); 62 | static NAN_INDEX_QUERY(QueryIndex); 63 | static NAN_INDEX_SETTER(SetIndex); 64 | static NAN_INDEX_DELETER(DeleteIndex); 65 | static NAN_INDEX_ENUMERATOR(EnumIndicies); 66 | 67 | static v8::Persistent constructor; 68 | 69 | xQ* _xq; 70 | }; 71 | 72 | #endif // __XQWRAPPER_H_INCLUDED__ 73 | -------------------------------------------------------------------------------- /ext/xqjs.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #include 17 | #include 18 | #include "xQWrapper.h" 19 | #include "Document.h" 20 | #include "Element.h" 21 | #include "CharacterData.h" 22 | 23 | using namespace v8; 24 | 25 | void RegisterModule(Handle target) { 26 | xQWrapper::Init(target); 27 | xmlselector::Node::Init(target); 28 | xmlselector::Document::Init(target); 29 | xmlselector::Element::Init(target); 30 | xmlselector::CharacterData::Init(target); 31 | } 32 | 33 | NODE_MODULE(xqjs, RegisterModule); 34 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | var xqjs = require('bindings')('xqjs') 17 | , util = require('util') 18 | ; 19 | 20 | // Add JavaScript-based utility functions 21 | 22 | /** 23 | * every function - returns true if all items pass a predicate 24 | */ 25 | xqjs.xQ.prototype.every = function(predicate, context) { 26 | return this.findIndex(function(n, idx, self) { 27 | return ! (context ? predicate.call(context, n, idx, self) : predicate(n, idx, self)); 28 | }) === -1; 29 | } 30 | 31 | /** 32 | * Modify filter function to accept a filter function or selector 33 | */ 34 | var _filter = xqjs.xQ.prototype.filter; 35 | xqjs.xQ.prototype.filter = function(selectorOrFilterFunc, context) { 36 | 37 | if ('function' == typeof selectorOrFilterFunc) { 38 | 39 | var nodes = []; 40 | 41 | this.forEach(function(value, index, q) { 42 | if (context ? selectorOrFilterFunc.call(context, value, index, q) : selectorOrFilterFunc(value, index, q)) 43 | nodes.push(value); 44 | }); 45 | 46 | return xQ(nodes); 47 | 48 | } else { 49 | 50 | return _filter.call(this, selectorOrFilterFunc); 51 | 52 | } 53 | 54 | } 55 | 56 | 57 | /** 58 | * find function 59 | */ 60 | xqjs.xQ.prototype.find = function(selectorOrPredicate, context) { 61 | 62 | if ('function' == typeof selectorOrPredicate) { 63 | 64 | var idx = this.findIndex(selectorOrPredicate, context); 65 | 66 | return idx === -1 ? undefined : this[idx]; 67 | 68 | } else { 69 | 70 | return this.search(selectorOrPredicate); 71 | 72 | } 73 | 74 | } 75 | 76 | /** 77 | * map function 78 | */ 79 | xqjs.xQ.prototype.map = function(iterator, context) { 80 | var results = []; 81 | 82 | this.forEach(function(value, index, q) { 83 | results.push(iterator.call(context, value, index, q)); 84 | }); 85 | 86 | return results; 87 | } 88 | 89 | /** 90 | * reduce function 91 | */ 92 | xqjs.xQ.prototype.reduce = function(iterator, initialValue, context) { 93 | this.forEach(function(value, index, q) { 94 | initialValue = iterator.call(this, initialValue, value, index, q); 95 | }, context); 96 | 97 | return initialValue; 98 | } 99 | 100 | /** 101 | * reduceRight function 102 | */ 103 | xqjs.xQ.prototype.reduceRight = function(iterator, initialValue, context) { 104 | for (var index = this.length; index > 0; ) { 105 | initialValue = context ? 106 | iterator.call(context, initialValue, this[--index], index, this) : 107 | iterator(initialValue, this[--index], index, this); 108 | } 109 | 110 | return initialValue; 111 | } 112 | 113 | /** 114 | * some function - returns true if any node in the list passes predicate 115 | */ 116 | xqjs.xQ.prototype.some = function(predicate, thisArg) { 117 | return this.findIndex(predicate, thisArg) !== -1; 118 | } 119 | 120 | 121 | /** 122 | * Wrap the native constructor with routines that normalize how it is 123 | * called. 124 | */ 125 | function xQ() { 126 | 127 | var nodes = []; 128 | 129 | function addArgs(args) { 130 | var len = args.length; 131 | for (var i = 0; i < len; ++i) { 132 | var a = args[i]; 133 | 134 | if (Array.isArray(a)) 135 | addArgs(a); 136 | else if ("object" === typeof a) 137 | nodes.push(a); 138 | else 139 | nodes.push(xqjs.parseFromString(String(a))); 140 | } 141 | } 142 | 143 | addArgs(arguments); 144 | 145 | return new xqjs.xQ(nodes); 146 | } 147 | 148 | util.inherits(xQ, xqjs.xQ); 149 | 150 | module.exports = xQ; 151 | module.exports.parseFromString = xqjs.parseFromString; 152 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xml-selector", 3 | "version": "0.3.0", 4 | "description": "A jQuery-like interface for working with XML using CSS-style selectors", 5 | "keywords": [ 6 | "dom", 7 | "libxml", 8 | "libxml2", 9 | "jquery", 10 | "selector", 11 | "simple", 12 | "util", 13 | "utility", 14 | "xml" 15 | ], 16 | "homepage": "https://github.com/Comcast/xml-selector", 17 | "bugs": { 18 | "url": "https://github.com/Comcast/xml-selector/issues" 19 | }, 20 | "license": "Apache-2.0", 21 | "author": "Jeffrey Hunter ", 22 | "dependencies": { 23 | "bindings": "1.2.1", 24 | "nan": "1.7.0" 25 | }, 26 | "devDependencies": { 27 | "nodeunit": "0.9.0" 28 | }, 29 | "scripts": { 30 | "test": "bin/test" 31 | }, 32 | "engines": { 33 | "node": ">=0.10.0" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/Comcast/xml-selector.git" 38 | } 39 | } -------------------------------------------------------------------------------- /test/document/character_data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | var $$ = require('../../index') 17 | ; 18 | 19 | 20 | /** 21 | * data - should return the character data 22 | */ 23 | module.exports['data - should return the character data'] = function(test) { 24 | var doc = $$.parseFromString("Hello"); 25 | test.strictEqual(doc.documentElement.firstChild.data, "Hello"); 26 | test.done(); 27 | } 28 | 29 | /** 30 | * length - should return the length of the character data 31 | */ 32 | module.exports['length - should return the length of the character data'] = function(test) { 33 | var doc = $$.parseFromString("Hello"); 34 | test.strictEqual(doc.documentElement.firstChild.length, 5); 35 | test.done(); 36 | } 37 | 38 | /** 39 | * length - should return the character count for multi-byte encodings 40 | */ 41 | module.exports['length - should return the character count for multi-byte encodings'] = function(test) { 42 | var doc = $$.parseFromString("H\u1EBDllo"); 43 | test.strictEqual(doc.documentElement.firstChild.length, 5); 44 | test.done(); 45 | } 46 | -------------------------------------------------------------------------------- /test/document/document.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | var $$ = require('../../index') 17 | ; 18 | 19 | 20 | /** 21 | * documentElement - should return the document element 22 | */ 23 | module.exports['documentElement - should return the documentElement'] = function(test) { 24 | var doc = $$.parseFromString(""); 25 | test.ok(doc.documentElement); 26 | test.strictEqual(doc.documentElement.nodeType, 1); // Node.ELEMENT_NODE 27 | test.strictEqual(doc.documentElement.nodeName, "doc"); 28 | test.done(); 29 | } 30 | -------------------------------------------------------------------------------- /test/document/element.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | var $$ = require('../../index') 17 | ; 18 | 19 | 20 | /** 21 | * getAttribute - should return the attribute value 22 | */ 23 | module.exports['getAttribute - should return the attribute value'] = function(test) { 24 | var doc = $$.parseFromString(""); 25 | test.strictEqual(doc.documentElement.getAttribute("foo"), "bar"); 26 | test.strictEqual(doc.documentElement.getAttribute("a"), "alpha"); 27 | test.done(); 28 | } 29 | 30 | /** 31 | * getAttribute - should return an empty string for no value 32 | */ 33 | module.exports['getAttribute - should return an empty string for no value'] = function(test) { 34 | var doc = $$.parseFromString(""); 35 | test.strictEqual(doc.documentElement.getAttribute("foo"), ""); 36 | test.strictEqual(doc.documentElement.getAttribute(), ""); 37 | test.done(); 38 | } 39 | 40 | /** 41 | * tagName - should return the tag name for an element 42 | */ 43 | module.exports['tagName - should return the tag name for an element'] = function(test) { 44 | var doc = $$.parseFromString(""); 45 | test.strictEqual(doc.documentElement.tagName, "doc"); 46 | test.done(); 47 | } 48 | -------------------------------------------------------------------------------- /test/document/node.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | var $$ = require('../../index') 17 | ; 18 | 19 | 20 | /** 21 | * nodeType - should return the DOM node type 22 | */ 23 | module.exports['nodeType - should return the DOM node type'] = function(test) { 24 | var doc = $$.parseFromString(""); 25 | test.strictEqual(doc.nodeType, 9); // Node.DOCUMENT_NODE 26 | test.done(); 27 | } 28 | 29 | /** 30 | * nodeName - should return the tag name for an element 31 | */ 32 | module.exports['nodeName - should return the tag name for an element'] = function(test) { 33 | var doc = $$.parseFromString(""); 34 | test.strictEqual(doc.documentElement.nodeName, "doc"); 35 | test.done(); 36 | } 37 | 38 | /** 39 | * nodeName - should allow UTF-8 encoded values 40 | */ 41 | module.exports['nodeName - should allow UTF-8 encoded values'] = function(test) { 42 | var doc = $$.parseFromString(""); 43 | test.strictEqual(doc.documentElement.nodeName, "d\u00F6c"); 44 | test.done(); 45 | } 46 | 47 | /** 48 | * firstChild - should return the first child node 49 | */ 50 | module.exports['firstChild - should return the first child node'] = function(test) { 51 | var doc = $$.parseFromString(""); 52 | test.ok(doc.documentElement.firstChild); 53 | test.strictEqual(doc.documentElement.firstChild.nodeType, 1) // Node.ELEMENT_NODE 54 | test.strictEqual(doc.documentElement.firstChild.nodeName, "a"); 55 | test.done(); 56 | } 57 | 58 | /** 59 | * firstChild - should return null for no children 60 | */ 61 | module.exports['firstChild - should return null for no children'] = function(test) { 62 | var doc = $$.parseFromString(""); 63 | test.strictEqual(doc.documentElement.firstChild, null); 64 | test.done(); 65 | } 66 | 67 | /** 68 | * lastChild - should return the last child node 69 | */ 70 | module.exports['lastChild - should return the last child node'] = function(test) { 71 | var doc = $$.parseFromString(""); 72 | test.ok(doc.documentElement.lastChild); 73 | test.strictEqual(doc.documentElement.lastChild.nodeType, 1) // Node.ELEMENT_NODE 74 | test.strictEqual(doc.documentElement.lastChild.nodeName, "c"); 75 | test.done(); 76 | } 77 | 78 | /** 79 | * lastChild - should return null for no children 80 | */ 81 | module.exports['lastChild - should return null for no children'] = function(test) { 82 | var doc = $$.parseFromString(""); 83 | test.strictEqual(doc.documentElement.lastChild, null); 84 | test.done(); 85 | } 86 | 87 | /** 88 | * parentNode - should return the parent node 89 | */ 90 | module.exports['parentNode - should return the parent node'] = function(test) { 91 | var doc = $$.parseFromString(""); 92 | var c = doc.documentElement.lastChild; 93 | test.ok(c.parentNode); 94 | test.strictEqual(c.parentNode.nodeType, 1) // Node.ELEMENT_NODE 95 | test.strictEqual(c.parentNode.nodeName, "doc"); 96 | test.done(); 97 | } 98 | 99 | /** 100 | * parentNode - should return null for the document 101 | */ 102 | module.exports['parentNode - should return null for the document'] = function(test) { 103 | var doc = $$.parseFromString(""); 104 | test.strictEqual(doc.parentNode, null); 105 | test.done(); 106 | } 107 | 108 | /** 109 | * nextSibling - should return the next sibling node 110 | */ 111 | module.exports['nextSibling - should return the next sibling node'] = function(test) { 112 | var doc = $$.parseFromString(""); 113 | var a = doc.documentElement.firstChild; 114 | test.ok(a.nextSibling); 115 | test.strictEqual(a.nextSibling.nodeType, 1) // Node.ELEMENT_NODE 116 | test.strictEqual(a.nextSibling.nodeName, "b"); 117 | test.done(); 118 | } 119 | 120 | /** 121 | * nextSibling - should return null for no next sibling 122 | */ 123 | module.exports['nextSibling - should return null for no next sibling'] = function(test) { 124 | var doc = $$.parseFromString(""); 125 | var c = doc.documentElement.lastChild; 126 | test.strictEqual(c.nextSibling, null); 127 | test.done(); 128 | } 129 | 130 | /** 131 | * previousSibling - should return the previous sibling node 132 | */ 133 | module.exports['previousSibling - should return the previous sibling node'] = function(test) { 134 | var doc = $$.parseFromString(""); 135 | var c = doc.documentElement.lastChild; 136 | test.ok(c.previousSibling); 137 | test.strictEqual(c.previousSibling.nodeType, 1) // Node.ELEMENT_NODE 138 | test.strictEqual(c.previousSibling.nodeName, "b"); 139 | test.done(); 140 | } 141 | 142 | /** 143 | * previousSibling - should return null for no previous sibling 144 | */ 145 | module.exports['previousSibling - should return null for no previous sibling'] = function(test) { 146 | var doc = $$.parseFromString(""); 147 | var a = doc.documentElement.firstChild; 148 | test.strictEqual(a.previousSibling, null); 149 | test.done(); 150 | } 151 | 152 | /** 153 | * ownerDocument - should return the document containing the node 154 | */ 155 | module.exports['ownerDocument - should return the document containing the node'] = function(test) { 156 | var doc = $$.parseFromString(""); 157 | var a = doc.documentElement.firstChild; 158 | test.ok(a.ownerDocument, null); 159 | test.strictEqual(a.ownerDocument.nodeType, 9); // Node.DOCUMENT_NODE 160 | test.done(); 161 | } 162 | 163 | /** 164 | * ownerDocument - should return null for the document 165 | */ 166 | module.exports['ownerDocument - should return null for the document'] = function(test) { 167 | var doc = $$.parseFromString(""); 168 | test.strictEqual(doc.ownerDocument, null); 169 | test.done(); 170 | } 171 | 172 | /** 173 | * hasChildNodes() - should return true for a node with children 174 | */ 175 | module.exports['hasChildNodes - should return true for a node with children'] = function(test) { 176 | var doc = $$.parseFromString(""); 177 | test.strictEqual(doc.hasChildNodes(), true); 178 | test.strictEqual(doc.documentElement.hasChildNodes(), true); 179 | test.done(); 180 | } 181 | 182 | /** 183 | * hasChildNodes() - should return false for a node without children 184 | */ 185 | module.exports['hasChildNodes - should return false for a node without children'] = function(test) { 186 | var doc = $$.parseFromString(""); 187 | test.strictEqual(doc.documentElement.hasChildNodes(), false); 188 | test.done(); 189 | } 190 | 191 | -------------------------------------------------------------------------------- /test/document/parse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | var $$ = require('../../index') 17 | ; 18 | 19 | 20 | /** 21 | * parseFromString - should create a document 22 | */ 23 | module.exports['parseFromString - should create a document'] = function(test) { 24 | var doc = $$.parseFromString(""); 25 | test.strictEqual(doc.constructor.name, 'Document'); 26 | test.done(); 27 | } 28 | 29 | /** 30 | * parseFromString - should thrown an exception for invalid XML 31 | */ 32 | module.exports['parseFromString - should thrown an exception for invalid XML'] = function(test) { 33 | test.throws(function() { var doc = $$.parseFromString("AB"); 41 | 42 | q.addNamespace("a", "http://csv.comcast.com/A"); 43 | q.addNamespace("b", "http://csv.comcast.com/B"); 44 | 45 | test.deepEqual(allXml(q.find('item')), ['A', 'B']); 46 | test.deepEqual(allXml(q.find('a:item')), ['A']); 47 | test.deepEqual(allXml(q.find('b:item')), ['B']); 48 | test.deepEqual(allXml(q.find('item').not('a:item')), ['B']); 49 | 50 | test.done(); 51 | } 52 | 53 | /** 54 | * Test invalid namespace prefix 55 | */ 56 | module.exports.testInvalidPrefix = function(test) { 57 | var q = new xQ("AB"); 58 | 59 | q.addNamespace("a", "http://csv.comcast.com/A"); 60 | q.addNamespace("b", "http://csv.comcast.com/B"); 61 | 62 | test.strictEqual(exceptionMessage(function() { q.find('c:item'); }), "Unknown namespace prefix"); 63 | 64 | test.done(); 65 | } 66 | -------------------------------------------------------------------------------- /test/xq_arrayAccess.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test array access and iteration 19 | */ 20 | 21 | var xQ = require('../index'); 22 | 23 | /** 24 | * Test array index access 25 | */ 26 | module.exports.testIndex = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty[0], undefined); 30 | 31 | var person = new xQ(''); 32 | 33 | test.strictEqual(person[10], undefined); 34 | 35 | var people = person.find('person'); 36 | test.strictEqual(people[0].getAttribute('name'), 'Fred'); 37 | test.strictEqual(people[1].getAttribute('name'), 'Sally'); 38 | test.strictEqual(people[2].getAttribute('name'), 'Jane'); 39 | test.strictEqual(people[3], undefined); 40 | 41 | test.strictEqual(person.find('missing')[0], undefined); 42 | 43 | test.done(); 44 | } 45 | 46 | /** 47 | * Test forEach 48 | */ 49 | module.exports.testForEach = function(test) { 50 | var out = []; 51 | var i = 0; 52 | 53 | var empty = new xQ(); 54 | 55 | empty.forEach(function(n, idx) { out.push([n.getAttribute('name'), idx]); }); 56 | 57 | test.ok(empty.forEach()); 58 | 59 | var person = new xQ(''); 60 | 61 | var people = person.find('person'); 62 | people.forEach(function(n, idx) { out.push([n.getAttribute('name'), idx]); }); 63 | 64 | test.throws(function() { people.forEach(function() { throw new Error("oops!"); }) }); 65 | 66 | var specialThis = {"special":true}; 67 | people.forEach(function(n, idx) { test.strictEqual(this, specialThis); }, specialThis); 68 | 69 | var missing = person.find('missing'); 70 | missing.forEach(function(n, idx) { out.push([n.getAttribute('name'), idx]); }); 71 | 72 | test.deepEqual(out, [['Fred', 0], ['Sally', 1], ['Jane', 2]]); 73 | 74 | test.done(); 75 | } 76 | -------------------------------------------------------------------------------- /test/xq_attr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test the attr() function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | /** 24 | * Test attr call on an empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty.attr("name"), undefined); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test attr call on a document 36 | */ 37 | module.exports.testDocument = function(test) { 38 | var q = new xQ(''); 39 | 40 | test.strictEqual(q.attr('name'), undefined); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test attr call on a single element 47 | */ 48 | module.exports.testSingle = function(test) { 49 | var q = new xQ(''); 50 | 51 | test.strictEqual(q.find('person').attr('name'), 'Fred'); 52 | test.strictEqual(q.find('person').attr('age'), undefined); 53 | 54 | test.done(); 55 | } 56 | 57 | /** 58 | * Test attr call on multiple elements 59 | */ 60 | module.exports.testMultiple = function(test) { 61 | var q = new xQ(''); 62 | 63 | test.strictEqual(q.find('person').attr('name'), 'Sally'); 64 | 65 | test.done(); 66 | } 67 | -------------------------------------------------------------------------------- /test/xq_available.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test that the xq extension loads 19 | */ 20 | exports.testAvailable = function(test) { 21 | var xq = require('../index'); 22 | 23 | test.ok(xq); 24 | test.strictEqual(typeof xq, 'function'); 25 | 26 | test.done(); 27 | } 28 | -------------------------------------------------------------------------------- /test/xq_children.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test children function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | function allXml(q) { return q.map(function(n) { return xQ(n).xml(); }); } 24 | 25 | /** 26 | * Test empty set 27 | */ 28 | module.exports.testEmpty = function(test) { 29 | var empty = new xQ(); 30 | 31 | test.strictEqual(empty.children().length, 0); 32 | test.strictEqual(empty.children('empty').length, 0); 33 | 34 | test.done(); 35 | } 36 | 37 | /** 38 | * Test single child 39 | */ 40 | module.exports.testSingleChild = function(test) { 41 | var q = new xQ(""); 42 | 43 | test.deepEqual(allXml(q.children()), [""]); 44 | test.deepEqual(allXml(q.children('doc')), [""]); 45 | test.deepEqual(allXml(q.children('*')), [""]); 46 | test.deepEqual(allXml(q.children('')), [""]); 47 | test.deepEqual(allXml(q.children('empty')), []); 48 | 49 | test.done(); 50 | } 51 | 52 | /** 53 | * Test multiple children with element selectors 54 | */ 55 | module.exports.testElementSelectors = function(test) { 56 | var q = new xQ("12foo3"); 57 | 58 | test.deepEqual(allXml(q.find('items').children()), ["1","2","foo","3"]); 59 | test.deepEqual(allXml(q.find('items').children('number')), ["1","2","3"]); 60 | test.deepEqual(allXml(q.find('items').children('items number')), []); 61 | 62 | test.done(); 63 | } 64 | 65 | /** 66 | * Test multiple children with attribute selectors 67 | */ 68 | module.exports.testAttributeSelectors = function(test) { 69 | var q = new xQ('AppleRed'); 70 | 71 | test.deepEqual(allXml(q.find('attrs').children('attr[name="color"]')), ["Red"]); 72 | test.deepEqual(allXml(q.find('attrs').children('attr[name="fruit"]')), ["Apple"]); 73 | 74 | test.done(); 75 | } 76 | -------------------------------------------------------------------------------- /test/xq_closest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test closest function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | function allXml(q) { return q.map(function(n) { return xQ(n).xml(); }); } 24 | 25 | /** 26 | * Test empty set 27 | */ 28 | module.exports.testEmpty = function(test) { 29 | var empty = new xQ(); 30 | 31 | test.strictEqual(empty.closest('empty').length, 0); 32 | 33 | test.done(); 34 | } 35 | 36 | /** 37 | * Test element selector 38 | */ 39 | module.exports.testElementSelector = function(test) { 40 | var q = new xQ(""); 41 | 42 | test.deepEqual(allXml(q.find('hello')), [""]); 43 | test.deepEqual(allXml(q.find('hello').closest('hello')), [""]); 44 | test.deepEqual(allXml(q.find('hello').closest('*')), [""]); 45 | test.deepEqual(allXml(q.find('hello').closest('empty')), []); 46 | test.deepEqual(allXml(q.find('hello').closest('doc hello')), []); 47 | test.deepEqual(allXml(q.find('hello').closest('doc')), [""]); 48 | 49 | test.done(); 50 | } 51 | 52 | /** 53 | * Test attribute selector 54 | */ 55 | module.exports.testAttrSelector = function(test) { 56 | var q = new xQ('AppleRed'); 57 | 58 | test.deepEqual(allXml(q.find('value').closest('attr[name="color"]')), ['Red']); 59 | test.deepEqual(allXml(q.find('value').closest('attr[name="fruit"]')), ['Apple']); 60 | 61 | test.done(); 62 | } 63 | -------------------------------------------------------------------------------- /test/xq_constructor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Constructor tests 19 | */ 20 | 21 | var xQ = require('../index'); 22 | 23 | /** 24 | * Test the empty constructor 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.ok(empty); 30 | 31 | test.strictEqual(empty.length, 0); 32 | 33 | test.done(); 34 | } 35 | 36 | /** 37 | * Test the empty constructor without new 38 | */ 39 | module.exports.testEmptySansNew = function(test) { 40 | var empty = xQ(); 41 | 42 | test.ok(empty); 43 | 44 | test.strictEqual(empty.length, 0); 45 | 46 | test.done(); 47 | } 48 | 49 | /** 50 | * Test the string constructor 51 | */ 52 | module.exports.testString = function(test) { 53 | var q = new xQ(""); 54 | 55 | test.ok(q); 56 | test.strictEqual(q.length, 1); 57 | 58 | test.done(); 59 | } 60 | 61 | /** 62 | * Test the string constructor without new 63 | */ 64 | module.exports.testStringSansNew = function(test) { 65 | var q = xQ(""); 66 | 67 | test.ok(q); 68 | test.strictEqual(q.length, 1); 69 | 70 | test.done(); 71 | } 72 | 73 | /** 74 | * Test invalid constructor calls 75 | */ 76 | module.exports.testInvalid = function(test) { 77 | test.throws(function() { 78 | new xQ("something's not right"); 79 | }); 80 | 81 | test.throws(function() { 82 | new xQ(5); 83 | }); 84 | 85 | test.done(); 86 | } 87 | 88 | /** 89 | * Test invalid constructor calls without new 90 | */ 91 | module.exports.testInvalidSansNew = function(test) { 92 | test.throws(function() { 93 | xQ("something's not right"); 94 | }); 95 | 96 | test.throws(function() { 97 | xQ(5); 98 | }); 99 | 100 | test.done(); 101 | } 102 | 103 | /** 104 | * Constructor from a document 105 | */ 106 | module.exports.testDocument = function(test) { 107 | var xml = "AppleOrangeBananaSalad"; 108 | var doc = xQ.parseFromString(xml); 109 | 110 | var q = new xQ(doc); 111 | 112 | test.ok(q); 113 | test.strictEqual(q.find('item').length, 4); 114 | 115 | test.done(); 116 | } 117 | 118 | /** 119 | * Constructor from a document without new 120 | */ 121 | module.exports.testDocumentSansNew = function(test) { 122 | var xml = "AppleOrangeBananaSalad"; 123 | var doc = xQ.parseFromString(xml); 124 | 125 | var q = xQ(doc); 126 | 127 | test.ok(q); 128 | test.strictEqual(q.find('item').length, 4); 129 | 130 | test.done(); 131 | } 132 | 133 | /** 134 | * Constructor for a single xml node 135 | */ 136 | module.exports.testSingleNode = function(test) { 137 | var xml = "AppleOrangeBananaSalad"; 138 | var doc = xQ.parseFromString(xml); 139 | 140 | var q = new xQ(doc.documentElement.firstChild); 141 | 142 | test.ok(q); 143 | test.strictEqual(q.find('item').length, 3); 144 | test.deepEqual(q.find('item').map(function(n) { return xQ(n).text(); }), ["Apple", "Orange", "Banana"]); 145 | 146 | test.done(); 147 | } 148 | 149 | /** 150 | * Constructor for a single xml node without new 151 | */ 152 | module.exports.testSingleNodeSansNew = function(test) { 153 | var xml = "AppleOrangeBananaSalad"; 154 | var doc = xQ.parseFromString(xml); 155 | 156 | var q = xQ(doc.documentElement.firstChild); 157 | 158 | test.ok(q); 159 | test.strictEqual(q.find('item').length, 3); 160 | test.deepEqual(q.find('item').map(function(n) { return xQ(n).text(); }), ["Apple", "Orange", "Banana"]); 161 | 162 | test.done(); 163 | } 164 | 165 | /** 166 | * Constructor for multiple xml nodes 167 | */ 168 | module.exports.testMultiNode = function(test) { 169 | var xml = "AppleOrangeBananaSalad"; 170 | var doc = xQ.parseFromString(xml); 171 | 172 | var a = doc.documentElement.firstChild; 173 | var b = a.nextSibling; 174 | var q = new xQ(a, b); 175 | 176 | test.ok(q); 177 | test.strictEqual(q.length, 2); 178 | test.strictEqual(q.find('item').length, 4); 179 | test.deepEqual(q.find('item').map(function(n) { return xQ(n).text(); }), ["Apple", "Orange", "Banana", "Salad"]); 180 | 181 | test.done(); 182 | } 183 | 184 | /** 185 | * Constructor for multiple xml nodes without new 186 | */ 187 | module.exports.testMultiNodeSansNew = function(test) { 188 | var xml = "AppleOrangeBananaSalad"; 189 | var doc = xQ.parseFromString(xml); 190 | 191 | var a = doc.documentElement.firstChild; 192 | var b = a.nextSibling; 193 | var q = xQ(a, b); 194 | 195 | test.ok(q); 196 | test.strictEqual(q.length, 2); 197 | test.strictEqual(q.find('item').length, 4); 198 | test.deepEqual(q.find('item').map(function(n) { return xQ(n).text(); }), ["Apple", "Orange", "Banana", "Salad"]); 199 | 200 | test.done(); 201 | } 202 | 203 | /** 204 | * Constructor for multiple xml nodes in an array 205 | */ 206 | module.exports.testArray = function(test) { 207 | var xml = "AppleOrangeBananaSalad"; 208 | var doc = xQ.parseFromString(xml); 209 | 210 | var a = doc.documentElement.firstChild; 211 | var b = a.nextSibling; 212 | var q = new xQ([a, b]); 213 | 214 | test.ok(q); 215 | test.strictEqual(q.length, 2); 216 | test.strictEqual(q.find('item').length, 4); 217 | test.deepEqual(q.find('item').map(function(n) { return xQ(n).text(); }), ["Apple", "Orange", "Banana", "Salad"]); 218 | 219 | test.done(); 220 | } 221 | 222 | /** 223 | * Constructor for multiple xml nodes in an array without new 224 | */ 225 | module.exports.testArraySansNew = function(test) { 226 | var xml = "AppleOrangeBananaSalad"; 227 | var doc = xQ.parseFromString(xml); 228 | 229 | var a = doc.documentElement.firstChild; 230 | var b = a.nextSibling; 231 | var q = xQ([a, b]); 232 | 233 | test.ok(q); 234 | test.strictEqual(q.length, 2); 235 | test.strictEqual(q.find('item').length, 4); 236 | test.deepEqual(q.find('item').map(function(n) { return xQ(n).text(); }), ["Apple", "Orange", "Banana", "Salad"]); 237 | 238 | test.done(); 239 | } 240 | -------------------------------------------------------------------------------- /test/xq_every.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the every() method 19 | */ 20 | 21 | var $$ = require('../index'); 22 | 23 | /** 24 | * Test empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var $doc = $$(); 28 | 29 | test.strictEqual($doc.every(function() { return true; }), true); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test failure 36 | */ 37 | module.exports.testFailure = function(test) { 38 | var $doc = $$('').find('fruit'); 39 | 40 | test.strictEqual($doc.every(function(elem) { 41 | return $$(elem).attr('name') == 'apple'; 42 | }), false); 43 | 44 | test.done(); 45 | } 46 | 47 | /** 48 | * Test success 49 | */ 50 | module.exports.testSuccess = function(test) { 51 | var $doc = $$('').find('fruit'); 52 | 53 | test.strictEqual($doc.every(function(elem) { 54 | return $$(elem).attr('name') != 'banana'; 55 | }), true); 56 | 57 | test.done(); 58 | } 59 | 60 | /** 61 | * Test context 62 | */ 63 | module.exports.testContext = function(test) { 64 | var out = []; 65 | var ctx = {"context": 1}; 66 | 67 | var $doc = $$('').find('fruit'); 68 | 69 | test.strictEqual($doc.every(function(elem) { 70 | out.push(this); 71 | return $$(elem).attr('name') != 'banana'; 72 | }, ctx), true); 73 | 74 | test.deepEqual(out, [ctx, ctx, ctx]); 75 | 76 | test.done(); 77 | } 78 | 79 | /** 80 | * Test args 81 | */ 82 | module.exports.testArgs = function(test) { 83 | var $doc = $$('').find('fruit'); 84 | 85 | test.strictEqual($doc.every(function(elem, idx, list) { 86 | 87 | test.strictEqual(elem, $doc[0]); 88 | test.strictEqual(idx, 0); 89 | test.strictEqual(list, $doc); 90 | 91 | return false; 92 | 93 | }), false); 94 | 95 | test.done(); 96 | } 97 | -------------------------------------------------------------------------------- /test/xq_filter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test filter function 19 | */ 20 | 21 | var xQ = require('../index'); 22 | var $$ = xQ; 23 | 24 | /** 25 | * Test empty document 26 | */ 27 | module.exports.testEmpty = function(test) { 28 | var empty = new xQ(); 29 | 30 | test.strictEqual(empty.filter().length, 0); 31 | 32 | test.done(); 33 | } 34 | 35 | /** 36 | * Test filtering from the document 37 | */ 38 | module.exports.testDocument = function(test) { 39 | var q = new xQ(""); 40 | 41 | test.strictEqual(q.filter('').length, 1); 42 | test.strictEqual(q.filter('*').length, 1); 43 | 44 | test.done(); 45 | } 46 | 47 | /** 48 | * Test filtering from an element 49 | */ 50 | module.exports.testElement = function(test) { 51 | var q = new xQ(""); 52 | 53 | test.strictEqual(q.find('hello').filter('hello').length, 1); 54 | test.strictEqual(q.find('hello').filter('hi').length, 0); 55 | 56 | test.done(); 57 | } 58 | 59 | /** 60 | * Test name filter 61 | */ 62 | module.exports.testName = function(test) { 63 | var q = new xQ("12foo3"); 64 | 65 | test.deepEqual(q.find('items *').filter('number').map(function(n) { return $$(n).text(); }), ['1', '2', '3']); 66 | 67 | test.deepEqual(q.find('items').filter('items number').length, 0); 68 | 69 | test.done(); 70 | } 71 | 72 | /** 73 | * Test attribute filtering 74 | */ 75 | module.exports.testAttribute = function(test) { 76 | var q = new xQ('AppleRed'); 77 | 78 | test.deepEqual(q.find('attr').filter('attr[name="color"]').map(function(n) { return $$(n).text(); }), ['Red']); 79 | 80 | test.deepEqual(q.find('attr').filter('attr[name="fruit"]').map(function(n) { return $$(n).text(); }), ['Apple']); 81 | 82 | test.done(); 83 | } 84 | 85 | /** 86 | * Test higher-order call on an empty set 87 | */ 88 | module.exports.testHigherOrderEmpty = function(test) { 89 | test.strictEqual($$().filter(function(n) { return true; }).length, 0); 90 | 91 | test.strictEqual($$('', '').filter(function(n) { return false; }).length, 0); 92 | 93 | test.done(); 94 | } 95 | 96 | /** 97 | * Test higher-order filter call 98 | */ 99 | module.exports.testHigherOrder = function(test) { 100 | var $attr = 101 | $$('AppleRed').find('attr'); 102 | 103 | test.deepEqual($attr.filter(function(n) { 104 | 105 | return n.getAttribute('name') == 'color'; 106 | 107 | }).map(function(n) { return $$(n).text(); }), ['Red']); 108 | 109 | test.deepEqual($attr.filter(function(n) { 110 | 111 | return n.getAttribute('name') == 'fruit'; 112 | 113 | }).map(function(n) { return $$(n).text(); }), ['Apple']); 114 | 115 | test.done(); 116 | } 117 | 118 | /** 119 | * Test higher-order context usage 120 | */ 121 | module.exports.testHigherOrderContext = function(test) { 122 | var out = []; 123 | var ctx = {"context": 1}; 124 | 125 | var $doc = $$('').find('fruit'); 126 | 127 | test.strictEqual($doc.filter(function(elem) { 128 | out.push(this); 129 | return false; 130 | }, ctx).length, 0); 131 | 132 | test.deepEqual(out, [ctx, ctx, ctx]); 133 | 134 | test.done(); 135 | } 136 | 137 | /** 138 | * Test args in higher-order usage 139 | */ 140 | module.exports.testHigherOrderArgs = function(test) { 141 | var $doc = $$('').find('fruit'); 142 | 143 | test.strictEqual($doc.filter(function(elem, idx, list) { 144 | 145 | test.strictEqual(elem, $doc[0]); 146 | test.strictEqual(idx, 0); 147 | test.strictEqual(list, $doc); 148 | 149 | return false; 150 | 151 | }).length, 0); 152 | 153 | test.done(); 154 | } 155 | -------------------------------------------------------------------------------- /test/xq_find.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the find() method 19 | */ 20 | 21 | var xQ = require('../index'); 22 | var $$ = xQ; 23 | 24 | /** 25 | * Test simple selector 26 | */ 27 | module.exports.testSimpleSelector = function(test) { 28 | var empty = new xQ(); 29 | test.strictEqual(empty.find('hello').length, 0); 30 | 31 | var hello = new xQ(""); 32 | test.strictEqual(hello.find('hello').length, 1); 33 | 34 | var items = new xQ("123"); 35 | test.strictEqual(items.find('item').length, 3); 36 | 37 | test.done(); 38 | } 39 | 40 | /** 41 | * Test multiple selectors 42 | */ 43 | module.exports.testMultipleSelector = function(test) { 44 | var pets = new xQ("FluffyFidoMr. WhiskersScratchy"); 45 | 46 | test.strictEqual(pets.find('pets cat').length, 2); 47 | 48 | test.done(); 49 | } 50 | 51 | /** 52 | * Test the attribute selector 53 | */ 54 | module.exports.testAttrSelector = function(test) { 55 | var attrEquals = 56 | new xQ('AppleRed'); 57 | 58 | var result = attrEquals.find('attr[name="color"] value'); 59 | 60 | test.strictEqual(result.length, 1); 61 | test.strictEqual(result.text(), 'Red'); 62 | 63 | test.done(); 64 | } 65 | 66 | /** 67 | * Test the > combinator 68 | */ 69 | module.exports.testImmediateCombinator = function(test) { 70 | var immediate = new xQ(''); 71 | 72 | var all = immediate.find('item'); 73 | var child = immediate.find('doc > item'); 74 | 75 | test.deepEqual(all.map(function(n) { return n.getAttribute('value'); }), ['Apple', 'Orange', 'Banana']); 76 | 77 | test.deepEqual(child.map(function(n) { return n.getAttribute('value'); }), ['Apple']); 78 | 79 | test.done(); 80 | } 81 | 82 | /** 83 | * Test the + combinator 84 | */ 85 | module.exports.testSiblingCombinator = function(test) { 86 | var siblings = new xQ(''); 87 | 88 | var orange = siblings.find('item[value="Kiwi"] + item'); 89 | 90 | test.deepEqual(orange.map(function(n) { return n.getAttribute('value'); }), ['Orange']); 91 | 92 | test.done(); 93 | } 94 | 95 | /** 96 | * Test * 97 | */ 98 | module.exports.testUniversalSelector = function(test) { 99 | var hello = new xQ(""); 100 | 101 | test.deepEqual(hello.find('*').map(function(n) { return n.nodeName; }), ['doc','hello']); 102 | 103 | var items = new xQ("123"); 104 | 105 | test.deepEqual(items.find('doc *').map(function(n) { return n.nodeName + ' (' + $$(n).text() + ')'; }), 106 | ['items (123)', 'item (1)', 'item (2)', 'item (3)']); 107 | 108 | test.done(); 109 | } 110 | 111 | /** 112 | * Test unmatched selectors 113 | */ 114 | module.exports.testUnmatchedSelector = function(test) { 115 | var hello = new xQ(""); 116 | 117 | test.strictEqual(hello.find('hi').length, 0); 118 | test.strictEqual(hello.find('doc hi').length, 0); 119 | test.strictEqual(hello.find('doc > hi').length, 0); 120 | test.strictEqual(hello.find('> hi').length, 0); 121 | test.strictEqual(hello.find('doc + hi').length, 0); 122 | test.strictEqual(hello.find('+ hi').length, 0); 123 | test.strictEqual(hello.find('doc hello *').length, 0); 124 | 125 | test.done(); 126 | } 127 | 128 | /** 129 | * Test higher-order match 130 | */ 131 | module.exports.testHigherOrderEmpty = function(test) { 132 | 133 | test.strictEqual( 134 | $$().find(function(n) { return n.getAttribute('value') == 'Apple'; }), 135 | undefined 136 | ); 137 | 138 | test.done(); 139 | } 140 | 141 | /** 142 | * Test higher-order match 143 | */ 144 | module.exports.testHigherOrderMatch = function(test) { 145 | var $set = $$('' + 146 | 'Manzana' + 147 | 'Naranja' + 148 | 'Plátano' + 149 | '').find('item'); 150 | 151 | test.strictEqual( 152 | $$($set.find(function(n) { return n.getAttribute('value') == 'Orange'; })).text(), 153 | 'Naranja' 154 | ); 155 | 156 | test.done(); 157 | } 158 | 159 | /** 160 | * Test higher-order match 161 | */ 162 | module.exports.testHigherOrderNoMatch = function(test) { 163 | var $set = $$('' + 164 | 'Manzana' + 165 | 'Naranja' + 166 | 'Plátano' + 167 | '').find('item'); 168 | 169 | test.strictEqual( 170 | $set.find(function(n) { return n.getAttribute('value') == 'Kumquat'; }), 171 | undefined 172 | ); 173 | 174 | test.done(); 175 | } 176 | 177 | /** 178 | * Test higher-order match 179 | */ 180 | module.exports.testHigherOrderContext = function(test) { 181 | var out = []; 182 | var ctx = {"context": 1}; 183 | 184 | var $set = $$('' + 185 | 'Manzana' + 186 | 'Naranja' + 187 | 'Plátano' + 188 | '').find('item'); 189 | 190 | test.strictEqual( 191 | $set.find(function(n) { out.push(this); return false; }, ctx), 192 | undefined 193 | ); 194 | 195 | test.deepEqual(out, [ctx, ctx, ctx]); 196 | 197 | test.done(); 198 | } 199 | -------------------------------------------------------------------------------- /test/xq_findIndex.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the findIndex() method 19 | */ 20 | 21 | var $$ = require('../index'); 22 | 23 | /** 24 | * Test empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var $doc = $$(); 28 | 29 | test.strictEqual($doc.findIndex(function() { return true; }), -1); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test no match 36 | */ 37 | module.exports.testNoMatch = function(test) { 38 | var $doc = $$('').find('fruit'); 39 | 40 | test.strictEqual($doc.findIndex(function(elem) { 41 | return $$(elem).attr('name') == 'banana'; 42 | }), -1); 43 | 44 | test.done(); 45 | } 46 | 47 | /** 48 | * Test first match 49 | */ 50 | module.exports.testFirstMatch = function(test) { 51 | var $doc = $$('').find('fruit'); 52 | 53 | test.strictEqual($doc.findIndex(function(elem) { 54 | return $$(elem).attr('name') == 'pear'; 55 | }), 1); 56 | 57 | test.done(); 58 | } 59 | -------------------------------------------------------------------------------- /test/xq_first.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test first function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | /** 24 | * Test empty document 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty.first().xml(), ""); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test single node in set 36 | */ 37 | module.exports.testSingle = function(test) { 38 | var q = new xQ("Hello world!"); 39 | 40 | test.strictEqual(q.first().xml(), "\nHello world!\n"); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test multiple nodes in set 47 | */ 48 | module.exports.testMultiple = function(test) { 49 | var q = new xQ("

The quick brown fox jumps...

"); 50 | 51 | test.strictEqual(q.find('i').first().xml(), "quick"); 52 | 53 | test.done(); 54 | } 55 | -------------------------------------------------------------------------------- /test/xq_invalidSelectors.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test invalid selectors 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | /** 24 | * Utility to catch an exception and return its message 25 | */ 26 | function exceptionMessage(block) { 27 | try { 28 | block(); 29 | } catch (e) { 30 | return e.message; 31 | } 32 | } 33 | 34 | /** 35 | * Test unterminated quotes 36 | */ 37 | module.exports.testUnterminatedQuote = function(test) { 38 | var empty = new xQ(); 39 | 40 | test.strictEqual(exceptionMessage(function() { empty.find("'string value"); }), "Unterminated string in selector"); 41 | 42 | test.strictEqual(exceptionMessage(function() { empty.find("\"string value"); }), "Unterminated string in selector"); 43 | 44 | test.done(); 45 | } 46 | 47 | /** 48 | * Test bad token sequence 49 | */ 50 | module.exports.testBadToken = function(test) { 51 | var empty = new xQ(); 52 | 53 | test.strictEqual(exceptionMessage(function() { empty.find(">> bad child"); }), "Invalid selector"); 54 | 55 | test.strictEqual(exceptionMessage(function() { empty.find("elem +"); }), "Invalid selector"); 56 | 57 | test.done(); 58 | } 59 | 60 | /** 61 | * Test attribute-related errors 62 | */ 63 | module.exports.testAttributes = function(test) { 64 | var empty = new xQ(); 65 | 66 | // no selector 67 | test.strictEqual(exceptionMessage(function() { empty.find("[attr=\"value\"]"); }), "Invalid selector"); 68 | 69 | // missing [ 70 | test.strictEqual(exceptionMessage(function() { empty.find("elem attr=\"value\"]"); }), "Invalid selector"); 71 | 72 | // missing = 73 | test.strictEqual(exceptionMessage(function() { empty.find("elem[attr\"value\"]"); }), "Invalid selector"); 74 | 75 | // missing string 76 | test.strictEqual(exceptionMessage(function() { empty.find("elem[attr=]"); }), "Invalid selector"); 77 | 78 | // missing ] 79 | test.strictEqual(exceptionMessage(function() { empty.find("elem[attr=\"value\""); }), "Invalid selector"); 80 | 81 | test.done(); 82 | } 83 | -------------------------------------------------------------------------------- /test/xq_last.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test last function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | /** 24 | * Test empty document 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty.last().xml(), ""); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test single node in set 36 | */ 37 | module.exports.testSingle = function(test) { 38 | var q = new xQ("Hello world!"); 39 | 40 | test.strictEqual(q.last().xml(), "\nHello world!\n"); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test multiple nodes in set 47 | */ 48 | module.exports.testMultiple = function(test) { 49 | var q = new xQ("

The quick brown fox jumps...

"); 50 | 51 | test.strictEqual(q.find('i').last().xml(), "fox"); 52 | 53 | test.done(); 54 | } 55 | -------------------------------------------------------------------------------- /test/xq_length.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test the length property 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | /** 24 | * Test length an empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty.length, 0); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test length on a single node 36 | */ 37 | module.exports.testSingle = function(test) { 38 | var q = new xQ(''); 39 | 40 | test.strictEqual(q.length, 1); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test length on a set of multiple nodes 47 | */ 48 | module.exports.testMultiple = function(test) { 49 | var q = new xQ(''); 50 | 51 | test.strictEqual(q.find('person').length, 3); 52 | 53 | test.done(); 54 | } 55 | 56 | /** 57 | * Test length on an empty set created from a search result 58 | */ 59 | module.exports.testEmptyResult = function(test) { 60 | var q = new xQ(''); 61 | 62 | test.strictEqual(q.find('missing').length, 0); 63 | 64 | test.done(); 65 | } 66 | 67 | /** 68 | * Test setting length (not allowed) 69 | */ 70 | module.exports.testSet = function(test) { 71 | var q = new xQ(''); 72 | 73 | test.strictEqual(q.length, 1); 74 | 75 | q.length = 5; 76 | 77 | test.strictEqual(q.length, 1); 78 | 79 | test.done(); 80 | } 81 | -------------------------------------------------------------------------------- /test/xq_next.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test next/nextAll/nextUntil functions 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | function allXml(q) { return q.map(function(n) { return xQ(n).xml(); }); } 24 | 25 | /** 26 | * Test empty set 27 | */ 28 | module.exports.testEmpty = function(test) { 29 | var empty = new xQ(); 30 | 31 | test.strictEqual(empty.next().length, 0); 32 | test.strictEqual(empty.next('empty').length, 0); 33 | test.strictEqual(empty.nextAll().length, 0); 34 | test.strictEqual(empty.nextAll('empty').length, 0); 35 | test.strictEqual(empty.nextUntil('empty').length, 0); 36 | 37 | test.done(); 38 | } 39 | 40 | /** 41 | * Test element selector 42 | */ 43 | module.exports.testElementSelector = function(test) { 44 | var q = new xQ("12foo3"); 45 | 46 | test.deepEqual(allXml(q.find('number').next()), ['2','foo']); 47 | test.deepEqual(allXml(q.find('number').next('string')), ['foo']); 48 | test.deepEqual(allXml(q.find('number').next('foo')), []); 49 | test.deepEqual(allXml(q.find('number').nextAll()), 50 | ['2','foo','3','foo','3']); 51 | test.deepEqual(allXml(q.find('number').nextAll('string')), ['foo','foo']); 52 | test.deepEqual(allXml(q.find('number').nextAll('foo')), []); 53 | 54 | test.done(); 55 | } 56 | 57 | /** 58 | * Test attribute selector 59 | */ 60 | module.exports.testAttributeSelector = function(test) { 61 | var q = new xQ('AppleRedSeven'); 62 | 63 | test.deepEqual(allXml(q.find('attr[name="fruit"]').next('attr[name="color"]')), ['Red']); 64 | test.deepEqual(allXml(q.find('attr[name="fruit"]').next('attr[name="number"]')), []); 65 | test.deepEqual(allXml(q.find('attr[name="fruit"]').next('attr[name="fruit"]')), []); 66 | test.deepEqual(allXml(q.find('attr[name="fruit"]').nextAll('attr[name="color"]')), ['Red']); 67 | test.deepEqual(allXml(q.find('attr[name="fruit"]').nextAll('attr[name="number"]')), ['Seven']); 68 | test.deepEqual(allXml(q.find('attr[name="fruit"]').nextAll('attr[name="fruit"]')), []); 69 | test.deepEqual(allXml(q.find('attr[name="fruit"]').nextUntil('attr[name="color"]')), []); 70 | test.deepEqual(allXml(q.find('attr[name="fruit"]').nextUntil('attr[name="number"]')), ['Red']); 71 | test.deepEqual(allXml(q.find('attr[name="fruit"]').nextUntil('attr[name="fruit"]')), 72 | ['Red','Seven']); 73 | 74 | test.done(); 75 | } 76 | -------------------------------------------------------------------------------- /test/xq_not.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test not function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | function allXml(q) { return q.map(function(n) { return xQ(n).xml(); }); } 24 | 25 | /** 26 | * Test empty set 27 | */ 28 | module.exports.testEmpty = function(test) { 29 | var empty = new xQ(); 30 | 31 | test.strictEqual(empty.not('empty').length, 0); 32 | 33 | test.done(); 34 | } 35 | 36 | /** 37 | * Test element selector 38 | */ 39 | module.exports.testElementSelector = function(test) { 40 | var q = new xQ("12foo3"); 41 | 42 | test.deepEqual(allXml(q.find('number').not('string')), ["1","2","3"]); 43 | test.deepEqual(allXml(q.find('number').not('number')), []); 44 | test.deepEqual(allXml(q.find('items *').not('number')), ["foo"]); 45 | 46 | test.done(); 47 | } 48 | 49 | /** 50 | * Test attribute selector 51 | */ 52 | module.exports.testAttrSelector = function(test) { 53 | var q = new xQ('AppleRedSeven'); 54 | 55 | test.deepEqual(allXml(q.find('attr').not('attr[name="color"]')), 56 | ['Apple', 'Seven']); 57 | 58 | test.deepEqual(allXml(q.find('attr').not('attr[name="number"]')), 59 | ['Apple', 'Red']); 60 | 61 | test.deepEqual(allXml(q.find('attr').not('attr[name="shape"]')), [ 62 | 'Apple', 63 | 'Red', 64 | 'Seven' 65 | ]); 66 | 67 | test.done(); 68 | } 69 | -------------------------------------------------------------------------------- /test/xq_parent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test parent/parents/parentsUntil functions 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | function allXml(q) { return q.map(function(n) { return xQ(n).xml(); }); } 24 | 25 | /** 26 | * Test empty set 27 | */ 28 | module.exports.testEmpty = function(test) { 29 | var empty = new xQ(); 30 | 31 | test.strictEqual(empty.parent().length, 0); 32 | test.strictEqual(empty.parent('empty').length, 0); 33 | test.strictEqual(empty.parents().length, 0); 34 | test.strictEqual(empty.parents('empty').length, 0); 35 | test.strictEqual(empty.parentsUntil('empty').length, 0); 36 | 37 | test.done(); 38 | } 39 | 40 | /** 41 | * Test parent() 42 | */ 43 | module.exports.testParent = function(test) { 44 | var q = new xQ("12" + 45 | "3" + 46 | "4"); 47 | 48 | test.deepEqual(allXml(q.find('number').parent()), 49 | ["12", 50 | "12", 51 | "3", 52 | "4"]); 53 | 54 | test.deepEqual(allXml(q.find('number').parent('items')), 55 | ["12", 56 | "12", 57 | "3"]); 58 | 59 | test.deepEqual(allXml(q.find('number').parent('wrapper')), ["4"]); 60 | 61 | test.deepEqual(allXml(q.find('number').parent('nomatch')), []); 62 | 63 | test.done(); 64 | } 65 | 66 | /** 67 | * Test parents() 68 | */ 69 | module.exports.testParents = function(test) { 70 | var q = new xQ("12" + 71 | "3" + 72 | "4"); 73 | 74 | test.deepEqual(allXml(q.find('number').parents()), 75 | ["12", 76 | "12", 77 | "1234", 78 | "12", 79 | "12", 80 | "1234", 81 | "3", 82 | "1234", 83 | "4", 84 | "4", 85 | "1234"]); 86 | 87 | test.deepEqual(allXml(q.find('number').parents('items')), 88 | ["12", 89 | "12", 90 | "3", 91 | "4"]); 92 | 93 | test.deepEqual(allXml(q.find('number').parents('nomatch')), []); 94 | 95 | test.done(); 96 | } 97 | 98 | /** 99 | * Test parentsUntil() 100 | */ 101 | module.exports.testParentsUntil = function(test) { 102 | var q = new xQ("12" + 103 | "3" + 104 | "4"); 105 | 106 | test.deepEqual(allXml(q.find('number').parentsUntil('items')), ["4"]); 107 | 108 | test.deepEqual(allXml(q.find('number').parentsUntil('nomatch')), 109 | ["12", 110 | "12", 111 | "1234", 112 | "12", 113 | "12", 114 | "1234", 115 | "3", 116 | "1234", 117 | "4", 118 | "4", 119 | "1234"]); 120 | 121 | test.done(); 122 | } 123 | -------------------------------------------------------------------------------- /test/xq_prev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test prev/prevAll/prevUntil functions 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | function allXml(q) { return q.map(function(n) { return xQ(n).xml(); }); } 24 | 25 | /** 26 | * Test empty set 27 | */ 28 | module.exports.testEmpty = function(test) { 29 | var empty = new xQ(); 30 | 31 | test.strictEqual(empty.prev().length, 0); 32 | test.strictEqual(empty.prev('empty').length, 0); 33 | test.strictEqual(empty.prevAll().length, 0); 34 | test.strictEqual(empty.prevAll('empty').length, 0); 35 | test.strictEqual(empty.prevUntil('empty').length, 0); 36 | 37 | test.done(); 38 | } 39 | 40 | /** 41 | * Test element selector 42 | */ 43 | module.exports.testElementSelector = function(test) { 44 | var q = new xQ("12foo3"); 45 | 46 | test.deepEqual(allXml(q.find('number').prev()), ['1','foo']); 47 | test.deepEqual(allXml(q.find('number').prev('string')), ['foo']); 48 | test.deepEqual(allXml(q.find('number').prev('foo')), []); 49 | test.deepEqual(allXml(q.find('number').prevAll()), 50 | ['1','foo','2','1']); 51 | test.deepEqual(allXml(q.find('number').prevAll('string')), ['foo']); 52 | test.deepEqual(allXml(q.find('number').prevAll('foo')), []); 53 | 54 | test.done(); 55 | } 56 | 57 | /** 58 | * Test attribute selector 59 | */ 60 | module.exports.testAttributeSelector = function(test) { 61 | var q = new xQ('AppleRedSeven'); 62 | 63 | test.deepEqual(allXml(q.find('attr[name="number"]').prev('attr[name="color"]')), ['Red']); 64 | test.deepEqual(allXml(q.find('attr[name="number"]').prev('attr[name="number"]')), []); 65 | test.deepEqual(allXml(q.find('attr[name="number"]').prev('attr[name="fruit"]')), []); 66 | test.deepEqual(allXml(q.find('attr[name="number"]').prevAll('attr[name="color"]')), ['Red']); 67 | test.deepEqual(allXml(q.find('attr[name="number"]').prevAll('attr[name="number"]')), []); 68 | test.deepEqual(allXml(q.find('attr[name="number"]').prevAll('attr[name="fruit"]')), ['Apple']); 69 | test.deepEqual(allXml(q.find('attr[name="number"]').prevUntil('attr[name="color"]')), []); 70 | test.deepEqual(allXml(q.find('attr[name="number"]').prevUntil('attr[name="number"]')), 71 | ['Red','Apple']); 72 | test.deepEqual(allXml(q.find('attr[name="number"]').prevUntil('attr[name="fruit"]')), ['Red']); 73 | 74 | test.done(); 75 | } 76 | -------------------------------------------------------------------------------- /test/xq_reduce.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the reduce() method 19 | */ 20 | 21 | var $$ = require('../index'); 22 | 23 | /** 24 | * Test empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | test.strictEqual($$().reduce(function(memo, n) { return memo+1; }, 0), 0); 28 | 29 | test.done(); 30 | } 31 | 32 | /** 33 | * Test success 34 | */ 35 | module.exports.testSuccess = function(test) { 36 | var $doc = $$('246').find('item'); 37 | 38 | test.strictEqual($doc.reduce(function(memo, elem) { 39 | return memo + parseInt($$(elem).text()); 40 | }, 0), 12); 41 | 42 | var $doc = $$('hello world').find('item'); 43 | 44 | test.strictEqual($doc.reduce(function(memo, elem) { 45 | return memo + $$(elem).text(); 46 | }, ""), "hello world"); 47 | 48 | test.done(); 49 | } 50 | 51 | /** 52 | * Test context 53 | */ 54 | module.exports.testContext = function(test) { 55 | var out = []; 56 | var ctx = {"context": 1}; 57 | 58 | test.strictEqual($$('').reduce(function(memo, n) { 59 | out.push(this); 60 | return memo + 1; 61 | }, 0, ctx), 1); 62 | 63 | test.deepEqual(out, [ctx]); 64 | 65 | test.done(); 66 | } 67 | 68 | /** 69 | * Test args 70 | */ 71 | module.exports.testArgs = function(test) { 72 | var $doc = $$('').find('fruit'); 73 | 74 | test.strictEqual($doc.reduce(function(memo, elem, idx, list) { 75 | 76 | test.strictEqual(memo, "memo"); 77 | test.strictEqual(elem, $doc[0]); 78 | test.strictEqual(idx, 0); 79 | test.strictEqual(list, $doc); 80 | 81 | return false; 82 | 83 | }, "memo"), false); 84 | 85 | test.done(); 86 | } 87 | -------------------------------------------------------------------------------- /test/xq_reduceRight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the reduceRight() method 19 | */ 20 | 21 | var $$ = require('../index'); 22 | 23 | /** 24 | * Test empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | test.strictEqual($$().reduceRight(function(memo, n) { return memo+1; }, 0), 0); 28 | 29 | test.done(); 30 | } 31 | 32 | /** 33 | * Test success 34 | */ 35 | module.exports.testSuccess = function(test) { 36 | var $doc = $$('246').find('item'); 37 | 38 | test.strictEqual($doc.reduceRight(function(memo, elem) { 39 | return memo + parseInt($$(elem).text()); 40 | }, 0), 12); 41 | 42 | var $doc = $$('hello world').find('item'); 43 | 44 | test.strictEqual($doc.reduceRight(function(memo, elem) { 45 | return memo + $$(elem).text(); 46 | }, ""), " worldllohe"); 47 | 48 | test.done(); 49 | } 50 | 51 | /** 52 | * Test context 53 | */ 54 | module.exports.testContext = function(test) { 55 | var out = []; 56 | var ctx = {"context": 1}; 57 | 58 | test.strictEqual($$('').reduceRight(function(memo, n) { 59 | out.push(this); 60 | return memo + 1; 61 | }, 0, ctx), 1); 62 | 63 | test.deepEqual(out, [ctx]); 64 | 65 | test.done(); 66 | } 67 | 68 | /** 69 | * Test args 70 | */ 71 | module.exports.testArgs = function(test) { 72 | var $doc = $$('').find('fruit'); 73 | 74 | test.strictEqual($doc.reduceRight(function(memo, elem, idx, list) { 75 | 76 | test.strictEqual(memo, "memo"); 77 | test.strictEqual(elem, $doc[0]); 78 | test.strictEqual(idx, 0); 79 | test.strictEqual(list, $doc); 80 | 81 | return false; 82 | 83 | }, "memo"), false); 84 | 85 | test.done(); 86 | } 87 | -------------------------------------------------------------------------------- /test/xq_search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the search() method 19 | */ 20 | 21 | var $$ = require('../index'); 22 | 23 | /** 24 | * Test simple selector 25 | */ 26 | module.exports.testSimpleSelector = function(test) { 27 | var empty = $$(); 28 | test.strictEqual(empty.search('hello').length, 0); 29 | 30 | var hello = $$(""); 31 | test.strictEqual(hello.search('hello').length, 1); 32 | 33 | var items = $$("123"); 34 | test.strictEqual(items.search('item').length, 3); 35 | 36 | test.done(); 37 | } 38 | 39 | /** 40 | * Test multiple selectors 41 | */ 42 | module.exports.testMultipleSelector = function(test) { 43 | var pets = $$("FluffyFidoMr. WhiskersScratchy"); 44 | 45 | test.strictEqual(pets.search('pets cat').length, 2); 46 | 47 | test.done(); 48 | } 49 | 50 | /** 51 | * Test the attribute selector 52 | */ 53 | module.exports.testAttrSelector = function(test) { 54 | var attrEquals = 55 | $$('AppleRed'); 56 | 57 | var result = attrEquals.search('attr[name="color"] value'); 58 | 59 | test.strictEqual(result.length, 1); 60 | test.strictEqual(result.text(), 'Red'); 61 | 62 | test.done(); 63 | } 64 | 65 | /** 66 | * Test the > combinator 67 | */ 68 | module.exports.testImmediateCombinator = function(test) { 69 | var immediate = $$(''); 70 | 71 | var all = immediate.search('item'); 72 | var child = immediate.search('doc > item'); 73 | 74 | test.deepEqual(all.map(function(n) { return n.getAttribute('value'); }), ['Apple', 'Orange', 'Banana']); 75 | 76 | test.deepEqual(child.map(function(n) { return n.getAttribute('value'); }), ['Apple']); 77 | 78 | test.done(); 79 | } 80 | 81 | /** 82 | * Test the + combinator 83 | */ 84 | module.exports.testSiblingCombinator = function(test) { 85 | var siblings = $$(''); 86 | 87 | var orange = siblings.search('item[value="Kiwi"] + item'); 88 | 89 | test.deepEqual(orange.map(function(n) { return n.getAttribute('value'); }), ['Orange']); 90 | 91 | test.done(); 92 | } 93 | 94 | /** 95 | * Test * 96 | */ 97 | module.exports.testUniversalSelector = function(test) { 98 | var hello = $$(""); 99 | 100 | test.deepEqual(hello.search('*').map(function(n) { return n.nodeName; }), ['doc','hello']); 101 | 102 | var items = $$("123"); 103 | 104 | test.deepEqual(items.search('doc *').map(function(n) { return n.nodeName + ' (' + $$(n).text() + ')'; }), 105 | ['items (123)', 'item (1)', 'item (2)', 'item (3)']); 106 | 107 | test.done(); 108 | } 109 | 110 | /** 111 | * Test unmatched selectors 112 | */ 113 | module.exports.testUnmatchedSelector = function(test) { 114 | var hello = $$(""); 115 | 116 | test.strictEqual(hello.search('hi').length, 0); 117 | test.strictEqual(hello.search('doc hi').length, 0); 118 | test.strictEqual(hello.search('doc > hi').length, 0); 119 | test.strictEqual(hello.search('> hi').length, 0); 120 | test.strictEqual(hello.search('doc + hi').length, 0); 121 | test.strictEqual(hello.search('+ hi').length, 0); 122 | test.strictEqual(hello.search('doc hello *').length, 0); 123 | 124 | test.done(); 125 | } 126 | -------------------------------------------------------------------------------- /test/xq_some.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Unit tests for the some() method 19 | */ 20 | 21 | var $$ = require('../index'); 22 | 23 | /** 24 | * Test empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | test.strictEqual($$().some(function() { return true; }), false); 28 | 29 | test.done(); 30 | } 31 | 32 | /** 33 | * Test failure 34 | */ 35 | module.exports.testFailure = function(test) { 36 | var $doc = $$('').find('fruit'); 37 | 38 | test.strictEqual($doc.some(function(elem) { 39 | return $$(elem).attr('name') == 'banana'; 40 | }), false); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test success 47 | */ 48 | module.exports.testSuccess = function(test) { 49 | var $doc = $$('').find('fruit'); 50 | 51 | test.strictEqual($doc.some(function(elem) { 52 | return $$(elem).attr('name') == 'pear'; 53 | }), true); 54 | 55 | test.done(); 56 | } 57 | 58 | /** 59 | * Test context 60 | */ 61 | module.exports.testContext = function(test) { 62 | var out = []; 63 | var ctx = {"context": 1}; 64 | 65 | var $doc = $$('').find('fruit'); 66 | 67 | test.strictEqual($doc.some(function(elem) { 68 | out.push(this); 69 | return $$(elem).attr('name') == 'banana'; 70 | }, ctx), false); 71 | 72 | test.deepEqual(out, [ctx, ctx, ctx]); 73 | 74 | test.done(); 75 | } 76 | 77 | /** 78 | * Test args 79 | */ 80 | module.exports.testArgs = function(test) { 81 | var $doc = $$('').find('fruit'); 82 | 83 | test.strictEqual($doc.some(function(elem, idx, list) { 84 | 85 | test.strictEqual(elem, $doc[0]); 86 | test.strictEqual(idx, 0); 87 | test.strictEqual(list, $doc); 88 | 89 | return false; 90 | 91 | }), false); 92 | 93 | test.done(); 94 | } 95 | -------------------------------------------------------------------------------- /test/xq_text.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test the text() function 19 | */ 20 | 21 | var xQ = require('../index'); 22 | 23 | /** 24 | * Test an empty set 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty.text(), ""); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test a single element 36 | */ 37 | module.exports.testSingle = function(test) { 38 | var q = new xQ("Hello world!"); 39 | 40 | test.strictEqual(q.text(), "Hello world!"); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test multiple desdendants 47 | */ 48 | module.exports.testMultipleDescendants = function(test) { 49 | var q = new xQ("

The quick brown fox jumps...

"); 50 | 51 | test.strictEqual(q.text(), "The quick brown fox jumps..."); 52 | 53 | test.done(); 54 | } 55 | -------------------------------------------------------------------------------- /test/xq_xml.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2013-2015 Comcast Cable Communications Management, LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Test xml function 19 | */ 20 | 21 | var xQ = require('../index') 22 | 23 | /** 24 | * Test empty document 25 | */ 26 | module.exports.testEmpty = function(test) { 27 | var empty = new xQ(); 28 | 29 | test.strictEqual(empty.xml(), ""); 30 | 31 | test.done(); 32 | } 33 | 34 | /** 35 | * Test single element document 36 | */ 37 | module.exports.testSingleElem = function(test) { 38 | var q = new xQ("Hello world!"); 39 | 40 | test.strictEqual(q.xml(), "\nHello world!\n"); 41 | 42 | test.done(); 43 | } 44 | 45 | /** 46 | * Test mulitple descendants 47 | */ 48 | module.exports.testMultiDescendants = function(test) { 49 | var q = new xQ("

The quick brown fox jumps...

"); 50 | 51 | test.strictEqual(q.xml(), "\n

The quick brown fox jumps...

\n"); 52 | 53 | test.done(); 54 | } 55 | 56 | /** 57 | * Test child node 58 | */ 59 | module.exports.testChildNode = function(test) { 60 | var q = new xQ("

The quick brown fox jumps...

"); 61 | 62 | test.strictEqual(q.find('b').xml(), "brown fox"); 63 | 64 | test.strictEqual(q.find('i').xml(), "quick"); 65 | 66 | test.done(); 67 | } 68 | 69 | /** 70 | * Test node without children 71 | */ 72 | module.exports.testChildlessNode = function(test) { 73 | var q = new xQ(""); 74 | 75 | test.strictEqual(q.find('hello').xml(), ""); 76 | 77 | test.done(); 78 | } 79 | 80 | --------------------------------------------------------------------------------