gbs-tests.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #!/usr/bin/env bash
  2. # gbs-tests.sh - test suite for git-branch-status
  3. #
  4. # Copyright 2020-2021,2023 bill-auger <bill-auger@programmer.net>
  5. #
  6. # git-branch-status is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License version 3
  8. # as published by the Free Software Foundation.
  9. #
  10. # git-branch-status is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License version 3
  16. # along with git-branch-status. If not, see <http://www.gnu.org/licenses/>.
  17. source ./gbs-tests-constants.sh.inc
  18. ## test data variables ##
  19. TempDir=''
  20. TestName=''
  21. Expected=''
  22. Actual=''
  23. ## logging ##
  24. STATE() { printf "\n=== ${CLIME}${1}${CEND} ===\n\n" ; true ; }
  25. LOG() { printf "${CBLUE}${1}${CEND}\n" ; true ; }
  26. PASS() { printf "${CGREEN}PASSED: ${1}${CEND}\n" ; true ; }
  27. FAIL() { printf "${CRED}FAILED: ${1}${CEND}\n"
  28. printf "${CRED}Expected:${CEND}\n${2}\n"
  29. printf "${CRED}Actual:${CEND}\n${3}\n" ; true ; }
  30. ## business ##
  31. Init()
  32. {
  33. [[ -z "${GBS_CMD}" ]] && ERR "constants file load failed - bailing" && return 1
  34. [[ ! -x "${GBS_CMD}" ]] && ERR "GBS_CMD is not executable - bailing" && return 1
  35. if TempDir="$(mktemp --directory -t $MKTEMP_TEMPLATE)"
  36. then STATE "initializing" ; LOG "created temp directory: ${TempDir}" ;
  37. else ERR "failed to create temp directory - bailing" ; return 1 ;
  38. fi
  39. export GBS_TEST_CFG=1
  40. export GBS_USE_ANSI_COLOR=0
  41. export GBS_FETCH_PERIOD=-1
  42. export GBS_SHOW_AUTHOR_DATES=1
  43. export GBS_CFG_FILE=${TempDir}/${TEST_CFG_FILE}
  44. if [[ -f $(git-branch-status | grep 'DEF_CFG_FILE=' | sed 's|[^:]*: ||') ]]
  45. then ERR "default config file must not exist - bailing" ; return 1 ;
  46. fi
  47. LOG "preparing test config file"
  48. echo "readonly CFG_FETCH_PERIOD=-42" > ${GBS_CFG_FILE}
  49. echo "readonly CFG_LAST_FETCH_FILE=${TempDir}/GBS_LAST_FETCH" >> ${GBS_CFG_FILE}
  50. echo "readonly CFG_USE_ANSI_COLOR=1" >> ${GBS_CFG_FILE}
  51. LOG "creating: '${UPSTREAM_NAME}'"
  52. cd ${TempDir} ; mkdir ${UPSTREAM_NAME} ; cd ${UPSTREAM_NAME} ;
  53. git init -b ${MASTER_BRANCH} > /dev/null
  54. touch ${TRACKED_FILE} ; git add ${TRACKED_FILE} ;
  55. echo 'some text' > ${TRACKED_FILE}
  56. git commit -m 'upstream-initial' --date 2000-01-01 ${TRACKED_FILE} > /dev/null
  57. LOG "preparing branches for: '${UPSTREAM_NAME}'"
  58. git checkout -b ${COMMON_BRANCH} 2> /dev/null
  59. echo 'diff text' > ${TRACKED_FILE}
  60. git commit -m 'upstream-change' --date 2000-01-02 ${TRACKED_FILE} > /dev/null
  61. git checkout ${MASTER_BRANCH} 2> /dev/null
  62. LOG "cloning: '${UPSTREAM_NAME}' as: '${PEER_NAME}'"
  63. cd ${TempDir}
  64. git clone --origin ${UPSTREAM_NAME} ${UPSTREAM_NAME} ${PEER_NAME} 2> /dev/null
  65. cd ${PEER_NAME}
  66. LOG "preparing branches for: '${PEER_NAME}'"
  67. git checkout -b ${PEER_RENAMED_BRANCH} ${UPSTREAM_NAME}/${COMMON_BRANCH} &> /dev/null
  68. git checkout -b ${WIP_BRANCH} ${PEER_RENAMED_BRANCH} 2> /dev/null
  69. echo 'more text' >> ${TRACKED_FILE}
  70. git commit -m 'peer-change' --date 2000-01-03 ${TRACKED_FILE} > /dev/null
  71. LOG "cloning: '${UPSTREAM_NAME}' as: '${LOCAL_NAME}'"
  72. cd ${TempDir}
  73. git clone --origin ${UPSTREAM_NAME} ${UPSTREAM_NAME} ${LOCAL_NAME} 2> /dev/null
  74. cd ${LOCAL_NAME}
  75. LOG "adding remote: '${PEER_NAME}' to: '${LOCAL_NAME}'"
  76. git remote add ${PEER_NAME} ../${PEER_NAME}
  77. git fetch ${PEER_NAME} 2> /dev/null
  78. LOG "preparing branches for: '${LOCAL_NAME}'"
  79. git checkout -b ${COMMON_BRANCH} ${UPSTREAM_NAME}/${COMMON_BRANCH} &> /dev/null
  80. echo 'more text' >> ${TRACKED_FILE}
  81. git commit -m 'local-change' --date 2000-01-04 ${TRACKED_FILE} > /dev/null
  82. git checkout -b ${WIP_BRANCH} ${COMMON_BRANCH} 2> /dev/null
  83. echo 'more text' >> ${TRACKED_FILE}
  84. git commit -m 'local-change' --date 2000-01-05 ${TRACKED_FILE} > /dev/null
  85. git checkout ${COMMON_BRANCH} &> /dev/null
  86. }
  87. AssertEqual()
  88. {
  89. if diff <(printf "%s" "${Expected}") <(printf "%s" "${Actual}") &> /dev/null
  90. then PASS "${TestName}"
  91. else FAIL "${TestName}" "${Expected}" "${Actual}"
  92. exit 1
  93. fi
  94. }
  95. TestConfig()
  96. {
  97. STATE "running config tests"
  98. export GBS_TEST_CFG=1
  99. TestName="config file location via env"
  100. Expected="$(printf "%s" "${CFG_FILE_LOC_ENV_TEXT} ${TempDir}/${TEST_CFG_FILE}")"
  101. Actual=$(git-branch-status | grep 'GBS_CFG_FILE=')
  102. AssertEqual
  103. TestName="config file location default"
  104. Expected="$(printf "%s" "${CFG_FILE_LOC_DEF_TEXT}")"
  105. Actual=$(GBS_CFG_FILE= git-branch-status | grep 'GBS_CFG_FILE=')
  106. AssertEqual
  107. TestName="fetch period via env"
  108. Expected="$(printf "%s" "${FETCH_PERIOD_ENV_TEXT}")"
  109. Actual=$(GBS_FETCH_PERIOD=42 git-branch-status | grep 'FETCH_PERIOD=')
  110. AssertEqual
  111. TestName="fetch period via config"
  112. Expected="$(printf "%s" "${FETCH_PERIOD_CFG_TEXT}")"
  113. Actual=$(GBS_FETCH_PERIOD= git-branch-status | grep 'FETCH_PERIOD=')
  114. AssertEqual
  115. mv ${GBS_CFG_FILE} ${GBS_CFG_FILE}-bak
  116. TestName="fetch period default"
  117. Expected="$(printf "%s" "${FETCH_PERIOD_DEF_TEXT}")"
  118. Actual=$(GBS_FETCH_PERIOD= git-branch-status | grep 'FETCH_PERIOD=')
  119. AssertEqual
  120. mv ${GBS_CFG_FILE}-bak ${GBS_CFG_FILE}
  121. TestName="last fetch file via env"
  122. Expected="$(printf "%s" "${LAST_FETCH_ENV_TEXT}" | sed "s|__TMP_DIR__|${TempDir}|")"
  123. Actual=$(GBS_LAST_FETCH_FILE=DUMMY git-branch-status | grep 'LAST_FETCH_FILE=')
  124. AssertEqual
  125. TestName="last fetch file via config"
  126. Expected="$(printf "%s" "${LAST_FETCH_CFG_TEXT}" | sed "s|__TMP_DIR__|${TempDir}|")"
  127. Actual=$(GBS_LAST_FETCH_FILE= git-branch-status | grep 'LAST_FETCH_FILE=')
  128. AssertEqual
  129. mv ${GBS_CFG_FILE} ${GBS_CFG_FILE}-bak
  130. TestName="last fetch file default"
  131. Expected="$(printf "%s" "${LAST_FETCH_DEF_TEXT}" | sed "s|__HOME_DIR__|${HOME}|")"
  132. Actual=$(GBS_LAST_FETCH_FILE= git-branch-status | grep 'LAST_FETCH_FILE=')
  133. AssertEqual
  134. mv ${GBS_CFG_FILE}-bak ${GBS_CFG_FILE}
  135. TestName="ansi color via env"
  136. Expected="$(printf "%s" "${ANSI_COLOR_ENV_TEXT}")"
  137. Actual=$(GBS_USE_ANSI_COLOR=0 git-branch-status | grep 'USE_ANSI_COLOR=')
  138. AssertEqual
  139. TestName="ansi color via config"
  140. Expected="$(printf "%s" "${ANSI_COLOR_CFG_TEXT}")"
  141. Actual=$(GBS_USE_ANSI_COLOR= git-branch-status | grep 'USE_ANSI_COLOR=')
  142. AssertEqual
  143. mv ${GBS_CFG_FILE} ${GBS_CFG_FILE}-bak
  144. TestName="ansi color default"
  145. Expected="$(printf "%s" "${ANSI_COLOR_DEF_TEXT}")"
  146. Actual=$(GBS_USE_ANSI_COLOR= git-branch-status | grep 'USE_ANSI_COLOR=')
  147. AssertEqual
  148. mv ${GBS_CFG_FILE}-bak ${GBS_CFG_FILE}
  149. }
  150. TestOptions()
  151. {
  152. STATE "running options tests"
  153. export GBS_TEST_CFG=0
  154. (git checkout ${COMMON_BRANCH} ; git reset --hard ${UPSTREAM_NAME}/${COMMON_BRANCH}) &> /dev/null
  155. TestName="default in-sync"
  156. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${TRACKED_ALL_INSYNC_TEXT}")"
  157. Actual=$(git-branch-status)
  158. AssertEqual
  159. (git rm ${TRACKED_FILE} ; git commit -m 'rm' --date 2000-01-06 ;) > /dev/null
  160. TestName="default out-of-sync"
  161. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${OUTOFSYNCH_TEXT}")"
  162. Actual=$(git-branch-status)
  163. AssertEqual
  164. TestName="arbitrary branch"
  165. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${TRACKED_INSYNC_TEXT}")"
  166. Actual=$(git-branch-status ${MASTER_BRANCH})
  167. AssertEqual
  168. TestName="arbitrary branches local<->local"
  169. Expected="$(printf "\n%s%s" "${LOCALDEV_LOCALWIP_TEXT}" "${ARBITRARYBRANCHES_LOCALDEV_LOCALWIP_TEXT}")"
  170. Actual=$(git-branch-status ${COMMON_BRANCH} ${WIP_BRANCH})
  171. AssertEqual
  172. TestName="arbitrary branches local<->remote"
  173. Expected="$(printf "\n%s%s" "${LOCALDEV_PEERDEV_TEXT}" "${ARBITRARYBRANCHES_LOCALDEV_PEERDEV_TEXT}")"
  174. Actual=$(git-branch-status ${COMMON_BRANCH} ${PEER_NAME}/${PEER_RENAMED_BRANCH})
  175. AssertEqual
  176. TestName="arbitrary branches remote<->local"
  177. Expected="$(printf "\n%s%s" "${PEERWIP_LOCALWIP_TEXT}" "${ARBITRARYBRANCHES_PEERWIP_LOCALWIP_TEXT}")"
  178. Actual=$(git-branch-status ${PEER_NAME}/${WIP_BRANCH} ${WIP_BRANCH})
  179. AssertEqual
  180. TestName="arbitrary branches remote<->remote"
  181. Expected="$(printf "\n%s%s" "${UPSTRMASTER_PEERMASTER_TEXT}" "${UNTRACKED_INSYNC_TEXT}")"
  182. Actual=$(git-branch-status ${UPSTREAM_NAME}/${MASTER_BRANCH} ${PEER_NAME}/${MASTER_BRANCH})
  183. AssertEqual
  184. TestName="all branches"
  185. Expected="$(printf "\n%s%s\n%s%s\n%s%s" \
  186. "${LOCAL_TRACKING_TEXT}" "${LOCALS_TEXT}" \
  187. "${LOCAL_COLLAB_TEXT}" "${REMOTES_COLLAB_TEXT}" \
  188. "${LOCAL_UPSTREAM_TEXT}" "${REMOTES_ORIGIN_TEXT}" )"
  189. Actual=$(git-branch-status --all)
  190. AssertEqual
  191. TestName="current branch"
  192. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${CURRENTBRANCH_TEXT}")"
  193. Actual=$(git-branch-status --branch)
  194. AssertEqual
  195. TestName="specific branch"
  196. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${SPECIFICBRANCH_TEXT}")"
  197. Actual=$(git-branch-status --branch ${WIP_BRANCH})
  198. AssertEqual
  199. git branch merged-into-master ${MASTER_BRANCH} 2> /dev/null
  200. TestName="cleanup insufficient args"
  201. Expected="$(printf "%s" "${ARG_REQUIRED_TEXT}")"
  202. Actual=$(git-branch-status --cleanup)
  203. AssertEqual
  204. TestName="cleanup"
  205. Expected="$(printf "\n%s%s" "${LOCALS_CLEANUP_TEXT}" "${CLEANUP_TEXT}")"
  206. Actual=$(yes | git-branch-status --cleanup ${MASTER_BRANCH})
  207. AssertEqual
  208. TestName="cleanup deleted branch"
  209. Expected=""
  210. Actual=$(git branch -a | grep -E "^.* merged-into-master$")
  211. AssertEqual
  212. TestName="dates"
  213. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${OUTOFSYNCH_DATES_TEXT}")"
  214. Actual=$(git-branch-status --dates)
  215. AssertEqual
  216. TestName="help"
  217. Expected="$(printf "%s" "${HELP_TEXT}")"
  218. Actual=$(git-branch-status --help)
  219. AssertEqual
  220. TestName="local"
  221. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${LOCALS_TEXT}")"
  222. Actual=$(git-branch-status --local)
  223. AssertEqual
  224. TestName="remotes out-of-sync"
  225. Expected="$(printf "\n%s%s\n%s%s" \
  226. "${LOCAL_COLLAB_TEXT}" "${REMOTES_COLLAB_TEXT}" \
  227. "${LOCAL_UPSTREAM_TEXT}" "${REMOTES_ORIGIN_TEXT}" )"
  228. Actual=$(git-branch-status --remotes)
  229. AssertEqual
  230. (git checkout ${WIP_BRANCH} ; git reset --hard ${PEER_NAME}/${WIP_BRANCH} ;) &> /dev/null
  231. (git checkout ${COMMON_BRANCH} ; ) &> /dev/null
  232. TestName="remotes in-sync"
  233. Expected="$(printf "\n%s%s%s\n%s%s" \
  234. "${LOCAL_COLLAB_TEXT}" "${REMOTES_COLLAB_INSYNC_TEXT}" "${REMOTES_INSYNC_TEXT}" \
  235. "${LOCAL_UPSTREAM_TEXT}" "${REMOTES_ORIGIN_TEXT}" )"
  236. Actual=$(git-branch-status --remotes)
  237. AssertEqual
  238. TestName="verbose"
  239. Expected="$(printf "\n%s%s\n%s%s%s\n%s%s" \
  240. "${LOCAL_TRACKING_TEXT}" "${LOCALS_DATES_TEXT}" \
  241. "${LOCAL_COLLAB_TEXT}" "${REMOTES_COLLAB_DATES_TEXT}" "${REMOTES_INSYNC_TEXT}" \
  242. "${LOCAL_UPSTREAM_TEXT}" "${REMOTES_ORIGIN_DATES_TEXT}" )"
  243. Actual=$(git-branch-status --verbose)
  244. AssertEqual
  245. }
  246. TestPresentation()
  247. {
  248. STATE "running presentation tests"
  249. export GBS_TEST_CFG=0
  250. TestName="tracked"
  251. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${CURRENTBRANCH_TEXT}")"
  252. Actual=$(git-branch-status ${COMMON_BRANCH})
  253. AssertEqual
  254. TestName="untracked"
  255. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${SPECIFICBRANCH_TEXT}")"
  256. Actual=$(git-branch-status ${WIP_BRANCH})
  257. AssertEqual
  258. local commit_n
  259. (git checkout ${COMMON_BRANCH} ; git reset --hard ${UPSTREAM_NAME}/${COMMON_BRANCH}) &> /dev/null
  260. for (( commit_n = 0 ; commit_n <= 999 ; ++commit_n )) # MAX_DIVERGENCE
  261. do echo 'text' >> ${TRACKED_FILE} ; git commit -m 'a-change' ${TRACKED_FILE} > /dev/null
  262. done
  263. TestName="n_commits over the cap"
  264. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${NCOMMITS_OVERCAP_TEXT}")"
  265. Actual=$(git-branch-status)
  266. AssertEqual
  267. git reset --hard HEAD^ > /dev/null
  268. TestName="n_commits under the cap"
  269. Expected="$(printf "\n%s%s" "${LOCAL_TRACKING_TEXT}" "${NCOMMITS_UNDERCAP_TEXT}")"
  270. Actual=$(git-branch-status)
  271. AssertEqual
  272. }
  273. RunTests()
  274. {
  275. TestConfig && \
  276. TestOptions && \
  277. TestPresentation && \
  278. STATE "(: all tests passed :)"
  279. }
  280. Cleanup()
  281. {
  282. STATE "cleaning up"
  283. rm -rf $TempDir 2> /dev/null
  284. }
  285. main()
  286. {
  287. local result
  288. Init && RunTests ; result=$? ;
  289. Cleanup
  290. exit ${result}
  291. }
  292. ## main entry ##
  293. main