Simple email application for Android. Original source code: https://framagit.org/dystopia-project/simple-email
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

373 lines
12 KiB

  1. var template, expect;
  2. if (typeof require !== 'undefined') {
  3. template = require('../lib/url-template.js');
  4. expect = require("expect.js");
  5. } else {
  6. template = window.urltemplate;
  7. expect = window.expect;
  8. }
  9. function createTestContext(c) {
  10. return function (t, r) {
  11. expect(template.parse(t).expand(c)).to.eql(r);
  12. };
  13. }
  14. describe('uri-template', function () {
  15. describe('Level 1', function () {
  16. var assert = createTestContext({
  17. 'var': 'value',
  18. 'some.value': 'some',
  19. 'some_value': 'value',
  20. 'Some%20Thing': 'hello',
  21. 'foo': 'bar',
  22. 'hello': 'Hello World!',
  23. 'bool': false,
  24. 'toString': 'string',
  25. 'number': 42,
  26. 'float': 3.14,
  27. 'undef': undefined,
  28. 'null': null,
  29. 'chars': 'šö䟜ñꀣ¥‡ÑÒÓÔÕÖ×ØÙÚàáâãäåæçÿü',
  30. 'surrogatepairs': '\uD834\uDF06'
  31. });
  32. it('empty string', function () {
  33. assert('', '');
  34. });
  35. it('encodes non expressions correctly', function () {
  36. assert('hello/world', 'hello/world');
  37. assert('Hello World!/{foo}', 'Hello%20World!/bar');
  38. assert(':/?#[]@!$&()*+,;=\'', ':/?#[]@!$&()*+,;=\'');
  39. assert('%20', '%20');
  40. assert('%xyz', '%25xyz');
  41. assert('%', '%25');
  42. });
  43. it('expand plain ASCII strings', function () {
  44. assert('{var}', 'value');
  45. });
  46. it('expand non-ASCII strings', function () {
  47. assert('{chars}', '%C5%A1%C3%B6%C3%A4%C5%B8%C5%93%C3%B1%C3%AA%E2%82%AC%C2%A3%C2%A5%E2%80%A1%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%BF%C3%BC');
  48. });
  49. it('expands and encodes surrogate pairs correctly', function () {
  50. assert('{surrogatepairs}', '%F0%9D%8C%86');
  51. });
  52. it('expand expressions with dot and underscore', function () {
  53. assert('{some.value}', 'some');
  54. assert('{some_value}', 'value');
  55. });
  56. it('expand expressions with encoding', function () {
  57. assert('{Some%20Thing}', 'hello');
  58. });
  59. it('expand expressions with reserved JavaScript names', function () {
  60. assert('{toString}', 'string');
  61. });
  62. it('expand variables that are not strings', function () {
  63. assert('{number}', '42');
  64. assert('{float}', '3.14');
  65. assert('{bool}', 'false');
  66. });
  67. it('expand variables that are undefined or null', function () {
  68. assert('{undef}', '');
  69. assert('{null}', '');
  70. });
  71. it('expand multiple values', function () {
  72. assert('{var}/{foo}', 'value/bar');
  73. });
  74. it('escape invalid characters correctly', function () {
  75. assert('{hello}', 'Hello%20World%21');
  76. });
  77. });
  78. describe('Level 2', function () {
  79. var assert = createTestContext({
  80. 'var': 'value',
  81. 'hello': 'Hello World!',
  82. 'path': '/foo/bar'
  83. });
  84. it('reserved expansion of basic strings', function () {
  85. assert('{+var}', 'value');
  86. assert('{+hello}', 'Hello%20World!');
  87. });
  88. it('preserves paths', function() {
  89. assert('{+path}/here', '/foo/bar/here');
  90. assert('here?ref={+path}', 'here?ref=/foo/bar');
  91. });
  92. });
  93. describe('Level 3', function () {
  94. var assert = createTestContext({
  95. 'var' : 'value',
  96. 'hello' : 'Hello World!',
  97. 'empty' : '',
  98. 'path' : '/foo/bar',
  99. 'x' : '1024',
  100. 'y' : '768'
  101. });
  102. it('variables without an operator', function () {
  103. assert('map?{x,y}', 'map?1024,768');
  104. assert('{x,hello,y}', '1024,Hello%20World%21,768');
  105. });
  106. it('variables with the reserved expansion operator', function () {
  107. assert('{+x,hello,y}', '1024,Hello%20World!,768');
  108. assert('{+path,x}/here', '/foo/bar,1024/here');
  109. });
  110. it('variables with the fragment expansion operator', function () {
  111. assert('{#x,hello,y}', '#1024,Hello%20World!,768');
  112. assert('{#path,x}/here', '#/foo/bar,1024/here');
  113. });
  114. it('variables with the dot operator', function () {
  115. assert('X{.var}', 'X.value');
  116. assert('X{.x,y}', 'X.1024.768');
  117. });
  118. it('variables with the path operator', function () {
  119. assert('{/var}', '/value');
  120. assert('{/var,x}/here', '/value/1024/here');
  121. });
  122. it('variables with the parameter operator', function () {
  123. assert('{;x,y}', ';x=1024;y=768');
  124. assert('{;x,y,empty}', ';x=1024;y=768;empty');
  125. });
  126. it('variables with the query operator', function () {
  127. assert('{?x,y}', '?x=1024&y=768');
  128. assert('{?x,y,empty}', '?x=1024&y=768&empty=');
  129. });
  130. it('variables with the query continuation operator', function () {
  131. assert('?fixed=yes{&x}', '?fixed=yes&x=1024');
  132. assert('{&x,y,empty}', '&x=1024&y=768&empty=');
  133. });
  134. });
  135. describe('Level 4', function () {
  136. var assert = createTestContext({
  137. 'var': 'value',
  138. 'hello': 'Hello World!',
  139. 'path': '/foo/bar',
  140. 'list': ['red', 'green', 'blue'],
  141. 'keys': {
  142. 'semi': ';',
  143. 'dot': '.',
  144. 'comma': ','
  145. },
  146. "chars": {
  147. 'ü': 'ü'
  148. },
  149. 'number': 2133,
  150. 'emptystring': '',
  151. 'emptylist': [],
  152. 'emptyobject': {},
  153. 'undefinedlistitem': [1,,2],
  154. 'undefinedobjectitem': { key: null, hello: 'world', 'empty': '', '': 'nothing' }
  155. });
  156. it('variable empty list', function () {
  157. assert('{/emptylist}', '');
  158. assert('{/emptylist*}', '');
  159. assert('{?emptylist}', '?emptylist=');
  160. assert('{?emptylist*}', '');
  161. });
  162. it('variable empty object', function () {
  163. assert('{/emptyobject}', '');
  164. assert('{/emptyobject*}', '');
  165. assert('{?emptyobject}', '?emptyobject=');
  166. assert('{?emptyobject*}', '');
  167. });
  168. it('variable undefined list item', function () {
  169. assert('{undefinedlistitem}', '1,2');
  170. assert('{undefinedlistitem*}', '1,2');
  171. assert('{?undefinedlistitem*}', '?undefinedlistitem=1&undefinedlistitem=2');
  172. });
  173. it('variable undefined object item', function () {
  174. assert('{undefinedobjectitem}', 'hello,world,empty,,,nothing');
  175. assert('{undefinedobjectitem*}', 'hello=world,empty=,nothing');
  176. });
  177. it('variable empty string', function () {
  178. assert('{emptystring}', '');
  179. assert('{+emptystring}', '');
  180. assert('{#emptystring}', '#');
  181. assert('{.emptystring}', '.');
  182. assert('{/emptystring}', '/');
  183. assert('{;emptystring}', ';emptystring');
  184. assert('{?emptystring}', '?emptystring=');
  185. assert('{&emptystring}', '&emptystring=');
  186. });
  187. it('variable modifiers prefix', function () {
  188. assert('{var:3}', 'val');
  189. assert('{var:30}', 'value');
  190. assert('{+path:6}/here', '/foo/b/here');
  191. assert('{#path:6}/here', '#/foo/b/here');
  192. assert('X{.var:3}', 'X.val');
  193. assert('{/var:1,var}', '/v/value');
  194. assert('{;hello:5}', ';hello=Hello');
  195. assert('{?var:3}', '?var=val');
  196. assert('{&var:3}', '&var=val');
  197. });
  198. it('variable modifier prefix converted to string', function () {
  199. assert('{number:3}', '213');
  200. });
  201. it('variable list expansion', function () {
  202. assert('{list}', 'red,green,blue');
  203. assert('{+list}', 'red,green,blue');
  204. assert('{#list}', '#red,green,blue');
  205. assert('{/list}', '/red,green,blue');
  206. assert('{;list}', ';list=red,green,blue');
  207. assert('{.list}', '.red,green,blue');
  208. assert('{?list}', '?list=red,green,blue');
  209. assert('{&list}', '&list=red,green,blue');
  210. });
  211. it('variable associative array expansion', function () {
  212. assert('{keys}', 'semi,%3B,dot,.,comma,%2C');
  213. assert('{keys*}', 'semi=%3B,dot=.,comma=%2C');
  214. assert('{+keys}', 'semi,;,dot,.,comma,,');
  215. assert('{#keys}', '#semi,;,dot,.,comma,,');
  216. assert('{.keys}', '.semi,%3B,dot,.,comma,%2C');
  217. assert('{/keys}', '/semi,%3B,dot,.,comma,%2C');
  218. assert('{;keys}', ';keys=semi,%3B,dot,.,comma,%2C');
  219. assert('{?keys}', '?keys=semi,%3B,dot,.,comma,%2C');
  220. assert('{&keys}', '&keys=semi,%3B,dot,.,comma,%2C');
  221. });
  222. it('variable list explode', function () {
  223. assert('{list*}', 'red,green,blue');
  224. assert('{+list*}', 'red,green,blue');
  225. assert('{#list*}', '#red,green,blue');
  226. assert('{/list*}', '/red/green/blue');
  227. assert('{;list*}', ';list=red;list=green;list=blue');
  228. assert('{.list*}', '.red.green.blue');
  229. assert('{?list*}', '?list=red&list=green&list=blue');
  230. assert('{&list*}', '&list=red&list=green&list=blue');
  231. assert('{/list*,path:4}', '/red/green/blue/%2Ffoo');
  232. });
  233. it('variable associative array explode', function () {
  234. assert('{+keys*}', 'semi=;,dot=.,comma=,');
  235. assert('{#keys*}', '#semi=;,dot=.,comma=,');
  236. assert('{/keys*}', '/semi=%3B/dot=./comma=%2C');
  237. assert('{;keys*}', ';semi=%3B;dot=.;comma=%2C');
  238. assert('{?keys*}', '?semi=%3B&dot=.&comma=%2C');
  239. assert('{&keys*}', '&semi=%3B&dot=.&comma=%2C')
  240. });
  241. it('encodes associative arrays correctly', function () {
  242. assert('{chars*}', '%C3%BC=%C3%BC');
  243. });
  244. });
  245. describe('Encoding', function () {
  246. var assert = createTestContext({
  247. restricted: ":/?#[]@!$&()*+,;='",
  248. percent: '%',
  249. encoded: '%25',
  250. 'pctencoded%20name': '',
  251. mapWithEncodedName: {
  252. 'encoded%20name': ''
  253. },
  254. mapWithRestrictedName: {
  255. 'restricted=name': ''
  256. },
  257. mapWidthUmlautName: {
  258. 'ümlaut': ''
  259. }
  260. });
  261. it('passes through percent encoded values', function () {
  262. assert('{percent}', '%25');
  263. assert('{+encoded}', '%25');
  264. });
  265. it('encodes restricted characters correctly', function () {
  266. assert('{restricted}', '%3A%2F%3F%23%5B%5D%40%21%24%26%28%29%2A%2B%2C%3B%3D%27');
  267. assert('{+restricted}', ':/?#[]@!$&()*+,;=\'');
  268. assert('{#restricted}', '#:/?#[]@!$&()*+,;=\'');
  269. assert('{/restricted}', '/%3A%2F%3F%23%5B%5D%40%21%24%26%28%29%2A%2B%2C%3B%3D%27');
  270. assert('{;restricted}', ';restricted=%3A%2F%3F%23%5B%5D%40%21%24%26%28%29%2A%2B%2C%3B%3D%27');
  271. assert('{.restricted}', '.%3A%2F%3F%23%5B%5D%40%21%24%26%28%29%2A%2B%2C%3B%3D%27');
  272. assert('{?restricted}', '?restricted=%3A%2F%3F%23%5B%5D%40%21%24%26%28%29%2A%2B%2C%3B%3D%27');
  273. assert('{&restricted}', '&restricted=%3A%2F%3F%23%5B%5D%40%21%24%26%28%29%2A%2B%2C%3B%3D%27');
  274. });
  275. });
  276. describe('Error handling (or the lack thereof)', function () {
  277. var assert = createTestContext({
  278. foo: 'test',
  279. keys: {
  280. foo: 'bar'
  281. }
  282. });
  283. it('does not expand invalid expressions', function () {
  284. assert('{test', '{test');
  285. assert('test}', 'test}');
  286. assert('{{test}}', '{}'); // TODO: Is this acceptable?
  287. });
  288. it('does not expand with incorrect operators', function () {
  289. assert('{@foo}', ''); // TODO: This will try to match a variable called `@foo` which will fail because it is not in our context. We could catch this by ignoring reserved operators?
  290. assert('{$foo}', ''); // TODO: Same story, but $ is not a reserved operator.
  291. assert('{++foo}', '');
  292. });
  293. it('ignores incorrect prefixes', function () {
  294. assert('{foo:test}', 'test'); // TODO: Invalid prefixes are ignored. We could throw an error.
  295. assert('{foo:2test}', 'te'); // TODO: Best effort is OK?
  296. });
  297. it('prefix applied to the wrong context', function () {
  298. assert('{keys:1}', 'foo,bar');
  299. });
  300. });
  301. describe('Skipping undefined arguments', function () {
  302. var assert = createTestContext({
  303. 'var': 'value',
  304. 'number': 2133,
  305. 'emptystring': '',
  306. 'emptylist': [],
  307. 'emptyobject': {},
  308. 'undefinedlistitem': [1,,2],
  309. });
  310. it('variable undefined list item', function () {
  311. assert('{undefinedlistitem}', '1,2');
  312. assert('{undefinedlistitem*}', '1,2');
  313. assert('{?undefinedlistitem*}', '?undefinedlistitem=1&undefinedlistitem=2');
  314. });
  315. it('query with empty/undefined arguments', function () {
  316. assert('{?var,number}', '?var=value&number=2133');
  317. assert('{?undef}', '');
  318. assert('{?emptystring}', '?emptystring=');
  319. assert('{?emptylist}', '?emptylist=');
  320. assert('{?emptyobject}', '?emptyobject=');
  321. assert('{?undef,var,emptystring}', '?var=value&emptystring=');
  322. });
  323. });
  324. });