xcres 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.travis.yml +18 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +85 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +181 -0
  8. data/Rakefile +58 -0
  9. data/bin/xcres +12 -0
  10. data/lib/xcres/analyzer/aggregate_analyzer.rb +48 -0
  11. data/lib/xcres/analyzer/analyzer.rb +141 -0
  12. data/lib/xcres/analyzer/resources_aggregate_analyzer.rb +27 -0
  13. data/lib/xcres/analyzer/resources_analyzer/base_resources_analyzer.rb +133 -0
  14. data/lib/xcres/analyzer/resources_analyzer/bundle_resources_analyzer.rb +68 -0
  15. data/lib/xcres/analyzer/resources_analyzer/loose_resources_analyzer.rb +39 -0
  16. data/lib/xcres/analyzer/resources_analyzer/xcassets_analyzer.rb +62 -0
  17. data/lib/xcres/analyzer/strings_analyzer.rb +255 -0
  18. data/lib/xcres/builder/file_builder.rb +61 -0
  19. data/lib/xcres/builder/resources_builder.rb +184 -0
  20. data/lib/xcres/builder/string_builder.rb +31 -0
  21. data/lib/xcres/command/build_command.rb +83 -0
  22. data/lib/xcres/command/command.rb +58 -0
  23. data/lib/xcres/command/install_command.rb +173 -0
  24. data/lib/xcres/command/main_command.rb +14 -0
  25. data/lib/xcres/command/project_command.rb +111 -0
  26. data/lib/xcres/command/version_command.rb +12 -0
  27. data/lib/xcres/helper/file_helper.rb +16 -0
  28. data/lib/xcres/logger.rb +148 -0
  29. data/lib/xcres/model/section.rb +43 -0
  30. data/lib/xcres/model/xcassets/bundle.rb +55 -0
  31. data/lib/xcres/model/xcassets/resource.rb +141 -0
  32. data/lib/xcres/model/xcassets/resource_image.rb +134 -0
  33. data/lib/xcres/version.rb +9 -0
  34. data/lib/xcres.rb +9 -0
  35. data/spec/fixtures/Example/Example/AppDelegate.h +15 -0
  36. data/spec/fixtures/Example/Example/AppDelegate.m +49 -0
  37. data/spec/fixtures/Example/Example/Example-Info.plist +38 -0
  38. data/spec/fixtures/Example/Example/Example-Prefix.pch +16 -0
  39. data/spec/fixtures/Example/Example/Images/doge.jpeg +0 -0
  40. data/spec/fixtures/Example/Example/Images/nyanCat.png +0 -0
  41. data/spec/fixtures/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  42. data/spec/fixtures/Example/Example/Images.xcassets/Doge.imageset/Contents.json +18 -0
  43. data/spec/fixtures/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
  44. data/spec/fixtures/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
  45. data/spec/fixtures/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  46. data/spec/fixtures/Example/Example/de.lproj/Localizable.strings +12 -0
  47. data/spec/fixtures/Example/Example/en.lproj/InfoPlist.strings +2 -0
  48. data/spec/fixtures/Example/Example/en.lproj/Localizable.strings +15 -0
  49. data/spec/fixtures/Example/Example/main.m +18 -0
  50. data/spec/fixtures/Example/Example.xcodeproj/project.pbxproj +449 -0
  51. data/spec/fixtures/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  52. data/spec/fixtures/ExampleOSX/ExampleOSX/AppDelegate.h +15 -0
  53. data/spec/fixtures/ExampleOSX/ExampleOSX/AppDelegate.m +18 -0
  54. data/spec/fixtures/ExampleOSX/ExampleOSX/Base.lproj/MainMenu.xib +680 -0
  55. data/spec/fixtures/ExampleOSX/ExampleOSX/ExampleOSX-Info.plist +34 -0
  56. data/spec/fixtures/ExampleOSX/ExampleOSX/ExampleOSX-Prefix.pch +9 -0
  57. data/spec/fixtures/ExampleOSX/ExampleOSX/Images.xcassets/AppIcon.appiconset/Contents.json +58 -0
  58. data/spec/fixtures/ExampleOSX/ExampleOSX/en.lproj/Credits.rtf +29 -0
  59. data/spec/fixtures/ExampleOSX/ExampleOSX/en.lproj/InfoPlist.strings +2 -0
  60. data/spec/fixtures/ExampleOSX/ExampleOSX/main.m +14 -0
  61. data/spec/fixtures/ExampleOSX/ExampleOSX.xcodeproj/project.pbxproj +481 -0
  62. data/spec/fixtures/ExampleOSX/ExampleOSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  63. data/spec/fixtures/ExampleOSX/ExampleOSXTests/ExampleOSXTests-Info.plist +22 -0
  64. data/spec/fixtures/ExampleOSX/ExampleOSXTests/ExampleOSXTests.m +34 -0
  65. data/spec/fixtures/ExampleOSX/ExampleOSXTests/en.lproj/InfoPlist.strings +2 -0
  66. data/spec/integration/build/after/Example/Example/AppDelegate.h +15 -0
  67. data/spec/integration/build/after/Example/Example/AppDelegate.m +49 -0
  68. data/spec/integration/build/after/Example/Example/Example-Info.plist +38 -0
  69. data/spec/integration/build/after/Example/Example/Example-Prefix.pch +16 -0
  70. data/spec/integration/build/after/Example/Example/Icons.bundle/tab_bar/tabbar_list.png +0 -0
  71. data/spec/integration/build/after/Example/Example/Icons.bundle/tab_bar/tabbar_list@2x.png +0 -0
  72. data/spec/integration/build/after/Example/Example/Icons.bundle/tab_bar/tabbar_map.png +0 -0
  73. data/spec/integration/build/after/Example/Example/Icons.bundle/tab_bar/tabbar_map@2x.png +0 -0
  74. data/spec/integration/build/after/Example/Example/Images/doge.jpeg +0 -0
  75. data/spec/integration/build/after/Example/Example/Images/nyanCat.png +0 -0
  76. data/spec/integration/build/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  77. data/spec/integration/build/after/Example/Example/Images.xcassets/Doge.imageset/Contents.json +18 -0
  78. data/spec/integration/build/after/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
  79. data/spec/integration/build/after/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
  80. data/spec/integration/build/after/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  81. data/spec/integration/build/after/Example/Example/de.lproj/Localizable.strings +12 -0
  82. data/spec/integration/build/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
  83. data/spec/integration/build/after/Example/Example/en.lproj/Localizable.strings +15 -0
  84. data/spec/integration/build/after/Example/Example/main.m +18 -0
  85. data/spec/integration/build/after/Example/Example.xcodeproj.yaml +168 -0
  86. data/spec/integration/build/after/R.h +39 -0
  87. data/spec/integration/build/after/R.m +29 -0
  88. data/spec/integration/build/after/execution_output.txt +19 -0
  89. data/spec/integration/build/before/Example/Example/AppDelegate.h +15 -0
  90. data/spec/integration/build/before/Example/Example/AppDelegate.m +49 -0
  91. data/spec/integration/build/before/Example/Example/Example-Info.plist +38 -0
  92. data/spec/integration/build/before/Example/Example/Example-Prefix.pch +16 -0
  93. data/spec/integration/build/before/Example/Example/Icons.bundle/tab_bar/tabbar_list.png +0 -0
  94. data/spec/integration/build/before/Example/Example/Icons.bundle/tab_bar/tabbar_list@2x.png +0 -0
  95. data/spec/integration/build/before/Example/Example/Icons.bundle/tab_bar/tabbar_map.png +0 -0
  96. data/spec/integration/build/before/Example/Example/Icons.bundle/tab_bar/tabbar_map@2x.png +0 -0
  97. data/spec/integration/build/before/Example/Example/Images/doge.jpeg +0 -0
  98. data/spec/integration/build/before/Example/Example/Images/nyanCat.png +0 -0
  99. data/spec/integration/build/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  100. data/spec/integration/build/before/Example/Example/Images.xcassets/Doge.imageset/Contents.json +18 -0
  101. data/spec/integration/build/before/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
  102. data/spec/integration/build/before/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
  103. data/spec/integration/build/before/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  104. data/spec/integration/build/before/Example/Example/de.lproj/Localizable.strings +12 -0
  105. data/spec/integration/build/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
  106. data/spec/integration/build/before/Example/Example/en.lproj/Localizable.strings +15 -0
  107. data/spec/integration/build/before/Example/Example/main.m +18 -0
  108. data/spec/integration/build/before/Example/Example.xcodeproj/project.pbxproj +453 -0
  109. data/spec/integration/build/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  110. data/spec/integration/build-keyword-clash/after/Example/Example/AppDelegate.h +15 -0
  111. data/spec/integration/build-keyword-clash/after/Example/Example/AppDelegate.m +49 -0
  112. data/spec/integration/build-keyword-clash/after/Example/Example/Default-568h@2x.png +0 -0
  113. data/spec/integration/build-keyword-clash/after/Example/Example/Default.png +0 -0
  114. data/spec/integration/build-keyword-clash/after/Example/Example/Default@2x.png +0 -0
  115. data/spec/integration/build-keyword-clash/after/Example/Example/Example-Info.plist +38 -0
  116. data/spec/integration/build-keyword-clash/after/Example/Example/Example-Prefix.pch +16 -0
  117. data/spec/integration/build-keyword-clash/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  118. data/spec/integration/build-keyword-clash/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
  119. data/spec/integration/build-keyword-clash/after/Example/Example/main.m +18 -0
  120. data/spec/integration/build-keyword-clash/after/Example/Example.xcodeproj.yaml +160 -0
  121. data/spec/integration/build-keyword-clash/after/R.h +15 -0
  122. data/spec/integration/build-keyword-clash/after/R.m +15 -0
  123. data/spec/integration/build-keyword-clash/after/execution_output.txt +14 -0
  124. data/spec/integration/build-keyword-clash/before/Example/Example/AppDelegate.h +15 -0
  125. data/spec/integration/build-keyword-clash/before/Example/Example/AppDelegate.m +49 -0
  126. data/spec/integration/build-keyword-clash/before/Example/Example/Default-568h@2x.png +0 -0
  127. data/spec/integration/build-keyword-clash/before/Example/Example/Default.png +0 -0
  128. data/spec/integration/build-keyword-clash/before/Example/Example/Default@2x.png +0 -0
  129. data/spec/integration/build-keyword-clash/before/Example/Example/Example-Info.plist +38 -0
  130. data/spec/integration/build-keyword-clash/before/Example/Example/Example-Prefix.pch +16 -0
  131. data/spec/integration/build-keyword-clash/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  132. data/spec/integration/build-keyword-clash/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
  133. data/spec/integration/build-keyword-clash/before/Example/Example/main.m +18 -0
  134. data/spec/integration/build-keyword-clash/before/Example/Example.xcodeproj/project.pbxproj +427 -0
  135. data/spec/integration/build-keyword-clash/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  136. data/spec/integration/build-var-infoplist/after/Example/Example/AppDelegate.h +15 -0
  137. data/spec/integration/build-var-infoplist/after/Example/Example/AppDelegate.m +49 -0
  138. data/spec/integration/build-var-infoplist/after/Example/Example/Example-Info.plist +38 -0
  139. data/spec/integration/build-var-infoplist/after/Example/Example/Example-Prefix.pch +16 -0
  140. data/spec/integration/build-var-infoplist/after/Example/Example/Icons.bundle/tab_bar/tabbar_list.png +0 -0
  141. data/spec/integration/build-var-infoplist/after/Example/Example/Icons.bundle/tab_bar/tabbar_list@2x.png +0 -0
  142. data/spec/integration/build-var-infoplist/after/Example/Example/Icons.bundle/tab_bar/tabbar_map.png +0 -0
  143. data/spec/integration/build-var-infoplist/after/Example/Example/Icons.bundle/tab_bar/tabbar_map@2x.png +0 -0
  144. data/spec/integration/build-var-infoplist/after/Example/Example/Images/doge.jpeg +0 -0
  145. data/spec/integration/build-var-infoplist/after/Example/Example/Images/nyanCat.png +0 -0
  146. data/spec/integration/build-var-infoplist/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  147. data/spec/integration/build-var-infoplist/after/Example/Example/Images.xcassets/Doge.imageset/Contents.json +18 -0
  148. data/spec/integration/build-var-infoplist/after/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
  149. data/spec/integration/build-var-infoplist/after/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
  150. data/spec/integration/build-var-infoplist/after/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  151. data/spec/integration/build-var-infoplist/after/Example/Example/de.lproj/Localizable.strings +12 -0
  152. data/spec/integration/build-var-infoplist/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
  153. data/spec/integration/build-var-infoplist/after/Example/Example/en.lproj/Localizable.strings +15 -0
  154. data/spec/integration/build-var-infoplist/after/Example/Example/main.m +18 -0
  155. data/spec/integration/build-var-infoplist/after/Example/Example.xcodeproj.yaml +168 -0
  156. data/spec/integration/build-var-infoplist/after/R.h +39 -0
  157. data/spec/integration/build-var-infoplist/after/R.m +29 -0
  158. data/spec/integration/build-var-infoplist/after/execution_output.txt +19 -0
  159. data/spec/integration/build-var-infoplist/before/Example/Example/AppDelegate.h +15 -0
  160. data/spec/integration/build-var-infoplist/before/Example/Example/AppDelegate.m +49 -0
  161. data/spec/integration/build-var-infoplist/before/Example/Example/Example-Info.plist +38 -0
  162. data/spec/integration/build-var-infoplist/before/Example/Example/Example-Prefix.pch +16 -0
  163. data/spec/integration/build-var-infoplist/before/Example/Example/Icons.bundle/tab_bar/tabbar_list.png +0 -0
  164. data/spec/integration/build-var-infoplist/before/Example/Example/Icons.bundle/tab_bar/tabbar_list@2x.png +0 -0
  165. data/spec/integration/build-var-infoplist/before/Example/Example/Icons.bundle/tab_bar/tabbar_map.png +0 -0
  166. data/spec/integration/build-var-infoplist/before/Example/Example/Icons.bundle/tab_bar/tabbar_map@2x.png +0 -0
  167. data/spec/integration/build-var-infoplist/before/Example/Example/Images/doge.jpeg +0 -0
  168. data/spec/integration/build-var-infoplist/before/Example/Example/Images/nyanCat.png +0 -0
  169. data/spec/integration/build-var-infoplist/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  170. data/spec/integration/build-var-infoplist/before/Example/Example/Images.xcassets/Doge.imageset/Contents.json +18 -0
  171. data/spec/integration/build-var-infoplist/before/Example/Example/Images.xcassets/Doge.imageset/doge.png +0 -0
  172. data/spec/integration/build-var-infoplist/before/Example/Example/Images.xcassets/Doge.imageset/doge@2x.png +0 -0
  173. data/spec/integration/build-var-infoplist/before/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  174. data/spec/integration/build-var-infoplist/before/Example/Example/de.lproj/Localizable.strings +12 -0
  175. data/spec/integration/build-var-infoplist/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
  176. data/spec/integration/build-var-infoplist/before/Example/Example/en.lproj/Localizable.strings +15 -0
  177. data/spec/integration/build-var-infoplist/before/Example/Example/main.m +18 -0
  178. data/spec/integration/build-var-infoplist/before/Example/Example.xcodeproj/project.pbxproj +453 -0
  179. data/spec/integration/build-var-infoplist/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  180. data/spec/integration/help/after/execution_output.txt +18 -0
  181. data/spec/integration/help/before/.gitkeep +0 -0
  182. data/spec/integration/install/after/Example/Example/AppDelegate.h +15 -0
  183. data/spec/integration/install/after/Example/Example/AppDelegate.m +49 -0
  184. data/spec/integration/install/after/Example/Example/Example-Info.plist +38 -0
  185. data/spec/integration/install/after/Example/Example/Example-Prefix.pch +18 -0
  186. data/spec/integration/install/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  187. data/spec/integration/install/after/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  188. data/spec/integration/install/after/Example/Example/Resources/R.h +19 -0
  189. data/spec/integration/install/after/Example/Example/Resources/R.m +17 -0
  190. data/spec/integration/install/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
  191. data/spec/integration/install/after/Example/Example/main.m +18 -0
  192. data/spec/integration/install/after/Example/Example.xcodeproj/project.pbxproj +898 -0
  193. data/spec/integration/install/after/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  194. data/spec/integration/install/after/Example/Example.xcodeproj.yaml +172 -0
  195. data/spec/integration/install/after/execution_output.txt +22 -0
  196. data/spec/integration/install/before/Example/Example/AppDelegate.h +15 -0
  197. data/spec/integration/install/before/Example/Example/AppDelegate.m +49 -0
  198. data/spec/integration/install/before/Example/Example/Example-Info.plist +38 -0
  199. data/spec/integration/install/before/Example/Example/Example-Prefix.pch +16 -0
  200. data/spec/integration/install/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  201. data/spec/integration/install/before/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  202. data/spec/integration/install/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
  203. data/spec/integration/install/before/Example/Example/main.m +18 -0
  204. data/spec/integration/install/before/Example/Example.xcodeproj/project.pbxproj +421 -0
  205. data/spec/integration/install/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  206. data/spec/integration/install-again/after/Example/Example/AppDelegate.h +15 -0
  207. data/spec/integration/install-again/after/Example/Example/AppDelegate.m +49 -0
  208. data/spec/integration/install-again/after/Example/Example/Example-Info.plist +38 -0
  209. data/spec/integration/install-again/after/Example/Example/Example-Prefix.pch +18 -0
  210. data/spec/integration/install-again/after/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  211. data/spec/integration/install-again/after/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  212. data/spec/integration/install-again/after/Example/Example/Resources/R.h +19 -0
  213. data/spec/integration/install-again/after/Example/Example/Resources/R.m +17 -0
  214. data/spec/integration/install-again/after/Example/Example/en.lproj/InfoPlist.strings +2 -0
  215. data/spec/integration/install-again/after/Example/Example/main.m +18 -0
  216. data/spec/integration/install-again/after/Example/Example.xcodeproj.yaml +172 -0
  217. data/spec/integration/install-again/after/execution_output.txt +23 -0
  218. data/spec/integration/install-again/before/Example/Example/AppDelegate.h +15 -0
  219. data/spec/integration/install-again/before/Example/Example/AppDelegate.m +49 -0
  220. data/spec/integration/install-again/before/Example/Example/Example-Info.plist +38 -0
  221. data/spec/integration/install-again/before/Example/Example/Example-Prefix.pch +18 -0
  222. data/spec/integration/install-again/before/Example/Example/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  223. data/spec/integration/install-again/before/Example/Example/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  224. data/spec/integration/install-again/before/Example/Example/Resources/R.h +19 -0
  225. data/spec/integration/install-again/before/Example/Example/Resources/R.m +17 -0
  226. data/spec/integration/install-again/before/Example/Example/en.lproj/InfoPlist.strings +2 -0
  227. data/spec/integration/install-again/before/Example/Example/main.m +18 -0
  228. data/spec/integration/install-again/before/Example/Example.xcodeproj/project.pbxproj +898 -0
  229. data/spec/integration/install-again/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  230. data/spec/integration/install-moved-supporting-files/after/Example/Example.xcodeproj.yaml +173 -0
  231. data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/Example-Info.plist +38 -0
  232. data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/Example-Prefix.pch +18 -0
  233. data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/Resources/R.h +19 -0
  234. data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/Resources/R.m +17 -0
  235. data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/en.lproj/InfoPlist.strings +2 -0
  236. data/spec/integration/install-moved-supporting-files/after/Example/Supporting_Files/main.m +18 -0
  237. data/spec/integration/install-moved-supporting-files/after/Example/res/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  238. data/spec/integration/install-moved-supporting-files/after/Example/res/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  239. data/spec/integration/install-moved-supporting-files/after/Example/src/AppDelegate.h +15 -0
  240. data/spec/integration/install-moved-supporting-files/after/Example/src/AppDelegate.m +49 -0
  241. data/spec/integration/install-moved-supporting-files/after/execution_output.txt +22 -0
  242. data/spec/integration/install-moved-supporting-files/before/Example/Example.xcodeproj/project.pbxproj +431 -0
  243. data/spec/integration/install-moved-supporting-files/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  244. data/spec/integration/install-moved-supporting-files/before/Example/Supporting_Files/Example-Info.plist +38 -0
  245. data/spec/integration/install-moved-supporting-files/before/Example/Supporting_Files/Example-Prefix.pch +16 -0
  246. data/spec/integration/install-moved-supporting-files/before/Example/Supporting_Files/en.lproj/InfoPlist.strings +2 -0
  247. data/spec/integration/install-moved-supporting-files/before/Example/Supporting_Files/main.m +18 -0
  248. data/spec/integration/install-moved-supporting-files/before/Example/res/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  249. data/spec/integration/install-moved-supporting-files/before/Example/res/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  250. data/spec/integration/install-moved-supporting-files/before/Example/src/AppDelegate.h +15 -0
  251. data/spec/integration/install-moved-supporting-files/before/Example/src/AppDelegate.m +49 -0
  252. data/spec/integration/install-no-supporting-files/after/Example/Example.xcodeproj.yaml +173 -0
  253. data/spec/integration/install-no-supporting-files/after/Example/Resources/R.h +19 -0
  254. data/spec/integration/install-no-supporting-files/after/Example/Resources/R.m +17 -0
  255. data/spec/integration/install-no-supporting-files/after/Example/Supporting_Files/Example-Info.plist +38 -0
  256. data/spec/integration/install-no-supporting-files/after/Example/Supporting_Files/Example-Prefix.pch +18 -0
  257. data/spec/integration/install-no-supporting-files/after/Example/Supporting_Files/en.lproj/InfoPlist.strings +2 -0
  258. data/spec/integration/install-no-supporting-files/after/Example/Supporting_Files/main.m +18 -0
  259. data/spec/integration/install-no-supporting-files/after/Example/res/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  260. data/spec/integration/install-no-supporting-files/after/Example/res/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  261. data/spec/integration/install-no-supporting-files/after/Example/src/AppDelegate.h +15 -0
  262. data/spec/integration/install-no-supporting-files/after/Example/src/AppDelegate.m +49 -0
  263. data/spec/integration/install-no-supporting-files/after/execution_output.txt +23 -0
  264. data/spec/integration/install-no-supporting-files/before/Example/Example.xcodeproj/project.pbxproj +430 -0
  265. data/spec/integration/install-no-supporting-files/before/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  266. data/spec/integration/install-no-supporting-files/before/Example/Supporting_Files/Example-Info.plist +38 -0
  267. data/spec/integration/install-no-supporting-files/before/Example/Supporting_Files/Example-Prefix.pch +16 -0
  268. data/spec/integration/install-no-supporting-files/before/Example/Supporting_Files/en.lproj/InfoPlist.strings +2 -0
  269. data/spec/integration/install-no-supporting-files/before/Example/Supporting_Files/main.m +18 -0
  270. data/spec/integration/install-no-supporting-files/before/Example/res/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  271. data/spec/integration/install-no-supporting-files/before/Example/res/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  272. data/spec/integration/install-no-supporting-files/before/Example/src/AppDelegate.h +15 -0
  273. data/spec/integration/install-no-supporting-files/before/Example/src/AppDelegate.m +49 -0
  274. data/spec/integration/version/after/execution_output.txt +3 -0
  275. data/spec/integration/version/before/.gitkeep +0 -0
  276. data/spec/integration.rb +86 -0
  277. data/spec/spec_helper/xcodeproj_project_yaml.rb +26 -0
  278. data/spec/unit/analyzer/aggregate_analyzer_spec.rb +61 -0
  279. data/spec/unit/analyzer/analyzer_spec.rb +123 -0
  280. data/spec/unit/analyzer/resources_aggregate_analyzer_spec.rb +46 -0
  281. data/spec/unit/analyzer/resources_analyzer/base_resources_analyzer_spec.rb +126 -0
  282. data/spec/unit/analyzer/resources_analyzer/bundle_resources_analyzer_spec.rb +57 -0
  283. data/spec/unit/analyzer/resources_analyzer/loose_resources_analyzer_spec.rb +22 -0
  284. data/spec/unit/analyzer/strings_analyzer_spec.rb +99 -0
  285. data/spec/unit/builder/file_builder_spec.rb +46 -0
  286. data/spec/unit/builder/resources_builder_spec.rb +50 -0
  287. data/spec/unit/builder/string_builder_spec.rb +76 -0
  288. data/spec/unit/command/main_command_spec.rb +5 -0
  289. data/spec/unit/command/project_command_spec.rb +23 -0
  290. data/spec/unit/helper/file_helper_spec.rb +24 -0
  291. data/spec/unit/logger_spec.rb +142 -0
  292. data/spec/unit/model/section_spec.rb +47 -0
  293. data/spec/unit/model/xcassets/bundle_spec.rb +154 -0
  294. data/spec/unit/model/xcassets/resource_image_spec.rb +141 -0
  295. data/spec/unit/model/xcassets/resource_spec.rb +174 -0
  296. data/spec/unit/model/xcassets/spec_helper.rb +31 -0
  297. data/spec/unit/spec_helper.rb +17 -0
  298. data/xcres.gemspec +42 -0
  299. metadata +811 -0
@@ -0,0 +1,86 @@
1
+ require 'bacon'
2
+ require 'pretty_bacon'
3
+ require 'clintegracon'
4
+ require File.expand_path('../spec_helper/xcodeproj_project_yaml', __FILE__)
5
+
6
+ ROOT = Pathname.new(File.expand_path('../..', __FILE__))
7
+ BIN = ROOT + 'bin'
8
+
9
+ CLIntegracon.configure do |c|
10
+ c.spec_path = ROOT + 'spec/integration'
11
+ c.temp_path = ROOT + 'tmp/integration'
12
+
13
+ c.hook_into :bacon
14
+
15
+ c.ignores '.DS_Store'
16
+ c.ignores '**.DS_Store'
17
+ c.ignores '.gitkeep'
18
+ c.ignores %r[/xcuserdata/]
19
+
20
+ # Transform produced project files to YAMLs
21
+ c.transform_produced "**/*.xcodeproj" do |path|
22
+ # Creates a YAML representation of the Xcodeproj files
23
+ # which should be used as a reference for comparison.
24
+ xcodeproj = Xcodeproj::Project.open(path)
25
+ File.open("#{path}.yaml", "w") do |file|
26
+ file.write xcodeproj.to_yaml
27
+ end
28
+ end
29
+
30
+ # So we don't need to compare them directly
31
+ c.ignores %r[\.xcodeproj/]
32
+ end
33
+
34
+
35
+ describe_cli 'xcres' do
36
+
37
+ subject do |s|
38
+ s.executable = "#{BIN}/xcres"
39
+ s.default_args = [
40
+ '--verbose',
41
+ '--no-ansi'
42
+ ]
43
+ s.replace_path ROOT.to_s, 'ROOT'
44
+ end
45
+
46
+ describe 'Build' do
47
+ describe 'with default settings' do
48
+ behaves_like cli_spec('build', '', 'build Example .')
49
+ end
50
+
51
+ describe 'with variable INFOPLIST_PATH' do
52
+ behaves_like cli_spec('build-var-infoplist', '', 'build Example .')
53
+ end
54
+
55
+ describe 'with resource which has a protected name' do
56
+ behaves_like cli_spec('build-keyword-clash', '', 'build Example .')
57
+ end
58
+ end
59
+
60
+ describe 'Install' do
61
+ describe 'with default template' do
62
+ behaves_like cli_spec('install', '', 'install Example')
63
+ end
64
+
65
+ describe 'with existing installation' do
66
+ behaves_like cli_spec('install-again', '', 'install Example')
67
+ end
68
+
69
+ describe 'without supporting files' do
70
+ behaves_like cli_spec('install-no-supporting-files', '', 'install Example')
71
+ end
72
+
73
+ describe 'with moved supporting files' do
74
+ behaves_like cli_spec('install-moved-supporting-files', '', 'install Example')
75
+ end
76
+ end
77
+
78
+ describe 'Get help' do
79
+ behaves_like cli_spec('help', '--help')
80
+ end
81
+
82
+ describe 'Get version' do
83
+ behaves_like cli_spec('version', 'version')
84
+ end
85
+
86
+ end
@@ -0,0 +1,26 @@
1
+ require 'xcodeproj'
2
+ require 'yaml'
3
+
4
+ class Xcodeproj::Project::Object::PBXShellScriptBuildPhase
5
+ def pretty_print
6
+ hash = {}
7
+ simple_attributes.each do |attr|
8
+ value = attr.get_value(self)
9
+ hash[attr.plist_name] = value if value
10
+ end
11
+ { display_name => hash }
12
+ end
13
+ end
14
+
15
+ class Xcodeproj::Project
16
+ def to_yaml
17
+ pretty_print_output = pretty_print
18
+ sections = []
19
+ sorted_keys = ['File References', 'Targets', 'Build Configurations']
20
+ sorted_keys.each do |key|
21
+ yaml = { key => pretty_print_output[key] }.to_yaml
22
+ sections << yaml
23
+ end
24
+ (sections * "\n\n").gsub!('---', '')
25
+ end
26
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::AggregateAnalyzer' do
4
+
5
+ def subject
6
+ XCRes::AggregateAnalyzer
7
+ end
8
+
9
+ before do
10
+ @analyzer = subject.new
11
+ end
12
+
13
+ describe '#initialize' do
14
+ it 'should initialize #analyzers with an empty array' do
15
+ @analyzer.analyzers.should.be.eql?([])
16
+ end
17
+ end
18
+
19
+ describe '#analyze' do
20
+ it 'should return aggregated output of all child analyzers' do
21
+ section1 = mock()
22
+ @analyzer.analyzers << mock(analyze: [section1])
23
+
24
+ section2 = mock()
25
+ @analyzer.analyzers << mock(analyze: [section2])
26
+
27
+ @analyzer.analyze.should.be.eql?([section1, section2])
28
+ end
29
+
30
+ it 'should return an empty array if there are no child analyzers' do
31
+ @analyzer.analyze.should.be.empty?
32
+ end
33
+ end
34
+
35
+ describe '#add_with_class' do
36
+ it 'should init an analyzer of given class with current attributes' do
37
+ @analyzer = subject.new(mock('Target'))
38
+ @analyzer.logger = mock('Logger')
39
+ @analyzer.exclude_file_patterns = ['foo', 'bar']
40
+
41
+ new_analyzer = @analyzer.add_with_class(XCRes::Analyzer, {})
42
+ new_analyzer.should.be.an.instance_of?(XCRes::Analyzer)
43
+ new_analyzer.should.be.equal?(@analyzer.analyzers.last)
44
+ new_analyzer.target.should.be.equal?(@analyzer.target)
45
+ new_analyzer.logger.should.be.equal?(@analyzer.logger)
46
+ new_analyzer.exclude_file_patterns.should.be.equal?(@analyzer.exclude_file_patterns)
47
+ end
48
+
49
+ it 'should pass the options to the initializer' do
50
+ result = @analyzer.add_with_class(XCRes::Analyzer, the_answer: 42)
51
+ result.options.should.be.eql?({ the_answer: 42 })
52
+ end
53
+
54
+ it 'should pass the merged options to the initializer' do
55
+ @analyzer.options = { the_question: '6x7=?' }
56
+ result = @analyzer.add_with_class(XCRes::Analyzer,the_answer: 42)
57
+ result.options.should.be.eql?({ the_question: '6x7=?', the_answer: 42 })
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,123 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::Analyzer' do
4
+
5
+ def subject
6
+ XCRes::Analyzer
7
+ end
8
+
9
+ before do
10
+ @target = app_target
11
+ @analyzer = subject.new(@target)
12
+ end
13
+
14
+ describe '#new_section' do
15
+ describe 'without configured options' do
16
+ describe 'without options given as argument' do
17
+ it 'should return a new section' do
18
+ @analyzer.new_section('Name', { a: 'a' })
19
+ .should.be.eql? XCRes::Section.new('Name', { a: 'a' })
20
+ end
21
+ end
22
+
23
+ describe 'with options given as argument' do
24
+ it 'should return a new section' do
25
+ @analyzer.new_section('Name', { a: 'a' }, the_answer: 42)
26
+ .should.be.eql? XCRes::Section.new('Name', { a: 'a' }, the_answer: 42)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe 'with configured options' do
32
+ before do
33
+ @analyzer.options = { the_answer: 42, the_question: '6x7=?' }
34
+ end
35
+
36
+ describe 'without options given as argument' do
37
+ it 'should return a new section' do
38
+ @analyzer.new_section('Name', { a: 'a' })
39
+ .should.be.eql? XCRes::Section.new('Name', { a: 'a' }, the_answer: 42, the_question: '6x7=?')
40
+ end
41
+ end
42
+
43
+ describe 'with options given as argument' do
44
+ it 'should return a new section' do
45
+ @analyzer.new_section('Name', { a: 'a' }, the_answer: 21)
46
+ .should.be.eql? XCRes::Section.new('Name', { a: 'a' }, the_answer: 21, the_question: '6x7=?')
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#filter_exclusions' do
53
+ describe 'single asterisk' do
54
+ it 'rejects file paths on first hierarchy level' do
55
+ @analyzer.exclude_file_patterns = ['*.gif']
56
+ @analyzer.filter_exclusions(['cat.jpg', 'doge.gif']).should.be.eql?(['cat.jpg'])
57
+ end
58
+
59
+ it 'rejects file paths in nested directories by default' do
60
+ @analyzer.exclude_file_patterns = ['*.gif']
61
+ @analyzer.filter_exclusions(['top_doge.gif', 'sub/sub/doge.gif', 'sub/sub/doge.gif']).should.be.eql?([])
62
+ end
63
+ end
64
+
65
+ describe 'double asterisk' do
66
+ it 'rejects file paths in nested directories only' do
67
+ @analyzer.exclude_file_patterns = ['**.gif']
68
+ @analyzer.filter_exclusions(['top_doge.gif', 'sub/sub/doge.gif', 'sub/sub/doge.gif']).should.be.eql?([])
69
+ end
70
+ end
71
+
72
+ it 'rejects hidden files' do
73
+ @analyzer.exclude_file_patterns = ['.git']
74
+ @analyzer.filter_exclusions(['.git']).should.be.eql?([])
75
+ end
76
+ end
77
+
78
+ describe '#find_files_by_extname' do
79
+ it 'should return an empty list for an empty project' do
80
+ @analyzer.project.stubs(:files).returns([])
81
+ @analyzer.find_file_refs_by_extname('.bundle').should.be.eql?([])
82
+ end
83
+
84
+ it 'should return matching files' do
85
+ @bundle = stub('FileRef', path: 'the-whole.bundle')
86
+ @img = stub('FileRef', path: 'awesome.jpg')
87
+ @target.project.stubs(:files).returns([@bundle, @img])
88
+
89
+ @analyzer.stubs(:is_file_ref_included_in_application_target?)
90
+ .returns(true)
91
+ @analyzer.find_file_refs_by_extname('.bundle').should.be.eql?([@bundle])
92
+ end
93
+
94
+ it 'should not return files, which do not belong to an application target' do
95
+ @dog_img = stub('FileRef', path: 'doge.jpg')
96
+ @cat_img = stub('FileRef', path: 'nyancat.jpg')
97
+ @target.project.stubs(:files).returns([@dog_img, @cat_img])
98
+
99
+ @analyzer.stubs(:is_file_ref_included_in_application_target?)
100
+ .with(@dog_img).returns(true)
101
+ @analyzer.stubs(:is_file_ref_included_in_application_target?)
102
+ .with(@cat_img).returns(false)
103
+ @analyzer.find_file_refs_by_extname('.jpg').should.be.eql?([@dog_img])
104
+ end
105
+ end
106
+
107
+ describe '#is_file_ref_included_in_application_target?' do
108
+ it 'should return true for included files' do
109
+ file = @target.project.files.find { |f| f.path.to_s == 'doge.jpeg' }
110
+ file.should.be.an.instance_of?(Xcodeproj::Project::Object::PBXFileReference)
111
+ @analyzer.is_file_ref_included_in_application_target?(file)
112
+ .should.be.true?
113
+ end
114
+
115
+ it 'should return false for non-included files' do
116
+ file = @target.project.files.find { |f| f.path.to_s == 'nyanCat.png' }
117
+ file.should.be.an.instance_of?(Xcodeproj::Project::Object::PBXFileReference)
118
+ @analyzer.is_file_ref_included_in_application_target?(file)
119
+ .should.be.false?
120
+ end
121
+ end
122
+
123
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::ResourcesAggregateAnalyzer' do
4
+
5
+ def subject
6
+ XCRes::ResourcesAggregateAnalyzer
7
+ end
8
+
9
+ before do
10
+ @analyzer = subject.new
11
+ @analyzer.logger = stub('Logger', :log)
12
+ end
13
+
14
+ describe '#analyze' do
15
+ it 'should return all sections' do
16
+ bundle_section_a = stub('Bundle Section A')
17
+ bundle_section_b = stub('Bundle Section B')
18
+ loose_image_section = stub('Loose Images Section')
19
+ xcassets_section = stub('XCAssets Section')
20
+
21
+ XCRes::ResourcesAnalyzer::BundleResourcesAnalyzer.any_instance
22
+ .expects(:analyze).returns([bundle_section_a, bundle_section_b])
23
+ XCRes::ResourcesAnalyzer::LooseResourcesAnalyzer.any_instance
24
+ .expects(:analyze).returns(loose_image_section)
25
+ XCRes::ResourcesAnalyzer::XCAssetsAnalyzer.any_instance
26
+ .expects(:analyze).returns(xcassets_section)
27
+
28
+ @analyzer.analyze.should.eql?([bundle_section_a, bundle_section_b, loose_image_section, xcassets_section])
29
+ end
30
+
31
+ it 'should return only bundle sections if there are no loose images' do
32
+ bundle_section = stub('Bundle Section')
33
+ xcassets_section = stub('XCAssets Section')
34
+
35
+ XCRes::ResourcesAnalyzer::BundleResourcesAnalyzer.any_instance
36
+ .expects(:analyze).returns(bundle_section)
37
+ XCRes::ResourcesAnalyzer::LooseResourcesAnalyzer.any_instance
38
+ .expects(:analyze).returns([])
39
+ XCRes::ResourcesAnalyzer::XCAssetsAnalyzer.any_instance
40
+ .expects(:analyze).returns(xcassets_section)
41
+
42
+ @analyzer.analyze.should.eql?([bundle_section, xcassets_section])
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,126 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::ResourcesAnalyzer::BaseResourcesAnalyzer' do
4
+
5
+ def subject
6
+ XCRes::ResourcesAnalyzer::BaseResourcesAnalyzer
7
+ end
8
+
9
+ before do
10
+ @analyzer = subject.new
11
+ @analyzer.logger = stub('Logger', :log)
12
+ end
13
+
14
+ describe '#find_files_in_dir' do
15
+ # TODO: Test using fakefs, ...
16
+ end
17
+
18
+ describe '#build_images_section_data' do
19
+ it 'returns an empty hash if no files were given' do
20
+ @analyzer.build_images_section_data([]).should.eql?({})
21
+ end
22
+
23
+ describe 'option use_basename? is not given' do
24
+ it 'builds an items hash and keep the path' do
25
+ @analyzer.build_images_section_data([Pathname('b/a.m'), Pathname('b/a.gif')])
26
+ .should.eql?({ 'b/a' => 'b/a.gif' })
27
+ end
28
+ end
29
+
30
+ describe 'option use_basename? is given as true' do
31
+ it 'builds an items hash and remove the path' do
32
+ @analyzer.build_images_section_data([Pathname('b/a.m'), Pathname('b/a.gif')], use_basename?: true)
33
+ .should.eql?({ 'a' => 'a.gif' })
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#filter_device_specific_image_paths' do
39
+ it 'returns an empty list if no files were given' do
40
+ @analyzer.filter_device_specific_image_paths([]).should.eql?([])
41
+ end
42
+
43
+ it 'filters device scale specific images without doublets' do
44
+ @analyzer.filter_device_specific_image_paths(['a.png', 'a@2x.png']).should.eql?(['a.png'])
45
+ end
46
+
47
+ it 'filters device scale specifiers from image paths' do
48
+ @analyzer.filter_device_specific_image_paths(['a@2x.png']).should.eql?(['a.png'])
49
+ end
50
+
51
+ it 'filters idiom specific images without doublets' do
52
+ @analyzer.filter_device_specific_image_paths(['a.png', 'a~iphone.png', 'a~ipad.png']).should.eql?(['a.png'])
53
+ end
54
+
55
+ it 'filters idiom specifiers from image paths' do
56
+ @analyzer.filter_device_specific_image_paths(['a~iphone.png']).should.eql?(['a.png'])
57
+ @analyzer.filter_device_specific_image_paths(['a~ipad.png']).should.eql?(['a.png'])
58
+ end
59
+ end
60
+
61
+ describe '#find_image_files' do
62
+ it 'returns a empty list if no files were given' do
63
+ @analyzer.find_image_files([]).should.eql?([])
64
+ end
65
+
66
+ it 'matches common image formats' do
67
+ @analyzer.find_image_files(['a.png', 'b.jpg', 'c.jpeg', 'd.gif', 'e.txt'])
68
+ .should.eql?(['a.png', 'b.jpg', 'c.jpeg', 'd.gif'])
69
+ end
70
+ end
71
+
72
+ describe '#build_section_data' do
73
+ before do
74
+ @file_paths = [Pathname('a/b')]
75
+ end
76
+
77
+ it 'returns an empty hash if no file paths given' do
78
+ @analyzer.build_section_data([]).should.be.eql?({})
79
+ end
80
+
81
+ it 'returns a hash with the basename if option use_basename? is enabled' do
82
+ @analyzer.expects(:key_from_path).with('b').returns('b')
83
+ @analyzer.build_section_data(@file_paths, use_basename?: true)
84
+ .should.be.eql?({ 'b' => 'b' })
85
+ end
86
+
87
+ it 'returns a hash with relative paths if option use_basename? is disabled' do
88
+ @analyzer.expects(:key_from_path).with('a/b').returns('a/b')
89
+ @analyzer.build_section_data(@file_paths, use_basename?: false)
90
+ .should.be.eql?({ 'a/b' => 'a/b' })
91
+ end
92
+
93
+ it 'returns a hash with relative paths if option use_basename? is not given' do
94
+ @analyzer.expects(:key_from_path).with('a/b').returns('a/b')
95
+ @analyzer.build_section_data(@file_paths)
96
+ .should.be.eql?({ 'a/b' => 'a/b' })
97
+ end
98
+ end
99
+
100
+ describe '#key_from_path' do
101
+ it 'should keep the path' do
102
+ @analyzer.key_from_path('b/a').should.be.eql?('b/a')
103
+ end
104
+
105
+ it 'should cut the file extension' do
106
+ @analyzer.key_from_path('a.gif').should.be.eql?('a')
107
+ end
108
+
109
+ it 'should cut only the last file extension' do
110
+ @analyzer.key_from_path('a.gif.gif').should.be.eql?('a.gif')
111
+ end
112
+
113
+ it 'should transform camel case to snake case' do
114
+ @analyzer.key_from_path('AbCdEf').should.be.eql?('ab_cd_ef')
115
+ end
116
+
117
+ it 'should filter certain words' do
118
+ @analyzer.key_from_path('my_icon_catImage').should.be.eql?('my_cat')
119
+ end
120
+
121
+ it 'should not contain unnecessary underscores' do
122
+ @analyzer.key_from_path('__a___b__c___').should.be.eql?('a_b_c')
123
+ end
124
+ end
125
+
126
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::ResourcesAnalyzer::BundleResourcesAnalyzer' do
4
+
5
+ def subject
6
+ XCRes::ResourcesAnalyzer::BundleResourcesAnalyzer
7
+ end
8
+
9
+ before do
10
+ @analyzer = subject.new
11
+ @analyzer.logger = stub('Logger', :log)
12
+ end
13
+
14
+ describe '#build_sections_for_bundles' do
15
+ it 'should return an empty array if the project does not contain any resource bundles' do
16
+ @analyzer.expects(:find_bundle_file_refs).returns([])
17
+ @analyzer.build_sections_for_bundles.should.eql?([])
18
+ end
19
+
20
+ it 'should build sections for given bundles' do
21
+ mock_bundle_a = mock('BundleFileRef').stubs(path: 'A.bundle', real_path: 'b/A.bundle')
22
+ mock_bundle_b = mock('BundleFileRef').stubs(path: 'B.bundle', real_path: 'b/B.bundle')
23
+ section = XCRes::Section.new('A', { 'a' => 'a.gif' })
24
+ @analyzer.expects(:find_bundle_file_refs).returns([mock_bundle_a, mock_bundle_b])
25
+ @analyzer.expects(:build_section_for_bundle).with(mock_bundle_a).returns(section)
26
+ @analyzer.expects(:build_section_for_bundle).with(mock_bundle_b).returns(nil)
27
+ @analyzer.build_sections_for_bundles.should.be.eql?([section])
28
+ end
29
+ end
30
+
31
+ describe '#find_bundle_file_refs' do
32
+ # TODO: Prepare a fixture project
33
+ end
34
+
35
+ describe '#build_section_for_bundle' do
36
+ before do
37
+ @mock_bundle = mock('Bundle') { stubs(path: 'A.bundle', real_path: 'b/A.bundle') }
38
+ end
39
+
40
+ it 'should return nil if the bundle does not contain any images' do
41
+ @analyzer.expects(:find_files_in_dir).with(@mock_bundle.real_path).returns([Pathname('a.m')])
42
+ @analyzer.build_section_for_bundle(@mock_bundle).should.be.nil?
43
+ end
44
+
45
+ it 'should return nil if the bundle does not contain any valid images' do
46
+ @analyzer.expects(:find_files_in_dir).with(@mock_bundle.real_path).returns([Pathname('a.gif')])
47
+ @analyzer.exclude_file_patterns = ['a.gif']
48
+ @analyzer.build_section_for_bundle(@mock_bundle).should.be.nil?
49
+ end
50
+
51
+ it 'should build a new section if the bundle contain valid images' do
52
+ @analyzer.expects(:find_files_in_dir).with(@mock_bundle.real_path).returns([Pathname('a.gif')])
53
+ @analyzer.build_section_for_bundle(@mock_bundle).should.be.eql?(XCRes::Section.new('A', 'a' => 'a.gif'))
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::ResourcesAnalyzer::LooseResourcesAnalyzer' do
4
+
5
+ def subject
6
+ XCRes::ResourcesAnalyzer::LooseResourcesAnalyzer
7
+ end
8
+
9
+ before do
10
+ @analyzer = subject.new
11
+ @analyzer.logger = stub('Logger', :log)
12
+ end
13
+
14
+ describe '#analyze' do
15
+ # TODO
16
+ end
17
+
18
+ describe '#build_section_for_loose_images' do
19
+ # TODO
20
+ end
21
+
22
+ end
@@ -0,0 +1,99 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'XCRes::StringsAnalyzer' do
4
+
5
+ def subject
6
+ XCRes::StringsAnalyzer
7
+ end
8
+
9
+ before do
10
+ @target = stub('Target', build_configurations: [])
11
+ @project = stub('Project', files: [], path: Pathname('.'))
12
+ @target.stubs(project: @project)
13
+
14
+ @analyzer = subject.new(@target)
15
+ @analyzer.logger = stub('Logger', :log)
16
+ end
17
+
18
+ describe "#initialize" do
19
+ it 'should set given target as attribute' do
20
+ @analyzer = subject.new(@target)
21
+ @analyzer.target.should.be.eql?(@target)
22
+ @analyzer.project.should.be.eql?(@project)
23
+ end
24
+
25
+ it 'should set option :default_language as attribute' do
26
+ @analyzer = subject.new(@target, default_language: 'en')
27
+ @analyzer.default_language.should.be.eql?('en')
28
+ end
29
+ end
30
+
31
+ describe "#analyze" do
32
+ it 'should return the built sections' do
33
+ section = mock()
34
+ @analyzer.expects(:build_section).returns(section)
35
+ @analyzer.analyze.should.be.eql?([section])
36
+ end
37
+ end
38
+
39
+ describe "#build_section" do
40
+ it 'should return an empty section if there are no strings files' do
41
+ @analyzer.stubs(:strings_file_refs).returns([])
42
+ @analyzer.build_section.should.be.eql?(XCRes::Section.new 'Strings', {})
43
+ end
44
+
45
+ it 'should return a new section if there are strings files' do
46
+ strings_file_ref = stub('FileRef', {
47
+ name: 'en',
48
+ path: 'Localizable.strings',
49
+ real_path: Pathname(File.expand_path('./en.lproj/Localizable.strings'))
50
+ })
51
+ @analyzer.stubs(:strings_file_refs).returns([strings_file_ref])
52
+ @analyzer.stubs(:keys_by_file)
53
+ .with(Pathname('en.lproj/Localizable.strings'))
54
+ .returns({ 'greeting' => { value: 'greeting' }})
55
+ @analyzer.build_section.should.be.eql?(XCRes::Section.new 'Strings', { 'greeting' => { value: 'greeting' }})
56
+ end
57
+ end
58
+
59
+ describe "#languages" do
60
+ it 'should return the default language if it is set' do
61
+ @analyzer.default_language = 'en'
62
+ @analyzer.languages.should.be.eql?(['en'])
63
+ end
64
+
65
+ it 'should return an empty array if there is no used language' do
66
+ @analyzer.expects(:native_dev_languages).returns(['en'].to_set).at_least_once
67
+ @analyzer.expects(:used_languages).returns([].to_set).at_least_once
68
+ @analyzer.languages.should.be.eql?([].to_set)
69
+ end
70
+
71
+ it 'should return the used languages if there is no matching native dev language' do
72
+ @analyzer.expects(:native_dev_languages).returns(['de'].to_set).at_least_once
73
+ @analyzer.expects(:used_languages).returns(['en', 'es'].to_set).at_least_once
74
+ @analyzer.languages.should.be.eql?(['en', 'es'].to_set)
75
+ end
76
+
77
+ it 'should return the intersection of languages if there is a common language' do
78
+ @analyzer.expects(:native_dev_languages).returns(['en'].to_set).at_least_once
79
+ @analyzer.expects(:used_languages).returns(['en', 'es'].to_set).at_least_once
80
+ @analyzer.languages.should.be.eql?(['en'].to_set)
81
+ end
82
+ end
83
+
84
+ describe "#find_strings_file_refs" do
85
+ before do
86
+ @target = app_target
87
+ @analyzer = subject.new(@target)
88
+ end
89
+
90
+ it 'should return the strings files of the fixture project' do
91
+ strings_files = @analyzer.find_file_refs_by_extname('.strings')
92
+ strings_files.count.should.be.eql?(3)
93
+ strings_files[0].path.should.be.eql?('en.lproj/InfoPlist.strings')
94
+ strings_files[1].path.should.be.eql?('en.lproj/Localizable.strings')
95
+ strings_files[2].path.should.be.eql?('de.lproj/Localizable.strings')
96
+ end
97
+ end
98
+
99
+ end