/test/phony-test.js

https://github.com/neocotic/phony.js · JavaScript · 467 lines · 356 code · 100 blank · 11 comment · 12 complexity · 6cd7092674a8624e2b45ce91d0ce9209 MD5 · raw file

  1. 'use strict';
  2. var expect = require('expect.js');
  3. var fs = require('fs');
  4. var path = require('path');
  5. var q = require('q');
  6. var phony = require('../lib/phony');
  7. /**
  8. * The regular expression used to find and replace EOL characters.
  9. *
  10. * @type {RegExp}
  11. */
  12. var rEOL = /[\n\r]+/g;
  13. /**
  14. * Loads the contents of a test fixture asynchronously.
  15. *
  16. * @param {String} filePath - the path to the file of the test fixture to be loaded
  17. * @returns {q.Promise} A promise to track the file loading.
  18. */
  19. function loadFixture(filePath) {
  20. filePath = path.join('test', 'fixtures', filePath);
  21. return q.nfcall(fs.readFile, filePath, {encoding: 'utf8'})
  22. .then(function(fixture) {
  23. return fixture.trim();
  24. });
  25. }
  26. describe('phony', function() {
  27. afterEach(function() {
  28. delete phony.alphabets.foo;
  29. phony.clearCache();
  30. });
  31. it('should be exported as an object', function() {
  32. expect(phony).to.be.an(Object);
  33. });
  34. describe('.alphabets', function() {
  35. it('should return a map of available alphabets', function() {
  36. expect(phony.alphabets).to.be.an(Object);
  37. expect(phony.alphabets).to.only.have.keys([
  38. 'ansi',
  39. 'faa',
  40. 'icao',
  41. 'itu'
  42. ]);
  43. });
  44. it('should have the "ansi" alphabet correctly defined', function() {
  45. var alphabet = phony.alphabets.ansi;
  46. expect(alphabet).to.be.an(Object);
  47. expect(alphabet.characters).to.be.an(Object);
  48. expect(alphabet.characters).not.to.be.empty();
  49. expect(alphabet.fallback).to.be('itu');
  50. });
  51. it('should have the "faa" alphabet correctly defined', function() {
  52. var alphabet = phony.alphabets.faa;
  53. expect(alphabet).to.be.an(Object);
  54. expect(alphabet.characters).to.be.an(Object);
  55. expect(alphabet.characters).not.to.be.empty();
  56. expect(alphabet.fallback).to.be('itu');
  57. });
  58. it('should have the "icao" alphabet correctly defined', function() {
  59. var alphabet = phony.alphabets.icao;
  60. expect(alphabet).to.be.an(Object);
  61. expect(alphabet.characters).to.be.an(Object);
  62. expect(alphabet.characters).not.to.be.empty();
  63. expect(alphabet.fallback).to.be('faa');
  64. });
  65. it('should have the "itu" alphabet correctly defined', function() {
  66. var alphabet = phony.alphabets.itu;
  67. expect(alphabet).to.be.an(Object);
  68. expect(alphabet).not.to.have.property('fallback');
  69. expect(alphabet.characters).to.be.an(Object);
  70. expect(alphabet.characters).not.to.be.empty();
  71. });
  72. it('should be exensible', function() {
  73. var options = {alphabet: 'foo'};
  74. expect(phony.alphabets).not.to.have.key('foo');
  75. phony.alphabets.foo = {
  76. fallback: 'itu',
  77. characters: {
  78. 'F': 'feck',
  79. 'O': 'off'
  80. }
  81. };
  82. expect(phony.to('FOO', options)).to.be('Feck Off Off');
  83. expect(phony.from('Feck Off Off', options)).to.be('FOO');
  84. });
  85. });
  86. describe('.defaults', function() {
  87. it('should be defined correctly', function() {
  88. expect(phony.defaults).to.be.an(Object);
  89. expect(phony.defaults).to.have.property('alphabet', 'itu');
  90. expect(phony.defaults).to.have.property('letterSplitter', ' ');
  91. expect(phony.defaults).to.have.property('wordSplitter', 'space');
  92. });
  93. });
  94. describe('.clearCache', function() {
  95. it('should clear cache of previously built alphabets', function() {
  96. var options = {alphabet: 'foo'};
  97. phony.alphabets.foo = {
  98. characters: {
  99. 'A': 'alpha'
  100. }
  101. };
  102. expect(phony.to('a', options)).to.be('Alpha');
  103. expect(phony.from('Alpha', options)).to.be('A');
  104. phony.alphabets.foo.characters.A = 'alfa';
  105. phony.clearCache();
  106. expect(phony.to('a', options)).to.be('Alfa');
  107. expect(phony.from('Alfa', options)).to.be('A');
  108. });
  109. it('should return a reference to phony', function() {
  110. expect(phony.clearCache()).to.be(phony);
  111. });
  112. });
  113. describe('.from', function() {
  114. it('should return an empty string if no message is provided', function() {
  115. expect(phony.from('')).to.be('');
  116. });
  117. it('should return an empty string if the message is empty', function() {
  118. expect(phony.from('')).to.be('');
  119. expect(phony.from(' ')).to.be('');
  120. expect(phony.from(' \n \r ')).to.be('');
  121. });
  122. it('should return an empty string if the alphabet does not exist', function() {
  123. expect(phony.from('Echo', {alphabet: 'foo'})).to.be('');
  124. });
  125. it('should return an empty string if the alphabet has no character mappings', function() {
  126. phony.alphabets.foo = {};
  127. expect(phony.from('Alpha', {alphabet: 'foo'})).to.be('');
  128. });
  129. it('should ignore invalid phonetics', function() {
  130. expect(phony.from('Alfa Foo Zulu')).to.be('AZ');
  131. });
  132. it('should ignore case', function() {
  133. expect(phony.from('iNdIa SpAcE cHaRlIe')).to.be('I C');
  134. });
  135. it('should ignore case for alphabet option', function() {
  136. expect(phony.from('Alpha Bravo Charlie', {alphabet: 'ANSI'})).to.be('ABC');
  137. });
  138. it('should throw an error if message is not a string', function() {
  139. expect(phony.from).withArgs(true).to.throwError();
  140. });
  141. it('should cache built alphabets by default', function() {
  142. var options = {alphabet: 'foo'};
  143. phony.alphabets.foo = {
  144. characters: {
  145. 'A': 'alpha'
  146. }
  147. };
  148. expect(phony.from('Alpha', options)).to.be('A');
  149. phony.alphabets.foo.characters.A = 'alfa';
  150. expect(phony.from('Alpha', options)).to.be('A');
  151. expect(phony.from('Alfa', options)).to.be('');
  152. });
  153. it('should support cache option', function() {
  154. var options = {
  155. alphabet: 'foo',
  156. cache: false
  157. };
  158. phony.alphabets.foo = {
  159. characters: {
  160. 'A': 'alpha'
  161. }
  162. };
  163. expect(phony.from('Alpha', options)).to.be('A');
  164. phony.alphabets.foo.characters.A = 'alfa';
  165. expect(phony.from('Alfa', options)).to.be('A');
  166. });
  167. it('should translate using the splitter options', function() {
  168. var options = {letterSplitter: '_', wordSplitter: '\\+'};
  169. expect(phony.from([
  170. 'Alfa_Juliett_Zulu',
  171. 'Nadazero_Dash_Novenine'
  172. ].join('_+_'), options)).to.be('AJZ 0-9');
  173. });
  174. it('should translate using "itu" alphabet by default', function() {
  175. expect(phony.from([
  176. 'Alfa Juliett Zulu',
  177. 'Nadazero Dash Novenine'
  178. ].join(' Space '))).to.be('AJZ 0-9');
  179. });
  180. it('should translate using "ansi" alphabet correctly', function(done) {
  181. var options = {alphabet: 'ansi'};
  182. expect(phony.from([
  183. 'Alpha Juliet Zulu',
  184. 'Nadazero Dash Novenine'
  185. ].join(' Space '), options)).to.be('AJZ 0-9');
  186. q.spread([loadFixture('ansi.txt'), loadFixture('characters.txt')], function(source, target) {
  187. expect(phony.from(source, options)).to.be(target.replace(rEOL, ' '));
  188. })
  189. .then(done)
  190. .done();
  191. });
  192. it('should translate using "faa" alphabet correctly', function(done) {
  193. var options = {alphabet: 'faa'};
  194. expect(phony.from([
  195. 'Alfa Juliett Zulu',
  196. 'Zero Dash Nine'
  197. ].join(' Space '), options)).to.be('AJZ 0-9');
  198. q.spread([loadFixture('faa.txt'), loadFixture('characters.txt')], function(source, target) {
  199. expect(phony.from(source, options)).to.be(target.replace(rEOL, ' '));
  200. })
  201. .then(done)
  202. .done();
  203. });
  204. it('should translate using "icao" alphabet correctly', function(done) {
  205. var options = {alphabet: 'icao'};
  206. expect(phony.from([
  207. 'Alfa Juliett Zulu',
  208. 'Zero Dash Niner'
  209. ].join(' Space '), options)).to.be('AJZ 0-9');
  210. q.spread([loadFixture('icao.txt'), loadFixture('characters.txt')], function(source, target) {
  211. expect(phony.from(source, options)).to.be(target.replace(rEOL, ' '));
  212. })
  213. .then(done)
  214. .done();
  215. });
  216. it('should translate using "itu" alphabet correctly', function(done) {
  217. var options = {alphabet: 'itu'};
  218. expect(phony.from([
  219. 'Alfa Juliett Zulu',
  220. 'Nadazero Dash Novenine'
  221. ].join(' Space '), options)).to.be('AJZ 0-9');
  222. q.spread([loadFixture('itu.txt'), loadFixture('characters.txt')], function(source, target) {
  223. expect(phony.from(source, options)).to.be(target.replace(rEOL, ' '));
  224. })
  225. .then(done)
  226. .done();
  227. });
  228. });
  229. describe('.to', function() {
  230. it('should return an empty string if no message is provided', function() {
  231. expect(phony.to('')).to.be('');
  232. });
  233. it('should return an empty string if the message is empty', function() {
  234. expect(phony.to('')).to.be('');
  235. expect(phony.to(' ')).to.be('');
  236. expect(phony.to(' \n \r ')).to.be('');
  237. });
  238. it('should return an empty string if the alphabet does not exist', function() {
  239. expect(phony.to('foo', {alphabet: 'foo'})).to.be('');
  240. });
  241. it('should return an empty string if the alphabet has no character mappings', function() {
  242. phony.alphabets.foo = {};
  243. expect(phony.to('A', {alphabet: 'foo'})).to.be('');
  244. });
  245. it('should ignore invalid characters', function() {
  246. expect(phony.to('A@Z')).to.be('Alfa Zulu');
  247. });
  248. it('should ignore case', function() {
  249. expect(phony.to('i C')).to.be('India Space Charlie');
  250. });
  251. it('should ignore case for alphabet option', function() {
  252. expect(phony.to('abc', {alphabet: 'ANSI'})).to.be('Alpha Bravo Charlie');
  253. });
  254. it('should throw an error if message is not a string', function() {
  255. expect(phony.to).withArgs(true).to.throwError();
  256. });
  257. it('should cache built alphabets by default', function() {
  258. var options = {alphabet: 'foo'};
  259. phony.alphabets.foo = {
  260. characters: {
  261. 'A': 'alpha'
  262. }
  263. };
  264. expect(phony.to('a', options)).to.be('Alpha');
  265. phony.alphabets.foo.characters.A = 'alfa';
  266. expect(phony.to('a', options)).to.be('Alpha');
  267. });
  268. it('should support cache option', function() {
  269. var options = {
  270. alphabet: 'foo',
  271. cache: false
  272. };
  273. phony.alphabets.foo = {
  274. characters: {
  275. 'A': 'alpha'
  276. }
  277. };
  278. expect(phony.to('a', options)).to.be('Alpha');
  279. phony.alphabets.foo.characters.A = 'alfa';
  280. expect(phony.to('a', options)).to.be('Alfa');
  281. });
  282. it('should translate using the splitter options', function() {
  283. var options = {letterSplitter: '_', wordSplitter: '+'};
  284. expect(phony.to('AJZ 0-9', options)).to.be([
  285. 'Alfa_Juliett_Zulu',
  286. 'Nadazero_Dash_Novenine'
  287. ].join('_+_'));
  288. });
  289. it('should translate using "itu" alphabet by default', function() {
  290. expect(phony.to('AJZ 0-9')).to.be([
  291. 'Alfa Juliett Zulu',
  292. 'Nadazero Dash Novenine'
  293. ].join(' Space '));
  294. });
  295. it('should translate using "ansi" alphabet correctly', function(done) {
  296. var options = {alphabet: 'ansi'};
  297. expect(phony.to('AJZ 0-9', options)).to.be([
  298. 'Alpha Juliet Zulu',
  299. 'Nadazero Dash Novenine'
  300. ].join(' Space '));
  301. q.spread([loadFixture('characters.txt'), loadFixture('ansi.txt')], function(source, target) {
  302. expect(phony.to(source, options)).to.be(target.replace(rEOL, ' Space '));
  303. })
  304. .then(done)
  305. .done();
  306. });
  307. it('should translate using "faa" alphabet correctly', function(done) {
  308. var options = {alphabet: 'faa'};
  309. expect(phony.to('AJZ 0-9', options)).to.be([
  310. 'Alfa Juliett Zulu',
  311. 'Zero Dash Nine'
  312. ].join(' Space '));
  313. q.spread([loadFixture('characters.txt'), loadFixture('faa.txt')], function(source, target) {
  314. expect(phony.to(source, options)).to.be(target.replace(rEOL, ' Space '));
  315. })
  316. .then(done)
  317. .done();
  318. });
  319. it('should translate using "icao" alphabet correctly', function(done) {
  320. var options = {alphabet: 'icao'};
  321. expect(phony.to('AJZ 0-9', options)).to.be([
  322. 'Alfa Juliett Zulu',
  323. 'Zero Dash Niner'
  324. ].join(' Space '));
  325. q.spread([loadFixture('characters.txt'), loadFixture('icao.txt')], function(source, target) {
  326. expect(phony.to(source, options)).to.be(target.replace(rEOL, ' Space '));
  327. })
  328. .then(done)
  329. .done();
  330. });
  331. it('should translate using "itu" alphabet correctly', function(done) {
  332. var options = {alphabet: 'itu'};
  333. expect(phony.to('AJZ 0-9', options)).to.be([
  334. 'Alfa Juliett Zulu',
  335. 'Nadazero Dash Novenine'
  336. ].join(' Space '));
  337. q.spread([loadFixture('characters.txt'), loadFixture('itu.txt')], function(source, target) {
  338. expect(phony.to(source, options)).to.be(target.replace(rEOL, ' Space '));
  339. })
  340. .then(done)
  341. .done();
  342. });
  343. });
  344. describe('.noConflict', function() {
  345. it('should return a reference to itself', function() {
  346. expect(phony.noConflict()).to.be(phony);
  347. });
  348. });
  349. describe('.VERSION', function() {
  350. it('should match version in bower.json', function(done) {
  351. q.nfcall(fs.readFile, 'bower.json', {encoding: 'utf8'})
  352. .then(function(data) {
  353. expect(phony.VERSION).to.be(JSON.parse(data).version);
  354. })
  355. .then(done)
  356. .done();
  357. });
  358. it('should match version in package.json', function(done) {
  359. q.nfcall(fs.readFile, 'package.json', {encoding: 'utf8'})
  360. .then(function(data) {
  361. expect(phony.VERSION).to.be(JSON.parse(data).version);
  362. })
  363. .then(done)
  364. .done();
  365. });
  366. });
  367. });