normalize.js~ 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. var tap = require("tap")
  2. var fs = require("fs")
  3. var path = require("path")
  4. var globals = Object.keys(global)
  5. var normalize = require("../lib/normalize")
  6. var warningMessages = require("../lib/warning_messages.json")
  7. var safeFormat = require("../lib/safe_format")
  8. var rpjPath = path.resolve(__dirname,"./fixtures/read-package-json.json")
  9. tap.test("normalize some package data", function(t) {
  10. var packageData = require(rpjPath)
  11. var warnings = []
  12. normalize(packageData, function(warning) {
  13. warnings.push(warning)
  14. })
  15. // there's no readme data in this particular object
  16. t.equal( warnings.length, 1, "There's exactly one warning.")
  17. fs.readFile(rpjPath, function(err, data) {
  18. if(err) throw err
  19. // Various changes have been made
  20. t.notEqual(packageData, JSON.parse(data), "Output is different from input.")
  21. t.end()
  22. })
  23. })
  24. tap.test("runs without passing warning function", function(t) {
  25. var packageData = require(rpjPath)
  26. fs.readFile(rpjPath, function(err, data) {
  27. if(err) throw err
  28. normalize(JSON.parse(data))
  29. t.ok(true, "If you read this, this means I'm still alive.")
  30. t.end()
  31. })
  32. })
  33. tap.test("empty object", function(t) {
  34. var packageData = {}
  35. var expect =
  36. { name: '',
  37. version: '',
  38. readme: 'ERROR: No README data found!',
  39. _id: '@' }
  40. var warnings = []
  41. function warn(m) {
  42. warnings.push(m)
  43. }
  44. normalize(packageData, warn)
  45. t.same(packageData, expect)
  46. t.same(warnings, [
  47. warningMessages.missingDescription,
  48. warningMessages.missingRepository,
  49. warningMessages.missingReadme,
  50. warningMessages.missingLicense
  51. ])
  52. t.end()
  53. })
  54. tap.test("core module name", function(t) {
  55. var warnings = []
  56. function warn(m) {
  57. warnings.push(m)
  58. }
  59. var a
  60. normalize(a={
  61. name: "http",
  62. readme: "read yourself how about",
  63. homepage: 123,
  64. bugs: "what is this i don't even",
  65. repository: "Hello."
  66. }, warn)
  67. var expect = [
  68. safeFormat(warningMessages.conflictingName, 'http'),
  69. warningMessages.nonEmailUrlBugsString,
  70. warningMessages.emptyNormalizedBugs,
  71. warningMessages.nonUrlHomepage,
  72. warningMessages.missingLicense
  73. ]
  74. t.same(warnings, expect)
  75. t.end()
  76. })
  77. tap.test("urls required", function(t) {
  78. var warnings = []
  79. function warn(w) {
  80. warnings.push(w)
  81. }
  82. normalize({
  83. bugs: {
  84. url: "/1",
  85. email: "not an email address"
  86. }
  87. }, warn)
  88. var a
  89. normalize(a={
  90. readme: "read yourself how about",
  91. homepage: 123,
  92. bugs: "what is this i don't even",
  93. repository: "Hello."
  94. }, warn)
  95. console.error(a)
  96. var expect =
  97. [ warningMessages.missingDescription,
  98. warningMessages.missingRepository,
  99. warningMessages.nonUrlBugsUrlField,
  100. warningMessages.nonEmailBugsEmailField,
  101. warningMessages.emptyNormalizedBugs,
  102. warningMessages.missingReadme,
  103. warningMessages.missingLicense,
  104. warningMessages.nonEmailUrlBugsString,
  105. warningMessages.emptyNormalizedBugs,
  106. warningMessages.nonUrlHomepage,
  107. warningMessages.missingLicense]
  108. t.same(warnings, expect)
  109. t.end()
  110. })
  111. tap.test("homepage field must start with a protocol.", function(t) {
  112. var warnings = []
  113. function warn(w) {
  114. warnings.push(w)
  115. }
  116. var a
  117. normalize(a={
  118. homepage: 'example.org'
  119. }, warn)
  120. console.error(a)
  121. var expect =
  122. [ warningMessages.missingDescription,
  123. warningMessages.missingRepository,
  124. warningMessages.missingReadme,
  125. warningMessages.missingProtocolHomepage,
  126. warningMessages.missingLicense]
  127. t.same(warnings, expect)
  128. t.same(a.homepage, 'http://example.org')
  129. t.end()
  130. })
  131. tap.test("license field should be a valid SPDX expression", function(t) {
  132. var warnings = []
  133. function warn(w) {
  134. warnings.push(w)
  135. }
  136. var a
  137. normalize(a={
  138. license: 'Apache 2'
  139. }, warn)
  140. console.error(a)
  141. var expect =
  142. [ warningMessages.missingDescription,
  143. warningMessages.missingRepository,
  144. warningMessages.missingReadme,
  145. warningMessages.invalidLicense]
  146. t.same(warnings, expect)
  147. t.end()
  148. })
  149. tap.test("gist bugs url", function(t) {
  150. var d = {
  151. repository: "git@gist.github.com:123456.git"
  152. }
  153. normalize(d)
  154. t.same(d.repository, { type: 'git', url: 'git+ssh://git@gist.github.com/123456.git' })
  155. t.same(d.bugs, { url: 'https://gist.github.com/123456' })
  156. t.end();
  157. });
  158. tap.test("singularize repositories", function(t) {
  159. var d = {repositories:["git@gist.github.com:123456.git"]}
  160. normalize(d)
  161. t.same(d.repository, { type: 'git', url: 'git+ssh://git@gist.github.com/123456.git' })
  162. t.end()
  163. });
  164. tap.test("treat visionmedia/express as github repo", function(t) {
  165. var d = {repository: {type: "git", url: "visionmedia/express"}}
  166. normalize(d)
  167. t.same(d.repository, { type: "git", url: "git+https://github.com/visionmedia/express.git" })
  168. t.end()
  169. });
  170. tap.test("treat isaacs/node-graceful-fs as github repo", function(t) {
  171. var d = {repository: {type: "git", url: "isaacs/node-graceful-fs"}}
  172. normalize(d)
  173. t.same(d.repository, { type: "git", url: "git+https://github.com/isaacs/node-graceful-fs.git" })
  174. t.end()
  175. });
  176. tap.test("homepage field will set to github url if repository is a github repo", function(t) {
  177. var a
  178. normalize(a={
  179. repository: { type: "git", url: "https://github.com/isaacs/node-graceful-fs" }
  180. })
  181. t.same(a.homepage, 'https://github.com/isaacs/node-graceful-fs#readme')
  182. t.end()
  183. })
  184. tap.test("homepage field will set to github gist url if repository is a gist", function(t) {
  185. var a
  186. normalize(a={
  187. repository: { type: "git", url: "git@gist.github.com:123456.git" }
  188. })
  189. t.same(a.homepage, 'https://gist.github.com/123456')
  190. t.end()
  191. })
  192. tap.test("homepage field will set to github gist url if repository is a shorthand reference", function(t) {
  193. var a
  194. normalize(a={
  195. repository: { type: "git", url: "sindresorhus/chalk" }
  196. })
  197. t.same(a.homepage, 'https://github.com/sindresorhus/chalk#readme')
  198. t.end()
  199. })
  200. tap.test("don't mangle github shortcuts in dependencies", function(t) {
  201. var d = {dependencies: {"node-graceful-fs": "isaacs/node-graceful-fs"}}
  202. normalize(d)
  203. t.same(d.dependencies, {"node-graceful-fs": "github:isaacs/node-graceful-fs" })
  204. t.end()
  205. });
  206. tap.test("deprecation warning for array in dependencies fields", function(t) {
  207. var a
  208. var warnings = []
  209. function warn(w) {
  210. warnings.push(w)
  211. }
  212. normalize(a={
  213. dependencies: [],
  214. devDependencies: [],
  215. optionalDependencies: []
  216. }, warn)
  217. t.ok(~warnings.indexOf(safeFormat(warningMessages.deprecatedArrayDependencies, 'dependencies')), "deprecation warning")
  218. t.ok(~warnings.indexOf(safeFormat(warningMessages.deprecatedArrayDependencies, 'devDependencies')), "deprecation warning")
  219. t.ok(~warnings.indexOf(safeFormat(warningMessages.deprecatedArrayDependencies, 'optionalDependencies')), "deprecation warning")
  220. t.end()
  221. })
  222. tap.test('no new globals', function(t) {
  223. t.same(Object.keys(global), globals)
  224. t.end()
  225. })