do the octopus by chunk of n branches.
8 | -e exclude branches matching the pattern.
9 | -v prints the version of git-octopus
10 | EOF
11 | exit
12 | }
13 |
14 | removeAllFrom() {
15 | from=$1
16 | remove=$2
17 | for i in $remove; do
18 | from=${from/$i/}
19 | done
20 | echo "$from"
21 | }
22 |
23 | line_break() {
24 | echo "-----------------------------------------------------------"
25 | }
26 |
27 | # Save the current state of the repository in $triggeredBranch
28 | triggeredBranch=$(git symbolic-ref --short HEAD 2> /dev/null) ||
29 | triggeredBranch=$(git rev-parse HEAD)
30 | # We save the current HEAD in case of an octopus by chunk
31 | triggeredSha1=$(git rev-parse --verify HEAD)
32 |
33 |
34 | signalHandler() {
35 | echo
36 | line_break
37 | echo "Stoping..."
38 | echo "HEAD -> $triggeredBranch"
39 | git reset -q --hard $triggeredSha1
40 | git checkout -q $triggeredBranch
41 | git clean -d -f
42 | exit 1
43 | }
44 |
45 | doCommit=$(git config octopus.commit)
46 | splitByChunk=false
47 | while getopts "nhvcs:e:" opt; do
48 | case "$opt" in
49 | h)
50 | usage
51 | ;;
52 | n)
53 | doCommit=false
54 | ;;
55 | c)
56 | doCommit=true
57 | ;;
58 | v)
59 | echo "1.4"
60 | exit 0
61 | ;;
62 | s)
63 | [[ $OPTARG =~ ^-?[0-9]+$ ]] || die "-s argument must be a postive number"
64 | splitByChunk=true
65 | chunkSize=$OPTARG
66 | ;;
67 | e)
68 | exclude+=" $OPTARG"
69 | ;;
70 | \?)
71 | exit 1
72 | ;;
73 | esac
74 | done
75 |
76 | [[ -z $(git status --porcelain) ]] || die "The repository has to be clean"
77 |
78 | trap signalHandler SIGINT SIGQUIT
79 |
80 | #Shift all options in order to iterate over refspec-patterns
81 | shift $(expr $OPTIND - 1)
82 |
83 | #Retrive patterns written in the conf
84 | patterns=$(git config --get-all octopus.pattern)
85 | excludePatterns=$(git config --get-all octopus.excludePattern)
86 |
87 | #Overriding the conf with the patterns given as parameters
88 | if [[ -n "$@" ]] ; then
89 | patterns=$@
90 | fi
91 | if [[ -n "$exclude" ]]; then
92 | excludePatterns=${exclude:1}
93 | fi
94 |
95 | #Exit code 0 if nothing to merge
96 | if [[ -z "$patterns" ]] ; then
97 | exit 0
98 | fi
99 |
100 | branches=$(git ls-remote . $patterns | cut -d $'\t' -f 2)
101 | #Get nothing if excludePatterns is empty
102 | [[ -n "$excludePatterns" ]] && excludedBranches=$(git ls-remote . $excludePatterns | cut -d $'\t' -f 2)
103 | branches=$(removeAllFrom "$branches" "$excludedBranches")
104 |
105 | [[ -z "$excludedBranches" ]] || echo "Excluding branches :"
106 | for branch in $excludedBranches ; do
107 | echo $'\t'$branch
108 | done
109 |
110 | if [ -z "$branches" ]; then
111 | echo "No branch matching $patterns were found"
112 | exit 0
113 | fi
114 |
115 | echo "Branches beeing merged :"
116 | for branch in $branches ; do
117 | echo $'\t'$branch
118 | done
119 |
120 | line_break
121 |
122 | mergeBases= sha1s= octopusMessage= i=0
123 | for branch in $branches
124 | do
125 | sha1=$(git rev-parse --verify "$branch")
126 | sha1s[$i]="$sha1"
127 | eval GITHEAD_$sha1='"$branch"'
128 | export GITHEAD_$sha1
129 |
130 | # merges bases are not used in the octopus stategy so we don't need to compute them
131 | # mergeBases="$mergeBases`git merge-base --all HEAD $branch` "
132 |
133 | octopusMessage[$i]="$branch"
134 | ((i++))
135 | done
136 | $splitByChunk || chunkSize=${#sha1s[@]}
137 |
138 | $splitByChunk && echo "Will merge ${#sha1s[@]} branches by chunks of $chunkSize"
139 | for ((i=0; $i < ${#sha1s[@]}; i+=$chunkSize))
140 | do
141 | if $splitByChunk; then
142 | upperChunk=$(($i + $chunkSize))
143 | [ $upperChunk -gt ${#sha1s[@]} ] && upperChunk=${#sha1s[@]}
144 | echo "Merging chunks $i to $upperChunk (out of ${#sha1s[@]})"
145 | fi
146 | sha1sChunk=" ${sha1s[@]:$i:$chunkSize}"
147 |
148 | alreadyUpToDate=true
149 | for sha1 in ${sha1sChunk[@]}
150 | do
151 | git merge-base --is-ancestor $sha1 HEAD || alreadyUpToDate=false
152 | done
153 |
154 | # This prevents git-octopus to create a commit when there's nothing to merge,
155 | # i.e. no feature branches but only master.
156 | $alreadyUpToDate && octopusStatus=0 && echo "Already up to date" && continue
157 |
158 | merge-octopus-fork "$mergeBases" -- HEAD $sha1sChunk
159 | octopusStatus=$?
160 | if [ $octopusStatus -eq 0 ]
161 | then
162 | if [[ $doCommit || $splitByChunk ]]; then
163 | tree=$(git write-tree)
164 | head=$(git rev-parse --verify HEAD)
165 | octopusMessageChunk="${octopusMessage[@]:$i:$chunkSize} "
166 | commit=$(git commit-tree -p $head ${sha1sChunk// / -p } -m "${octopusMessageChunk// /$LF}" $tree)
167 | git update-ref HEAD $commit
168 | $splitByChunk && echo "Chunk success"
169 | fi
170 | else
171 | $splitByChunk && echo "Chunk failed"
172 | break
173 | fi
174 | done
175 |
176 | if [ $octopusStatus -eq 0 ]
177 | then
178 | if ! $doCommit; then
179 | git reset -q --hard $triggeredSha1
180 | fi
181 | line_break
182 | echo "OCTOPUS SUCCESS"
183 | else
184 | # Octopus merge failed, starting to run the analysis sequence ...
185 | line_break
186 |
187 | git reset -q --hard $triggeredSha1
188 |
189 | echo "Testing merges one by one with $triggeredBranch..."
190 | echo
191 |
192 | tmpFile=
193 |
194 | # Will perform a simple merge from the current branch with each branches one by one.
195 | for branch in $branches
196 | do
197 | if [[ $(git rev-parse $branch) != $(git rev-parse $triggeredBranch) ]]
198 | then
199 | echo -n "merging $branch ... "
200 |
201 | # merge base is not used in the octopus strategy
202 | # mergeBase=$(git merge-base --all HEAD $branch)
203 | mergeBase=
204 |
205 | sha1=$(git rev-parse --verify "$branch")
206 |
207 | tmpFile=$(merge-octopus-fork "$mergeBase" -- HEAD $sha1 2>&1)
208 |
209 | if [ $? -eq 0 ]
210 | then
211 | echo "SUCCESS"
212 | else
213 | echo "FAILED"
214 | echo "$tmpFile"
215 | git diff
216 | conflicts+="$branch "
217 | fi
218 | git reset -q --hard
219 | fi
220 | done
221 |
222 | line_break
223 |
224 | if [ -z "$conflicts" ]; then
225 | echo "No conflicts found between $triggeredBranch and the rest of the branches"
226 | else
227 | echo "$triggeredBranch has conflicts with :"
228 | for branch in $conflicts
229 | do
230 | echo $'\t'$branch
231 | done
232 | fi
233 |
234 | echo "OCTOPUS FAILED"
235 | exit 1
236 | fi
237 |
--------------------------------------------------------------------------------
/src/lib/common:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | LF='
3 | '
4 | die () {
5 | echo >&2 "$*"
6 | exit 1
7 | }
8 |
--------------------------------------------------------------------------------
/src/lib/git-merge-octopus-fork.sh:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2005 Junio C Hamano
2 | #
3 | # Resolve two or more trees.
4 | #
5 |
6 | merge-octopus-fork () {
7 | # The first parameters up to -- are merge bases; the rest are heads.
8 | bases= head= remotes= sep_seen=
9 | for arg
10 | do
11 | case ",$sep_seen,$head,$arg," in
12 | *,--,)
13 | sep_seen=yes
14 | ;;
15 | ,yes,,*)
16 | head=$arg
17 | ;;
18 | ,yes,*)
19 | remotes="$remotes$arg "
20 | ;;
21 | *)
22 | bases="$bases$arg "
23 | ;;
24 | esac
25 | done
26 |
27 | # MRC is the current "merge reference commit"
28 | # MRT is the current "merge result tree"
29 |
30 | MRC=$(git rev-parse --verify -q $head)
31 | MRT=$(git write-tree)
32 | NON_FF_MERGE=0
33 | OCTOPUS_FAILURE=0
34 | for SHA1 in $remotes
35 | do
36 | case "$OCTOPUS_FAILURE" in
37 | 1)
38 | # We allow only last one to have a hand-resolvable
39 | # conflicts. Last round failed and we still had
40 | # a head to merge.
41 | echo "Automated merge did not work."
42 | echo "Should not be doing an Octopus."
43 | return 2
44 | esac
45 |
46 | eval pretty_name=\${GITHEAD_$SHA1:-$SHA1}
47 | if test "$SHA1" = "$pretty_name"
48 | then
49 | SHA1_UP="$(echo "$SHA1" | tr a-z A-Z)"
50 | eval pretty_name=\${GITHEAD_$SHA1_UP:-$pretty_name}
51 | fi
52 | common=$(git merge-base --all $SHA1 $MRC) ||
53 | die "Unable to find common commit with $pretty_name"
54 |
55 | case "$LF$common$LF" in
56 | *"$LF$SHA1$LF"*)
57 | echo "Already up-to-date with $pretty_name"
58 | continue
59 | ;;
60 | esac
61 |
62 | if test "$common,$NON_FF_MERGE" = "$MRC,0"
63 | then
64 | # The first head being merged was a fast-forward.
65 | # Advance MRC to the head being merged, and use that
66 | # tree as the intermediate result of the merge.
67 | # We still need to count this as part of the parent set.
68 |
69 | echo "Fast-forwarding to: $pretty_name"
70 | git read-tree -u -m $head $SHA1 || return 0
71 | MRC=$SHA1 MRT=$(git write-tree)
72 | continue
73 | fi
74 |
75 | NON_FF_MERGE=1
76 |
77 | echo "Trying simple merge with $pretty_name"
78 | git read-tree -u -m --aggressive $common $MRT $SHA1 || return 2
79 | next=$(git write-tree 2>/dev/null)
80 | if test $? -ne 0
81 | then
82 | echo "Simple merge did not work, trying automatic merge."
83 | git-merge-index -o git-merge-one-file -a
84 |
85 | if test $? -ne 0
86 | then
87 | git apply-conflict-resolution || OCTOPUS_FAILURE=1
88 | fi
89 |
90 | next=$(git write-tree 2>/dev/null)
91 | fi
92 |
93 | MRC="$MRC $SHA1"
94 | MRT=$next
95 | done
96 |
97 | return "$OCTOPUS_FAILURE"
98 | }
99 |
--------------------------------------------------------------------------------
/src/lib/hash-conflict:
--------------------------------------------------------------------------------
1 | cat-UU-conflict() {
2 | leftContent=
3 | rightContent=
4 | reading="base"
5 |
6 | while read l ; do
7 | [[ $l == \<\<\<\<\<\<\<* ]] && reading="left" && continue
8 | [[ $l == \=\=\=\=\=\=\=* ]] && reading="right" && continue
9 | [[ $l == \>\>\>\>\>\>\>* ]] && reading="base" && continue
10 |
11 | case $reading in
12 | "base")
13 | ;;
14 | "left")
15 | leftContent+="$l$LF"
16 | ;;
17 | "right")
18 | rightContent+="$l$LF"
19 | ;;
20 | esac
21 | done < "$1"
22 |
23 | conflictContent=
24 | if ! $ordered && [ "$leftContent" \< "$rightContent" ] ; then
25 | conflictContent="$leftContent$LF$rightContent"
26 | else
27 | conflictContent="$rightContent$LF$leftContent"
28 | fi
29 |
30 | echo "$conflictContent"
31 | }
32 |
33 | hash-conflict () {
34 | # -o Make the order between left and right side matters.
35 | # -i Read instead of conflicting paths in the index
36 | ordered=false
37 | file=
38 | while getopts "oi:h" opt; do
39 | case "$opt" in
40 | h)
41 | usage
42 | return 0
43 | ;;
44 | o)
45 | ordered=true
46 | ;;
47 | i)
48 | file=$OPTARG
49 | ;;
50 | *)
51 | usage
52 | return 1
53 | ;;
54 | esac
55 | done
56 |
57 | conflictContent=
58 |
59 | while read status ; do
60 | state=$(echo $status | awk '{print $1;}')
61 | path=$(echo $status | awk '{print $2;}')
62 | case $state in
63 | "UU")
64 | conflictContent+="$(cat-UU-conflict $path)$LF"
65 | ;;
66 | esac
67 | done <<< "$(if [ -z "$file" ] ; then echo "$(git status --porcelain | grep "^U.\|^.U\|^AA\|^DD" | awk -v cdup="$(git rev-parse --show-cdup)" '{print $1" "cdup$2;}')" ; else echo "UU $file" ; fi)"
68 |
69 | echo "$conflictContent" | shasum | cut -f 1 -d " "
70 | }
71 |
--------------------------------------------------------------------------------
/test/empty_command_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/empty_command_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | #saving the initial state of the repository
7 | sha1=`git rev-parse HEAD`
8 |
9 | git octopus
10 |
11 | if [ $? -ne 0 ] ; then
12 | exit 1
13 | fi
14 |
15 | if [[ `git rev-parse HEAD` != $sha1 ]] ; then
16 | echo "should stayed at HEAD"
17 | exit 1
18 | fi
19 |
20 | if [[ -n `git diff-index HEAD` ]] ; then
21 | echo "repository should be clean"
22 | exit 1
23 | fi
24 |
25 | if [[ `git symbolic-ref HEAD` != "refs/heads/master" ]] ; then
26 | echo "Should be still on master"
27 | exit 1
28 | fi
--------------------------------------------------------------------------------
/test/exclude_pattern_config_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/exclude_pattern_config_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | git checkout features/feat1
7 | git config octopus.pattern features/*
8 | git config --add octopus.pattern master
9 |
10 | git config octopus.excludePattern "features/feat3"
11 |
12 | git octopus
13 | merged=`git branch --merged`
14 | if [[ $merged != *feat1* ]] ; then
15 | exit 1
16 | fi
17 | if [[ $merged != *feat2* ]] ; then
18 | exit 1
19 | fi
20 | if [[ $merged == *feat3* ]] ; then
21 | exit 1
22 | fi
23 | if [[ $merged != *master* ]] ; then
24 | exit 1
25 | fi
26 |
--------------------------------------------------------------------------------
/test/no_commit_config_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/no_commit_config_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | git config octopus.commit false
7 | #saving the initial state of the repository
8 | sha1=`git rev-parse HEAD`
9 |
10 | git octopus features/*
11 |
12 | #should be back to HEAD
13 | if [[ `git rev-parse HEAD` != $sha1 ]] ; then
14 | exit 1
15 | fi
16 |
17 | #repository should be clean
18 | if [[ -n `git diff-index HEAD` ]] ; then
19 | exit 1
20 | fi
21 |
22 | #should be still on master
23 | if [[ `git symbolic-ref HEAD` != "refs/heads/master" ]] ; then
24 | echo "Should be still on master"
25 | exit 1
26 | fi
--------------------------------------------------------------------------------
/test/no_commit_detached_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/no_commit_detached_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | git status &> /dev/null
3 |
4 | git checkout --detach
5 |
6 | sha1=`git rev-parse HEAD`
7 |
8 | git octopus -n features/*
9 |
10 | #should be back to HEAD
11 | if [[ `git rev-parse HEAD` != $sha1 ]] ; then
12 | exit 1
13 | fi
14 |
15 | #repository should be clean
16 | if [[ -n `git diff-index HEAD` ]] ; then
17 | exit 1
18 | fi
19 |
20 | #should be still detached
21 | git symbolic-ref HEAD &> /dev/null
22 |
23 | if [ $? -eq 0 ] ; then
24 | echo "Repository should remains detached"
25 | exit 1
26 | fi
--------------------------------------------------------------------------------
/test/no_commit_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/no_commit_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | #saving the initial state of the repository
7 | sha1=`git rev-parse HEAD`
8 |
9 | git octopus -n features/*
10 |
11 | #should be back to HEAD
12 | if [[ `git rev-parse HEAD` != $sha1 ]] ; then
13 | exit 1
14 | fi
15 |
16 | #repository should be clean
17 | if [[ -n `git diff-index HEAD` ]] ; then
18 | exit 1
19 | fi
20 |
21 | #should be still on master
22 | if [[ `git symbolic-ref HEAD` != "refs/heads/master" ]] ; then
23 | echo "Should be still on master"
24 | exit 1
25 | fi
--------------------------------------------------------------------------------
/test/octopus_failed_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:merge_failure_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
--------------------------------------------------------------------------------
/test/octopus_failed_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | sha1=`git rev-parse HEAD`
7 |
8 | git octopus -n features/*
9 |
10 | if [ $? -ne 1 ] ; then
11 | exit 1
12 | fi
13 |
14 | #should be back to HEAD
15 | if [[ `git rev-parse HEAD` != $sha1 ]] ; then
16 | exit 1
17 | fi
18 |
19 | #repository should be clean
20 | if [[ -n `git diff-index HEAD` ]] ; then
21 | exit 1
22 | fi
--------------------------------------------------------------------------------
/test/pattern_config_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/pattern_config_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | git checkout features/feat1
7 | git config octopus.pattern features/*
8 | git config --add octopus.pattern master
9 |
10 | git octopus
11 | merged=`git branch --merged`
12 | if [[ $merged != *feat1* ]] ; then
13 | exit 1
14 | fi
15 | if [[ $merged != *feat2* ]] ; then
16 | exit 1
17 | fi
18 | if [[ $merged != *feat3* ]] ; then
19 | exit 1
20 | fi
21 | if [[ $merged != *master* ]] ; then
22 | exit 1
23 | fi
--------------------------------------------------------------------------------
/test/record_conflicts_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:merge_failure_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
--------------------------------------------------------------------------------
/test/record_conflicts_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | mergeBase=$(git merge-base --all HEAD features/feat1)
7 | git read-tree -um --aggressive $mergeBase HEAD features/feat1
8 | git merge-index -o -q git-merge-one-file -a
9 |
10 | git store-conflict
--------------------------------------------------------------------------------
/test/run_all.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | testDir=`dirname $0`
3 | tests=`ls -1d $testDir/*_test`
4 | for test in $tests; do
5 | $testDir/run_test.sh "$test"
6 | echo "==========================================================="
7 | done
--------------------------------------------------------------------------------
/test/run_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | bold="\\033[1m"
3 | green="\\033[1;32m"
4 | red="\\033[1;31m"
5 | normal="\\033[0m"
6 |
7 | testDir=`dirname $0`
8 | dockerImage=`basename $1`
9 |
10 | echo -e "Executing test ${bold}${dockerImage}${normal}..."
11 |
12 | #Copy bin sources into the docker build context.
13 | #see https://docs.docker.com/reference/builder/#add
14 | cp -Rf $testDir/../bin $1
15 |
16 | #Build a docker image for the test
17 | docker build -t $dockerImage $1 &> /dev/null
18 | echo
19 |
20 | #Run the test within a container
21 | docker run --cidfile="cid" -i $dockerImage
22 | cid=`cat cid`
23 | #Exit code of the container represent the test result
24 | exit=`docker wait "$cid"`
25 |
26 | #Cleanup cid file, docker container and docker image
27 | rm cid
28 | docker rm "$cid" 1> /dev/null
29 | docker rmi -f $dockerImage 1> /dev/null
30 |
31 | echo
32 |
33 | #Print test result
34 | if [ $exit == 0 ]
35 | then
36 | echo -e "${green}$dockerImage SUCCESS${normal}"
37 | else
38 | echo -e "${red}$dockerImage FAILED${normal}"
39 | exit 1
40 | fi
41 |
42 |
--------------------------------------------------------------------------------
/test/simple_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/simple_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | git octopus features/*
7 | merged=`git branch --merged`
8 | if [[ $merged != *feat1* ]] ; then
9 | exit 1
10 | fi
11 | if [[ $merged != *feat2* ]] ; then
12 | exit 1
13 | fi
14 | if [[ $merged != *feat3* ]] ; then
15 | exit 1
16 | fi
17 | if [[ $merged != *master* ]] ; then
18 | exit 1
19 | fi
--------------------------------------------------------------------------------
/test/single_parent_merge_test/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM lesfurets/octopus-tests:simple_merge_latest
2 | ADD test.sh /home/
3 | ADD bin /usr/local/bin
4 | RUN chmod +x /home/test.sh
5 | WORKDIR /home/octopus-tests/
6 | CMD /home/test.sh
7 |
--------------------------------------------------------------------------------
/test/single_parent_merge_test/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #FIXME
4 | git status &> /dev/null
5 |
6 | git branch -D features/feat2 features/feat3
7 | git branch features/feat0
8 |
9 | git octopus features/*
10 | merged=`git branch --merged`
11 | if [[ $merged != *feat0* ]] ; then
12 | exit 1
13 | fi
14 | if [[ $merged != *feat1* ]] ; then
15 | exit 1
16 | fi
17 | if [[ $merged != *master* ]] ; then
18 | exit 1
19 | fi
20 |
--------------------------------------------------------------------------------
/test/test_utils.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/lesfurets/git-octopus/git"
5 | "io/ioutil"
6 | "os"
7 | )
8 |
9 | func CreateTempDir() string {
10 | dir, _ := ioutil.TempDir("", "git-octopus-test-")
11 | return dir
12 | }
13 |
14 | func Cleanup(repo *git.Repository) error {
15 | return os.RemoveAll(repo.Path)
16 | }
17 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/LICENCE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
2 |
3 | Please consider promoting this project if you find it useful.
4 |
5 | Permission is hereby granted, free of charge, to any person
6 | obtaining a copy of this software and associated documentation
7 | files (the "Software"), to deal in the Software without restriction,
8 | including without limitation the rights to use, copy, modify, merge,
9 | publish, distribute, sublicense, and/or sell copies of the Software,
10 | and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
2 |
3 | Please consider promoting this project if you find it useful.
4 |
5 | Permission is hereby granted, free of charge, to any person
6 | obtaining a copy of this software and associated documentation
7 | files (the "Software"), to deal in the Software without restriction,
8 | including without limitation the rights to use, copy, modify, merge,
9 | publish, distribute, sublicense, and/or sell copies of the Software,
10 | and to permit persons to whom the Software is furnished to do so,
11 | subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included
14 | in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
21 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/doc.go:
--------------------------------------------------------------------------------
1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
2 | //
3 | // Example Usage
4 | //
5 | // The following is a complete example using assert in a standard test function:
6 | // import (
7 | // "testing"
8 | // "github.com/stretchr/testify/assert"
9 | // )
10 | //
11 | // func TestSomething(t *testing.T) {
12 | //
13 | // var a string = "Hello"
14 | // var b string = "Hello"
15 | //
16 | // assert.Equal(t, a, b, "The two words should be the same.")
17 | //
18 | // }
19 | //
20 | // if you assert many times, use the format below:
21 | //
22 | // import (
23 | // "testing"
24 | // "github.com/stretchr/testify/assert"
25 | // )
26 | //
27 | // func TestSomething(t *testing.T) {
28 | // assert := assert.New(t)
29 | //
30 | // var a string = "Hello"
31 | // var b string = "Hello"
32 | //
33 | // assert.Equal(a, b, "The two words should be the same.")
34 | // }
35 | //
36 | // Assertions
37 | //
38 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package.
39 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the
40 | // testing framework. This allows the assertion funcs to write the failings and other details to
41 | // the correct place.
42 | //
43 | // Every assertion function also takes an optional string message as the final argument,
44 | // allowing custom error messages to be appended to the message the assertion method outputs.
45 | package assert
46 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/errors.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | // AnError is an error instance useful for testing. If the code does not care
8 | // about error specifics, and only needs to return the error for example, this
9 | // error should be used to make the test code more readable.
10 | var AnError = errors.New("assert.AnError general error for testing")
11 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/forward_assertions.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | // Assertions provides assertion methods around the
4 | // TestingT interface.
5 | type Assertions struct {
6 | t TestingT
7 | }
8 |
9 | // New makes a new Assertions object for the specified TestingT.
10 | func New(t TestingT) *Assertions {
11 | return &Assertions{
12 | t: t,
13 | }
14 | }
15 |
16 | //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl
17 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/http_assertions.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "fmt"
5 | "net/http"
6 | "net/http/httptest"
7 | "net/url"
8 | "strings"
9 | )
10 |
11 | // httpCode is a helper that returns HTTP code of the response. It returns -1
12 | // if building a new request fails.
13 | func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int {
14 | w := httptest.NewRecorder()
15 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
16 | if err != nil {
17 | return -1
18 | }
19 | handler(w, req)
20 | return w.Code
21 | }
22 |
23 | // HTTPSuccess asserts that a specified handler returns a success status code.
24 | //
25 | // assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil)
26 | //
27 | // Returns whether the assertion was successful (true) or not (false).
28 | func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
29 | code := httpCode(handler, method, url, values)
30 | if code == -1 {
31 | return false
32 | }
33 | return code >= http.StatusOK && code <= http.StatusPartialContent
34 | }
35 |
36 | // HTTPRedirect asserts that a specified handler returns a redirect status code.
37 | //
38 | // assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
39 | //
40 | // Returns whether the assertion was successful (true) or not (false).
41 | func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
42 | code := httpCode(handler, method, url, values)
43 | if code == -1 {
44 | return false
45 | }
46 | return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect
47 | }
48 |
49 | // HTTPError asserts that a specified handler returns an error status code.
50 | //
51 | // assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
52 | //
53 | // Returns whether the assertion was successful (true) or not (false).
54 | func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool {
55 | code := httpCode(handler, method, url, values)
56 | if code == -1 {
57 | return false
58 | }
59 | return code >= http.StatusBadRequest
60 | }
61 |
62 | // HTTPBody is a helper that returns HTTP body of the response. It returns
63 | // empty string if building a new request fails.
64 | func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {
65 | w := httptest.NewRecorder()
66 | req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
67 | if err != nil {
68 | return ""
69 | }
70 | handler(w, req)
71 | return w.Body.String()
72 | }
73 |
74 | // HTTPBodyContains asserts that a specified handler returns a
75 | // body that contains a string.
76 | //
77 | // assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
78 | //
79 | // Returns whether the assertion was successful (true) or not (false).
80 | func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
81 | body := HTTPBody(handler, method, url, values)
82 |
83 | contains := strings.Contains(body, fmt.Sprint(str))
84 | if !contains {
85 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
86 | }
87 |
88 | return contains
89 | }
90 |
91 | // HTTPBodyNotContains asserts that a specified handler returns a
92 | // body that does not contain a string.
93 | //
94 | // assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
95 | //
96 | // Returns whether the assertion was successful (true) or not (false).
97 | func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool {
98 | body := HTTPBody(handler, method, url, values)
99 |
100 | contains := strings.Contains(body, fmt.Sprint(str))
101 | if contains {
102 | Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body))
103 | }
104 |
105 | return !contains
106 | }
107 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/doc.go:
--------------------------------------------------------------------------------
1 | // Package testify is a set of packages that provide many tools for testifying that your code will behave as you intend.
2 | //
3 | // testify contains the following packages:
4 | //
5 | // The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system.
6 | //
7 | // The http package contains tools to make it easier to test http activity using the Go testing system.
8 | //
9 | // The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected.
10 | //
11 | // The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests. It includes setup/teardown functionality in the way of interfaces.
12 | package testify
13 |
14 | // blank imports help docs.
15 | import (
16 | // assert package
17 | _ "github.com/stretchr/testify/assert"
18 | // http package
19 | _ "github.com/stretchr/testify/http"
20 | // mock package
21 | _ "github.com/stretchr/testify/mock"
22 | )
23 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/http/doc.go:
--------------------------------------------------------------------------------
1 | // Package http DEPRECATED USE net/http/httptest
2 | package http
3 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/http/test_response_writer.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import (
4 | "net/http"
5 | )
6 |
7 | // TestResponseWriter DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
8 | type TestResponseWriter struct {
9 |
10 | // StatusCode is the last int written by the call to WriteHeader(int)
11 | StatusCode int
12 |
13 | // Output is a string containing the written bytes using the Write([]byte) func.
14 | Output string
15 |
16 | // header is the internal storage of the http.Header object
17 | header http.Header
18 | }
19 |
20 | // Header DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
21 | func (rw *TestResponseWriter) Header() http.Header {
22 |
23 | if rw.header == nil {
24 | rw.header = make(http.Header)
25 | }
26 |
27 | return rw.header
28 | }
29 |
30 | // Write DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
31 | func (rw *TestResponseWriter) Write(bytes []byte) (int, error) {
32 |
33 | // assume 200 success if no header has been set
34 | if rw.StatusCode == 0 {
35 | rw.WriteHeader(200)
36 | }
37 |
38 | // add these bytes to the output string
39 | rw.Output = rw.Output + string(bytes)
40 |
41 | // return normal values
42 | return 0, nil
43 |
44 | }
45 |
46 | // WriteHeader DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
47 | func (rw *TestResponseWriter) WriteHeader(i int) {
48 | rw.StatusCode = i
49 | }
50 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/http/test_round_tripper.go:
--------------------------------------------------------------------------------
1 | package http
2 |
3 | import (
4 | "github.com/stretchr/testify/mock"
5 | "net/http"
6 | )
7 |
8 | // TestRoundTripper DEPRECATED USE net/http/httptest
9 | type TestRoundTripper struct {
10 | mock.Mock
11 | }
12 |
13 | // RoundTrip DEPRECATED USE net/http/httptest
14 | func (t *TestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
15 | args := t.Called(req)
16 | return args.Get(0).(*http.Response), args.Error(1)
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/mock/doc.go:
--------------------------------------------------------------------------------
1 | // Package mock provides a system by which it is possible to mock your objects
2 | // and verify calls are happening as expected.
3 | //
4 | // Example Usage
5 | //
6 | // The mock package provides an object, Mock, that tracks activity on another object. It is usually
7 | // embedded into a test object as shown below:
8 | //
9 | // type MyTestObject struct {
10 | // // add a Mock object instance
11 | // mock.Mock
12 | //
13 | // // other fields go here as normal
14 | // }
15 | //
16 | // When implementing the methods of an interface, you wire your functions up
17 | // to call the Mock.Called(args...) method, and return the appropriate values.
18 | //
19 | // For example, to mock a method that saves the name and age of a person and returns
20 | // the year of their birth or an error, you might write this:
21 | //
22 | // func (o *MyTestObject) SavePersonDetails(firstname, lastname string, age int) (int, error) {
23 | // args := o.Called(firstname, lastname, age)
24 | // return args.Int(0), args.Error(1)
25 | // }
26 | //
27 | // The Int, Error and Bool methods are examples of strongly typed getters that take the argument
28 | // index position. Given this argument list:
29 | //
30 | // (12, true, "Something")
31 | //
32 | // You could read them out strongly typed like this:
33 | //
34 | // args.Int(0)
35 | // args.Bool(1)
36 | // args.String(2)
37 | //
38 | // For objects of your own type, use the generic Arguments.Get(index) method and make a type assertion:
39 | //
40 | // return args.Get(0).(*MyObject), args.Get(1).(*AnotherObjectOfMine)
41 | //
42 | // This may cause a panic if the object you are getting is nil (the type assertion will fail), in those
43 | // cases you should check for nil first.
44 | package mock
45 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/doc.go:
--------------------------------------------------------------------------------
1 | // Package require implements the same assertions as the `assert` package but
2 | // stops test execution when a test fails.
3 | //
4 | // Example Usage
5 | //
6 | // The following is a complete example using require in a standard test function:
7 | // import (
8 | // "testing"
9 | // "github.com/stretchr/testify/require"
10 | // )
11 | //
12 | // func TestSomething(t *testing.T) {
13 | //
14 | // var a string = "Hello"
15 | // var b string = "Hello"
16 | //
17 | // require.Equal(t, a, b, "The two words should be the same.")
18 | //
19 | // }
20 | //
21 | // Assertions
22 | //
23 | // The `require` package have same global functions as in the `assert` package,
24 | // but instead of returning a boolean result they call `t.FailNow()`.
25 | //
26 | // Every assertion function also takes an optional string message as the final argument,
27 | // allowing custom error messages to be appended to the message the assertion method outputs.
28 | package require
29 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/forward_requirements.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | // Assertions provides assertion methods around the
4 | // TestingT interface.
5 | type Assertions struct {
6 | t TestingT
7 | }
8 |
9 | // New makes a new Assertions object for the specified TestingT.
10 | func New(t TestingT) *Assertions {
11 | return &Assertions{
12 | t: t,
13 | }
14 | }
15 |
16 | //go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl
17 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/require_forward.go:
--------------------------------------------------------------------------------
1 | /*
2 | * CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen
3 | * THIS FILE MUST NOT BE EDITED BY HAND
4 | */
5 |
6 | package require
7 |
8 | import (
9 | assert "github.com/stretchr/testify/assert"
10 | http "net/http"
11 | url "net/url"
12 | time "time"
13 | )
14 |
15 | // Condition uses a Comparison to assert a complex condition.
16 | func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) {
17 | Condition(a.t, comp, msgAndArgs...)
18 | }
19 |
20 | // Contains asserts that the specified string, list(array, slice...) or map contains the
21 | // specified substring or element.
22 | //
23 | // a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'")
24 | // a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'")
25 | // a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'")
26 | //
27 | // Returns whether the assertion was successful (true) or not (false).
28 | func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
29 | Contains(a.t, s, contains, msgAndArgs...)
30 | }
31 |
32 | // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either
33 | // a slice or a channel with len == 0.
34 | //
35 | // a.Empty(obj)
36 | //
37 | // Returns whether the assertion was successful (true) or not (false).
38 | func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {
39 | Empty(a.t, object, msgAndArgs...)
40 | }
41 |
42 | // Equal asserts that two objects are equal.
43 | //
44 | // a.Equal(123, 123, "123 and 123 should be equal")
45 | //
46 | // Returns whether the assertion was successful (true) or not (false).
47 | //
48 | // Pointer variable equality is determined based on the equality of the
49 | // referenced values (as opposed to the memory addresses).
50 | func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
51 | Equal(a.t, expected, actual, msgAndArgs...)
52 | }
53 |
54 | // EqualError asserts that a function returned an error (i.e. not `nil`)
55 | // and that it is equal to the provided error.
56 | //
57 | // actualObj, err := SomeFunction()
58 | // a.EqualError(err, expectedErrorString, "An error was expected")
59 | //
60 | // Returns whether the assertion was successful (true) or not (false).
61 | func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {
62 | EqualError(a.t, theError, errString, msgAndArgs...)
63 | }
64 |
65 | // EqualValues asserts that two objects are equal or convertable to the same types
66 | // and equal.
67 | //
68 | // a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal")
69 | //
70 | // Returns whether the assertion was successful (true) or not (false).
71 | func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
72 | EqualValues(a.t, expected, actual, msgAndArgs...)
73 | }
74 |
75 | // Error asserts that a function returned an error (i.e. not `nil`).
76 | //
77 | // actualObj, err := SomeFunction()
78 | // if a.Error(err, "An error was expected") {
79 | // assert.Equal(t, err, expectedError)
80 | // }
81 | //
82 | // Returns whether the assertion was successful (true) or not (false).
83 | func (a *Assertions) Error(err error, msgAndArgs ...interface{}) {
84 | Error(a.t, err, msgAndArgs...)
85 | }
86 |
87 | // Exactly asserts that two objects are equal is value and type.
88 | //
89 | // a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal")
90 | //
91 | // Returns whether the assertion was successful (true) or not (false).
92 | func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
93 | Exactly(a.t, expected, actual, msgAndArgs...)
94 | }
95 |
96 | // Fail reports a failure through
97 | func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {
98 | Fail(a.t, failureMessage, msgAndArgs...)
99 | }
100 |
101 | // FailNow fails test
102 | func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) {
103 | FailNow(a.t, failureMessage, msgAndArgs...)
104 | }
105 |
106 | // False asserts that the specified value is false.
107 | //
108 | // a.False(myBool, "myBool should be false")
109 | //
110 | // Returns whether the assertion was successful (true) or not (false).
111 | func (a *Assertions) False(value bool, msgAndArgs ...interface{}) {
112 | False(a.t, value, msgAndArgs...)
113 | }
114 |
115 | // HTTPBodyContains asserts that a specified handler returns a
116 | // body that contains a string.
117 | //
118 | // a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
119 | //
120 | // Returns whether the assertion was successful (true) or not (false).
121 | func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
122 | HTTPBodyContains(a.t, handler, method, url, values, str)
123 | }
124 |
125 | // HTTPBodyNotContains asserts that a specified handler returns a
126 | // body that does not contain a string.
127 | //
128 | // a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
129 | //
130 | // Returns whether the assertion was successful (true) or not (false).
131 | func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) {
132 | HTTPBodyNotContains(a.t, handler, method, url, values, str)
133 | }
134 |
135 | // HTTPError asserts that a specified handler returns an error status code.
136 | //
137 | // a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}}
138 | //
139 | // Returns whether the assertion was successful (true) or not (false).
140 | func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) {
141 | HTTPError(a.t, handler, method, url, values)
142 | }
143 |
144 | // HTTPRedirect asserts that a specified handler returns a redirect status code.
145 | //
146 | // a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}}
147 | //
148 | // Returns whether the assertion was successful (true) or not (false).
149 | func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) {
150 | HTTPRedirect(a.t, handler, method, url, values)
151 | }
152 |
153 | // HTTPSuccess asserts that a specified handler returns a success status code.
154 | //
155 | // a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil)
156 | //
157 | // Returns whether the assertion was successful (true) or not (false).
158 | func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) {
159 | HTTPSuccess(a.t, handler, method, url, values)
160 | }
161 |
162 | // Implements asserts that an object is implemented by the specified interface.
163 | //
164 | // a.Implements((*MyInterface)(nil), new(MyObject), "MyObject")
165 | func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
166 | Implements(a.t, interfaceObject, object, msgAndArgs...)
167 | }
168 |
169 | // InDelta asserts that the two numerals are within delta of each other.
170 | //
171 | // a.InDelta(math.Pi, (22 / 7.0), 0.01)
172 | //
173 | // Returns whether the assertion was successful (true) or not (false).
174 | func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
175 | InDelta(a.t, expected, actual, delta, msgAndArgs...)
176 | }
177 |
178 | // InDeltaSlice is the same as InDelta, except it compares two slices.
179 | func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
180 | InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
181 | }
182 |
183 | // InEpsilon asserts that expected and actual have a relative error less than epsilon
184 | //
185 | // Returns whether the assertion was successful (true) or not (false).
186 | func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
187 | InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
188 | }
189 |
190 | // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
191 | func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
192 | InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
193 | }
194 |
195 | // IsType asserts that the specified objects are of the same type.
196 | func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
197 | IsType(a.t, expectedType, object, msgAndArgs...)
198 | }
199 |
200 | // JSONEq asserts that two JSON strings are equivalent.
201 | //
202 | // a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
203 | //
204 | // Returns whether the assertion was successful (true) or not (false).
205 | func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {
206 | JSONEq(a.t, expected, actual, msgAndArgs...)
207 | }
208 |
209 | // Len asserts that the specified object has specific length.
210 | // Len also fails if the object has a type that len() not accept.
211 | //
212 | // a.Len(mySlice, 3, "The size of slice is not 3")
213 | //
214 | // Returns whether the assertion was successful (true) or not (false).
215 | func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {
216 | Len(a.t, object, length, msgAndArgs...)
217 | }
218 |
219 | // Nil asserts that the specified object is nil.
220 | //
221 | // a.Nil(err, "err should be nothing")
222 | //
223 | // Returns whether the assertion was successful (true) or not (false).
224 | func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {
225 | Nil(a.t, object, msgAndArgs...)
226 | }
227 |
228 | // NoError asserts that a function returned no error (i.e. `nil`).
229 | //
230 | // actualObj, err := SomeFunction()
231 | // if a.NoError(err) {
232 | // assert.Equal(t, actualObj, expectedObj)
233 | // }
234 | //
235 | // Returns whether the assertion was successful (true) or not (false).
236 | func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {
237 | NoError(a.t, err, msgAndArgs...)
238 | }
239 |
240 | // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the
241 | // specified substring or element.
242 | //
243 | // a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'")
244 | // a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'")
245 | // a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'")
246 | //
247 | // Returns whether the assertion was successful (true) or not (false).
248 | func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {
249 | NotContains(a.t, s, contains, msgAndArgs...)
250 | }
251 |
252 | // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either
253 | // a slice or a channel with len == 0.
254 | //
255 | // if a.NotEmpty(obj) {
256 | // assert.Equal(t, "two", obj[1])
257 | // }
258 | //
259 | // Returns whether the assertion was successful (true) or not (false).
260 | func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {
261 | NotEmpty(a.t, object, msgAndArgs...)
262 | }
263 |
264 | // NotEqual asserts that the specified values are NOT equal.
265 | //
266 | // a.NotEqual(obj1, obj2, "two objects shouldn't be equal")
267 | //
268 | // Returns whether the assertion was successful (true) or not (false).
269 | //
270 | // Pointer variable equality is determined based on the equality of the
271 | // referenced values (as opposed to the memory addresses).
272 | func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
273 | NotEqual(a.t, expected, actual, msgAndArgs...)
274 | }
275 |
276 | // NotNil asserts that the specified object is not nil.
277 | //
278 | // a.NotNil(err, "err should be something")
279 | //
280 | // Returns whether the assertion was successful (true) or not (false).
281 | func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {
282 | NotNil(a.t, object, msgAndArgs...)
283 | }
284 |
285 | // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.
286 | //
287 | // a.NotPanics(func(){
288 | // RemainCalm()
289 | // }, "Calling RemainCalm() should NOT panic")
290 | //
291 | // Returns whether the assertion was successful (true) or not (false).
292 | func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
293 | NotPanics(a.t, f, msgAndArgs...)
294 | }
295 |
296 | // NotRegexp asserts that a specified regexp does not match a string.
297 | //
298 | // a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
299 | // a.NotRegexp("^start", "it's not starting")
300 | //
301 | // Returns whether the assertion was successful (true) or not (false).
302 | func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
303 | NotRegexp(a.t, rx, str, msgAndArgs...)
304 | }
305 |
306 | // NotZero asserts that i is not the zero value for its type and returns the truth.
307 | func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {
308 | NotZero(a.t, i, msgAndArgs...)
309 | }
310 |
311 | // Panics asserts that the code inside the specified PanicTestFunc panics.
312 | //
313 | // a.Panics(func(){
314 | // GoCrazy()
315 | // }, "Calling GoCrazy() should panic")
316 | //
317 | // Returns whether the assertion was successful (true) or not (false).
318 | func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {
319 | Panics(a.t, f, msgAndArgs...)
320 | }
321 |
322 | // Regexp asserts that a specified regexp matches a string.
323 | //
324 | // a.Regexp(regexp.MustCompile("start"), "it's starting")
325 | // a.Regexp("start...$", "it's not starting")
326 | //
327 | // Returns whether the assertion was successful (true) or not (false).
328 | func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {
329 | Regexp(a.t, rx, str, msgAndArgs...)
330 | }
331 |
332 | // True asserts that the specified value is true.
333 | //
334 | // a.True(myBool, "myBool should be true")
335 | //
336 | // Returns whether the assertion was successful (true) or not (false).
337 | func (a *Assertions) True(value bool, msgAndArgs ...interface{}) {
338 | True(a.t, value, msgAndArgs...)
339 | }
340 |
341 | // WithinDuration asserts that the two times are within duration delta of each other.
342 | //
343 | // a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s")
344 | //
345 | // Returns whether the assertion was successful (true) or not (false).
346 | func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
347 | WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
348 | }
349 |
350 | // Zero asserts that i is the zero value for its type and returns the truth.
351 | func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {
352 | Zero(a.t, i, msgAndArgs...)
353 | }
354 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/requirements.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | // TestingT is an interface wrapper around *testing.T
4 | type TestingT interface {
5 | Errorf(format string, args ...interface{})
6 | FailNow()
7 | }
8 |
9 | //go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl
10 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/suite/doc.go:
--------------------------------------------------------------------------------
1 | // Package suite contains logic for creating testing suite structs
2 | // and running the methods on those structs as tests. The most useful
3 | // piece of this package is that you can create setup/teardown methods
4 | // on your testing suites, which will run before/after the whole suite
5 | // or individual tests (depending on which interface(s) you
6 | // implement).
7 | //
8 | // A testing suite is usually built by first extending the built-in
9 | // suite functionality from suite.Suite in testify. Alternatively,
10 | // you could reproduce that logic on your own if you wanted (you
11 | // just need to implement the TestingSuite interface from
12 | // suite/interfaces.go).
13 | //
14 | // After that, you can implement any of the interfaces in
15 | // suite/interfaces.go to add setup/teardown functionality to your
16 | // suite, and add any methods that start with "Test" to add tests.
17 | // Methods that do not match any suite interfaces and do not begin
18 | // with "Test" will not be run by testify, and can safely be used as
19 | // helper methods.
20 | //
21 | // Once you've built your testing suite, you need to run the suite
22 | // (using suite.Run from testify) inside any function that matches the
23 | // identity that "go test" is already looking for (i.e.
24 | // func(*testing.T)).
25 | //
26 | // Regular expression to select test suites specified command-line
27 | // argument "-run". Regular expression to select the methods
28 | // of test suites specified command-line argument "-m".
29 | // Suite object has assertion methods.
30 | //
31 | // A crude example:
32 | // // Basic imports
33 | // import (
34 | // "testing"
35 | // "github.com/stretchr/testify/assert"
36 | // "github.com/stretchr/testify/suite"
37 | // )
38 | //
39 | // // Define the suite, and absorb the built-in basic suite
40 | // // functionality from testify - including a T() method which
41 | // // returns the current testing context
42 | // type ExampleTestSuite struct {
43 | // suite.Suite
44 | // VariableThatShouldStartAtFive int
45 | // }
46 | //
47 | // // Make sure that VariableThatShouldStartAtFive is set to five
48 | // // before each test
49 | // func (suite *ExampleTestSuite) SetupTest() {
50 | // suite.VariableThatShouldStartAtFive = 5
51 | // }
52 | //
53 | // // All methods that begin with "Test" are run as tests within a
54 | // // suite.
55 | // func (suite *ExampleTestSuite) TestExample() {
56 | // assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
57 | // suite.Equal(5, suite.VariableThatShouldStartAtFive)
58 | // }
59 | //
60 | // // In order for 'go test' to run this suite, we need to create
61 | // // a normal test function and pass our suite to suite.Run
62 | // func TestExampleTestSuite(t *testing.T) {
63 | // suite.Run(t, new(ExampleTestSuite))
64 | // }
65 | package suite
66 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/suite/interfaces.go:
--------------------------------------------------------------------------------
1 | package suite
2 |
3 | import "testing"
4 |
5 | // TestingSuite can store and return the current *testing.T context
6 | // generated by 'go test'.
7 | type TestingSuite interface {
8 | T() *testing.T
9 | SetT(*testing.T)
10 | }
11 |
12 | // SetupAllSuite has a SetupSuite method, which will run before the
13 | // tests in the suite are run.
14 | type SetupAllSuite interface {
15 | SetupSuite()
16 | }
17 |
18 | // SetupTestSuite has a SetupTest method, which will run before each
19 | // test in the suite.
20 | type SetupTestSuite interface {
21 | SetupTest()
22 | }
23 |
24 | // TearDownAllSuite has a TearDownSuite method, which will run after
25 | // all the tests in the suite have been run.
26 | type TearDownAllSuite interface {
27 | TearDownSuite()
28 | }
29 |
30 | // TearDownTestSuite has a TearDownTest method, which will run after
31 | // each test in the suite.
32 | type TearDownTestSuite interface {
33 | TearDownTest()
34 | }
35 |
36 | // BeforeTest has a function to be executed right before the test
37 | // starts and receives the suite and test names as input
38 | type BeforeTest interface {
39 | BeforeTest(suiteName, testName string)
40 | }
41 |
42 | // AfterTest has a function to be executed right after the test
43 | // finishes and receives the suite and test names as input
44 | type AfterTest interface {
45 | AfterTest(suiteName, testName string)
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/suite/suite.go:
--------------------------------------------------------------------------------
1 | package suite
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | "os"
7 | "reflect"
8 | "regexp"
9 | "testing"
10 |
11 | "github.com/stretchr/testify/assert"
12 | "github.com/stretchr/testify/require"
13 | )
14 |
15 | var matchMethod = flag.String("testify.m", "", "regular expression to select tests of the testify suite to run")
16 |
17 | // Suite is a basic testing suite with methods for storing and
18 | // retrieving the current *testing.T context.
19 | type Suite struct {
20 | *assert.Assertions
21 | require *require.Assertions
22 | t *testing.T
23 | }
24 |
25 | // T retrieves the current *testing.T context.
26 | func (suite *Suite) T() *testing.T {
27 | return suite.t
28 | }
29 |
30 | // SetT sets the current *testing.T context.
31 | func (suite *Suite) SetT(t *testing.T) {
32 | suite.t = t
33 | suite.Assertions = assert.New(t)
34 | suite.require = require.New(t)
35 | }
36 |
37 | // Require returns a require context for suite.
38 | func (suite *Suite) Require() *require.Assertions {
39 | if suite.require == nil {
40 | suite.require = require.New(suite.T())
41 | }
42 | return suite.require
43 | }
44 |
45 | // Assert returns an assert context for suite. Normally, you can call
46 | // `suite.NoError(expected, actual)`, but for situations where the embedded
47 | // methods are overridden (for example, you might want to override
48 | // assert.Assertions with require.Assertions), this method is provided so you
49 | // can call `suite.Assert().NoError()`.
50 | func (suite *Suite) Assert() *assert.Assertions {
51 | if suite.Assertions == nil {
52 | suite.Assertions = assert.New(suite.T())
53 | }
54 | return suite.Assertions
55 | }
56 |
57 | // Run takes a testing suite and runs all of the tests attached
58 | // to it.
59 | func Run(t *testing.T, suite TestingSuite) {
60 | suite.SetT(t)
61 |
62 | if setupAllSuite, ok := suite.(SetupAllSuite); ok {
63 | setupAllSuite.SetupSuite()
64 | }
65 | defer func() {
66 | if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
67 | tearDownAllSuite.TearDownSuite()
68 | }
69 | }()
70 |
71 | methodFinder := reflect.TypeOf(suite)
72 | tests := []testing.InternalTest{}
73 | for index := 0; index < methodFinder.NumMethod(); index++ {
74 | method := methodFinder.Method(index)
75 | ok, err := methodFilter(method.Name)
76 | if err != nil {
77 | fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
78 | os.Exit(1)
79 | }
80 | if ok {
81 | test := testing.InternalTest{
82 | Name: method.Name,
83 | F: func(t *testing.T) {
84 | parentT := suite.T()
85 | suite.SetT(t)
86 | if setupTestSuite, ok := suite.(SetupTestSuite); ok {
87 | setupTestSuite.SetupTest()
88 | }
89 | if beforeTestSuite, ok := suite.(BeforeTest); ok {
90 | beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
91 | }
92 | defer func() {
93 | if afterTestSuite, ok := suite.(AfterTest); ok {
94 | afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
95 | }
96 | if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
97 | tearDownTestSuite.TearDownTest()
98 | }
99 | suite.SetT(parentT)
100 | }()
101 | method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
102 | },
103 | }
104 | tests = append(tests, test)
105 | }
106 | }
107 |
108 | if !testing.RunTests(func(_, _ string) (bool, error) { return true, nil },
109 | tests) {
110 | t.Fail()
111 | }
112 | }
113 |
114 | // Filtering method according to set regular expression
115 | // specified command-line argument -m
116 | func methodFilter(name string) (bool, error) {
117 | if ok, _ := regexp.MatchString("^Test", name); !ok {
118 | return false, nil
119 | }
120 | return regexp.MatchString(*matchMethod, name)
121 | }
122 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypass.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015 Dave Collins
2 | //
3 | // Permission to use, copy, modify, and distribute this software for any
4 | // purpose with or without fee is hereby granted, provided that the above
5 | // copyright notice and this permission notice appear in all copies.
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 |
15 | // NOTE: Due to the following build constraints, this file will only be compiled
16 | // when the code is not running on Google App Engine, compiled by GopherJS, and
17 | // "-tags safe" is not added to the go build command line. The "disableunsafe"
18 | // tag is deprecated and thus should not be used.
19 | // +build !js,!appengine,!safe,!disableunsafe
20 |
21 | package spew
22 |
23 | import (
24 | "reflect"
25 | "unsafe"
26 | )
27 |
28 | const (
29 | // UnsafeDisabled is a build-time constant which specifies whether or
30 | // not access to the unsafe package is available.
31 | UnsafeDisabled = false
32 |
33 | // ptrSize is the size of a pointer on the current arch.
34 | ptrSize = unsafe.Sizeof((*byte)(nil))
35 | )
36 |
37 | var (
38 | // offsetPtr, offsetScalar, and offsetFlag are the offsets for the
39 | // internal reflect.Value fields. These values are valid before golang
40 | // commit ecccf07e7f9d which changed the format. The are also valid
41 | // after commit 82f48826c6c7 which changed the format again to mirror
42 | // the original format. Code in the init function updates these offsets
43 | // as necessary.
44 | offsetPtr = uintptr(ptrSize)
45 | offsetScalar = uintptr(0)
46 | offsetFlag = uintptr(ptrSize * 2)
47 |
48 | // flagKindWidth and flagKindShift indicate various bits that the
49 | // reflect package uses internally to track kind information.
50 | //
51 | // flagRO indicates whether or not the value field of a reflect.Value is
52 | // read-only.
53 | //
54 | // flagIndir indicates whether the value field of a reflect.Value is
55 | // the actual data or a pointer to the data.
56 | //
57 | // These values are valid before golang commit 90a7c3c86944 which
58 | // changed their positions. Code in the init function updates these
59 | // flags as necessary.
60 | flagKindWidth = uintptr(5)
61 | flagKindShift = uintptr(flagKindWidth - 1)
62 | flagRO = uintptr(1 << 0)
63 | flagIndir = uintptr(1 << 1)
64 | )
65 |
66 | func init() {
67 | // Older versions of reflect.Value stored small integers directly in the
68 | // ptr field (which is named val in the older versions). Versions
69 | // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
70 | // scalar for this purpose which unfortunately came before the flag
71 | // field, so the offset of the flag field is different for those
72 | // versions.
73 | //
74 | // This code constructs a new reflect.Value from a known small integer
75 | // and checks if the size of the reflect.Value struct indicates it has
76 | // the scalar field. When it does, the offsets are updated accordingly.
77 | vv := reflect.ValueOf(0xf00)
78 | if unsafe.Sizeof(vv) == (ptrSize * 4) {
79 | offsetScalar = ptrSize * 2
80 | offsetFlag = ptrSize * 3
81 | }
82 |
83 | // Commit 90a7c3c86944 changed the flag positions such that the low
84 | // order bits are the kind. This code extracts the kind from the flags
85 | // field and ensures it's the correct type. When it's not, the flag
86 | // order has been changed to the newer format, so the flags are updated
87 | // accordingly.
88 | upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
89 | upfv := *(*uintptr)(upf)
90 | flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) {
92 | flagKindShift = 0
93 | flagRO = 1 << 5
94 | flagIndir = 1 << 6
95 |
96 | // Commit adf9b30e5594 modified the flags to separate the
97 | // flagRO flag into two bits which specifies whether or not the
98 | // field is embedded. This causes flagIndir to move over a bit
99 | // and means that flagRO is the combination of either of the
100 | // original flagRO bit and the new bit.
101 | //
102 | // This code detects the change by extracting what used to be
103 | // the indirect bit to ensure it's set. When it's not, the flag
104 | // order has been changed to the newer format, so the flags are
105 | // updated accordingly.
106 | if upfv&flagIndir == 0 {
107 | flagRO = 3 << 5
108 | flagIndir = 1 << 7
109 | }
110 | }
111 | }
112 |
113 | // unsafeReflectValue converts the passed reflect.Value into a one that bypasses
114 | // the typical safety restrictions preventing access to unaddressable and
115 | // unexported data. It works by digging the raw pointer to the underlying
116 | // value out of the protected value and generating a new unprotected (unsafe)
117 | // reflect.Value to it.
118 | //
119 | // This allows us to check for implementations of the Stringer and error
120 | // interfaces to be used for pretty printing ordinarily unaddressable and
121 | // inaccessible values such as unexported struct fields.
122 | func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
123 | indirects := 1
124 | vt := v.Type()
125 | upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
126 | rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
127 | if rvf&flagIndir != 0 {
128 | vt = reflect.PtrTo(v.Type())
129 | indirects++
130 | } else if offsetScalar != 0 {
131 | // The value is in the scalar field when it's not one of the
132 | // reference types.
133 | switch vt.Kind() {
134 | case reflect.Uintptr:
135 | case reflect.Chan:
136 | case reflect.Func:
137 | case reflect.Map:
138 | case reflect.Ptr:
139 | case reflect.UnsafePointer:
140 | default:
141 | upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
142 | offsetScalar)
143 | }
144 | }
145 |
146 | pv := reflect.NewAt(vt, upv)
147 | rv = pv
148 | for i := 0; i < indirects; i++ {
149 | rv = rv.Elem()
150 | }
151 | return rv
152 | }
153 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015 Dave Collins
2 | //
3 | // Permission to use, copy, modify, and distribute this software for any
4 | // purpose with or without fee is hereby granted, provided that the above
5 | // copyright notice and this permission notice appear in all copies.
6 | //
7 | // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 | // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 | // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 | // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 | // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 | // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 | // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 |
15 | // NOTE: Due to the following build constraints, this file will only be compiled
16 | // when the code is running on Google App Engine, compiled by GopherJS, or
17 | // "-tags safe" is added to the go build command line. The "disableunsafe"
18 | // tag is deprecated and thus should not be used.
19 | // +build js appengine safe disableunsafe
20 |
21 | package spew
22 |
23 | import "reflect"
24 |
25 | const (
26 | // UnsafeDisabled is a build-time constant which specifies whether or
27 | // not access to the unsafe package is available.
28 | UnsafeDisabled = true
29 | )
30 |
31 | // unsafeReflectValue typically converts the passed reflect.Value into a one
32 | // that bypasses the typical safety restrictions preventing access to
33 | // unaddressable and unexported data. However, doing this relies on access to
34 | // the unsafe package. This is a stub version which simply returns the passed
35 | // reflect.Value when the unsafe package is not available.
36 | func unsafeReflectValue(v reflect.Value) reflect.Value {
37 | return v
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/common.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Dave Collins
3 | *
4 | * Permission to use, copy, modify, and distribute this software for any
5 | * purpose with or without fee is hereby granted, provided that the above
6 | * copyright notice and this permission notice appear in all copies.
7 | *
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 | */
16 |
17 | package spew
18 |
19 | import (
20 | "bytes"
21 | "fmt"
22 | "io"
23 | "reflect"
24 | "sort"
25 | "strconv"
26 | )
27 |
28 | // Some constants in the form of bytes to avoid string overhead. This mirrors
29 | // the technique used in the fmt package.
30 | var (
31 | panicBytes = []byte("(PANIC=")
32 | plusBytes = []byte("+")
33 | iBytes = []byte("i")
34 | trueBytes = []byte("true")
35 | falseBytes = []byte("false")
36 | interfaceBytes = []byte("(interface {})")
37 | commaNewlineBytes = []byte(",\n")
38 | newlineBytes = []byte("\n")
39 | openBraceBytes = []byte("{")
40 | openBraceNewlineBytes = []byte("{\n")
41 | closeBraceBytes = []byte("}")
42 | asteriskBytes = []byte("*")
43 | colonBytes = []byte(":")
44 | colonSpaceBytes = []byte(": ")
45 | openParenBytes = []byte("(")
46 | closeParenBytes = []byte(")")
47 | spaceBytes = []byte(" ")
48 | pointerChainBytes = []byte("->")
49 | nilAngleBytes = []byte("")
50 | maxNewlineBytes = []byte("\n")
51 | maxShortBytes = []byte("")
52 | circularBytes = []byte("")
53 | circularShortBytes = []byte("")
54 | invalidAngleBytes = []byte("")
55 | openBracketBytes = []byte("[")
56 | closeBracketBytes = []byte("]")
57 | percentBytes = []byte("%")
58 | precisionBytes = []byte(".")
59 | openAngleBytes = []byte("<")
60 | closeAngleBytes = []byte(">")
61 | openMapBytes = []byte("map[")
62 | closeMapBytes = []byte("]")
63 | lenEqualsBytes = []byte("len=")
64 | capEqualsBytes = []byte("cap=")
65 | )
66 |
67 | // hexDigits is used to map a decimal value to a hex digit.
68 | var hexDigits = "0123456789abcdef"
69 |
70 | // catchPanic handles any panics that might occur during the handleMethods
71 | // calls.
72 | func catchPanic(w io.Writer, v reflect.Value) {
73 | if err := recover(); err != nil {
74 | w.Write(panicBytes)
75 | fmt.Fprintf(w, "%v", err)
76 | w.Write(closeParenBytes)
77 | }
78 | }
79 |
80 | // handleMethods attempts to call the Error and String methods on the underlying
81 | // type the passed reflect.Value represents and outputes the result to Writer w.
82 | //
83 | // It handles panics in any called methods by catching and displaying the error
84 | // as the formatted value.
85 | func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
86 | // We need an interface to check if the type implements the error or
87 | // Stringer interface. However, the reflect package won't give us an
88 | // interface on certain things like unexported struct fields in order
89 | // to enforce visibility rules. We use unsafe, when it's available,
90 | // to bypass these restrictions since this package does not mutate the
91 | // values.
92 | if !v.CanInterface() {
93 | if UnsafeDisabled {
94 | return false
95 | }
96 |
97 | v = unsafeReflectValue(v)
98 | }
99 |
100 | // Choose whether or not to do error and Stringer interface lookups against
101 | // the base type or a pointer to the base type depending on settings.
102 | // Technically calling one of these methods with a pointer receiver can
103 | // mutate the value, however, types which choose to satisify an error or
104 | // Stringer interface with a pointer receiver should not be mutating their
105 | // state inside these interface methods.
106 | if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
107 | v = unsafeReflectValue(v)
108 | }
109 | if v.CanAddr() {
110 | v = v.Addr()
111 | }
112 |
113 | // Is it an error or Stringer?
114 | switch iface := v.Interface().(type) {
115 | case error:
116 | defer catchPanic(w, v)
117 | if cs.ContinueOnMethod {
118 | w.Write(openParenBytes)
119 | w.Write([]byte(iface.Error()))
120 | w.Write(closeParenBytes)
121 | w.Write(spaceBytes)
122 | return false
123 | }
124 |
125 | w.Write([]byte(iface.Error()))
126 | return true
127 |
128 | case fmt.Stringer:
129 | defer catchPanic(w, v)
130 | if cs.ContinueOnMethod {
131 | w.Write(openParenBytes)
132 | w.Write([]byte(iface.String()))
133 | w.Write(closeParenBytes)
134 | w.Write(spaceBytes)
135 | return false
136 | }
137 | w.Write([]byte(iface.String()))
138 | return true
139 | }
140 | return false
141 | }
142 |
143 | // printBool outputs a boolean value as true or false to Writer w.
144 | func printBool(w io.Writer, val bool) {
145 | if val {
146 | w.Write(trueBytes)
147 | } else {
148 | w.Write(falseBytes)
149 | }
150 | }
151 |
152 | // printInt outputs a signed integer value to Writer w.
153 | func printInt(w io.Writer, val int64, base int) {
154 | w.Write([]byte(strconv.FormatInt(val, base)))
155 | }
156 |
157 | // printUint outputs an unsigned integer value to Writer w.
158 | func printUint(w io.Writer, val uint64, base int) {
159 | w.Write([]byte(strconv.FormatUint(val, base)))
160 | }
161 |
162 | // printFloat outputs a floating point value using the specified precision,
163 | // which is expected to be 32 or 64bit, to Writer w.
164 | func printFloat(w io.Writer, val float64, precision int) {
165 | w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
166 | }
167 |
168 | // printComplex outputs a complex value using the specified float precision
169 | // for the real and imaginary parts to Writer w.
170 | func printComplex(w io.Writer, c complex128, floatPrecision int) {
171 | r := real(c)
172 | w.Write(openParenBytes)
173 | w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
174 | i := imag(c)
175 | if i >= 0 {
176 | w.Write(plusBytes)
177 | }
178 | w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
179 | w.Write(iBytes)
180 | w.Write(closeParenBytes)
181 | }
182 |
183 | // printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
184 | // prefix to Writer w.
185 | func printHexPtr(w io.Writer, p uintptr) {
186 | // Null pointer.
187 | num := uint64(p)
188 | if num == 0 {
189 | w.Write(nilAngleBytes)
190 | return
191 | }
192 |
193 | // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
194 | buf := make([]byte, 18)
195 |
196 | // It's simpler to construct the hex string right to left.
197 | base := uint64(16)
198 | i := len(buf) - 1
199 | for num >= base {
200 | buf[i] = hexDigits[num%base]
201 | num /= base
202 | i--
203 | }
204 | buf[i] = hexDigits[num]
205 |
206 | // Add '0x' prefix.
207 | i--
208 | buf[i] = 'x'
209 | i--
210 | buf[i] = '0'
211 |
212 | // Strip unused leading bytes.
213 | buf = buf[i:]
214 | w.Write(buf)
215 | }
216 |
217 | // valuesSorter implements sort.Interface to allow a slice of reflect.Value
218 | // elements to be sorted.
219 | type valuesSorter struct {
220 | values []reflect.Value
221 | strings []string // either nil or same len and values
222 | cs *ConfigState
223 | }
224 |
225 | // newValuesSorter initializes a valuesSorter instance, which holds a set of
226 | // surrogate keys on which the data should be sorted. It uses flags in
227 | // ConfigState to decide if and how to populate those surrogate keys.
228 | func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
229 | vs := &valuesSorter{values: values, cs: cs}
230 | if canSortSimply(vs.values[0].Kind()) {
231 | return vs
232 | }
233 | if !cs.DisableMethods {
234 | vs.strings = make([]string, len(values))
235 | for i := range vs.values {
236 | b := bytes.Buffer{}
237 | if !handleMethods(cs, &b, vs.values[i]) {
238 | vs.strings = nil
239 | break
240 | }
241 | vs.strings[i] = b.String()
242 | }
243 | }
244 | if vs.strings == nil && cs.SpewKeys {
245 | vs.strings = make([]string, len(values))
246 | for i := range vs.values {
247 | vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
248 | }
249 | }
250 | return vs
251 | }
252 |
253 | // canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
254 | // directly, or whether it should be considered for sorting by surrogate keys
255 | // (if the ConfigState allows it).
256 | func canSortSimply(kind reflect.Kind) bool {
257 | // This switch parallels valueSortLess, except for the default case.
258 | switch kind {
259 | case reflect.Bool:
260 | return true
261 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
262 | return true
263 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
264 | return true
265 | case reflect.Float32, reflect.Float64:
266 | return true
267 | case reflect.String:
268 | return true
269 | case reflect.Uintptr:
270 | return true
271 | case reflect.Array:
272 | return true
273 | }
274 | return false
275 | }
276 |
277 | // Len returns the number of values in the slice. It is part of the
278 | // sort.Interface implementation.
279 | func (s *valuesSorter) Len() int {
280 | return len(s.values)
281 | }
282 |
283 | // Swap swaps the values at the passed indices. It is part of the
284 | // sort.Interface implementation.
285 | func (s *valuesSorter) Swap(i, j int) {
286 | s.values[i], s.values[j] = s.values[j], s.values[i]
287 | if s.strings != nil {
288 | s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
289 | }
290 | }
291 |
292 | // valueSortLess returns whether the first value should sort before the second
293 | // value. It is used by valueSorter.Less as part of the sort.Interface
294 | // implementation.
295 | func valueSortLess(a, b reflect.Value) bool {
296 | switch a.Kind() {
297 | case reflect.Bool:
298 | return !a.Bool() && b.Bool()
299 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
300 | return a.Int() < b.Int()
301 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
302 | return a.Uint() < b.Uint()
303 | case reflect.Float32, reflect.Float64:
304 | return a.Float() < b.Float()
305 | case reflect.String:
306 | return a.String() < b.String()
307 | case reflect.Uintptr:
308 | return a.Uint() < b.Uint()
309 | case reflect.Array:
310 | // Compare the contents of both arrays.
311 | l := a.Len()
312 | for i := 0; i < l; i++ {
313 | av := a.Index(i)
314 | bv := b.Index(i)
315 | if av.Interface() == bv.Interface() {
316 | continue
317 | }
318 | return valueSortLess(av, bv)
319 | }
320 | }
321 | return a.String() < b.String()
322 | }
323 |
324 | // Less returns whether the value at index i should sort before the
325 | // value at index j. It is part of the sort.Interface implementation.
326 | func (s *valuesSorter) Less(i, j int) bool {
327 | if s.strings == nil {
328 | return valueSortLess(s.values[i], s.values[j])
329 | }
330 | return s.strings[i] < s.strings[j]
331 | }
332 |
333 | // sortValues is a sort function that handles both native types and any type that
334 | // can be converted to error or Stringer. Other inputs are sorted according to
335 | // their Value.String() value to ensure display stability.
336 | func sortValues(values []reflect.Value, cs *ConfigState) {
337 | if len(values) == 0 {
338 | return
339 | }
340 | sort.Sort(newValuesSorter(values, cs))
341 | }
342 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/config.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Dave Collins
3 | *
4 | * Permission to use, copy, modify, and distribute this software for any
5 | * purpose with or without fee is hereby granted, provided that the above
6 | * copyright notice and this permission notice appear in all copies.
7 | *
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 | */
16 |
17 | package spew
18 |
19 | import (
20 | "bytes"
21 | "fmt"
22 | "io"
23 | "os"
24 | )
25 |
26 | // ConfigState houses the configuration options used by spew to format and
27 | // display values. There is a global instance, Config, that is used to control
28 | // all top-level Formatter and Dump functionality. Each ConfigState instance
29 | // provides methods equivalent to the top-level functions.
30 | //
31 | // The zero value for ConfigState provides no indentation. You would typically
32 | // want to set it to a space or a tab.
33 | //
34 | // Alternatively, you can use NewDefaultConfig to get a ConfigState instance
35 | // with default settings. See the documentation of NewDefaultConfig for default
36 | // values.
37 | type ConfigState struct {
38 | // Indent specifies the string to use for each indentation level. The
39 | // global config instance that all top-level functions use set this to a
40 | // single space by default. If you would like more indentation, you might
41 | // set this to a tab with "\t" or perhaps two spaces with " ".
42 | Indent string
43 |
44 | // MaxDepth controls the maximum number of levels to descend into nested
45 | // data structures. The default, 0, means there is no limit.
46 | //
47 | // NOTE: Circular data structures are properly detected, so it is not
48 | // necessary to set this value unless you specifically want to limit deeply
49 | // nested data structures.
50 | MaxDepth int
51 |
52 | // DisableMethods specifies whether or not error and Stringer interfaces are
53 | // invoked for types that implement them.
54 | DisableMethods bool
55 |
56 | // DisablePointerMethods specifies whether or not to check for and invoke
57 | // error and Stringer interfaces on types which only accept a pointer
58 | // receiver when the current type is not a pointer.
59 | //
60 | // NOTE: This might be an unsafe action since calling one of these methods
61 | // with a pointer receiver could technically mutate the value, however,
62 | // in practice, types which choose to satisify an error or Stringer
63 | // interface with a pointer receiver should not be mutating their state
64 | // inside these interface methods. As a result, this option relies on
65 | // access to the unsafe package, so it will not have any effect when
66 | // running in environments without access to the unsafe package such as
67 | // Google App Engine or with the "safe" build tag specified.
68 | DisablePointerMethods bool
69 |
70 | // DisablePointerAddresses specifies whether to disable the printing of
71 | // pointer addresses. This is useful when diffing data structures in tests.
72 | DisablePointerAddresses bool
73 |
74 | // DisableCapacities specifies whether to disable the printing of capacities
75 | // for arrays, slices, maps and channels. This is useful when diffing
76 | // data structures in tests.
77 | DisableCapacities bool
78 |
79 | // ContinueOnMethod specifies whether or not recursion should continue once
80 | // a custom error or Stringer interface is invoked. The default, false,
81 | // means it will print the results of invoking the custom error or Stringer
82 | // interface and return immediately instead of continuing to recurse into
83 | // the internals of the data type.
84 | //
85 | // NOTE: This flag does not have any effect if method invocation is disabled
86 | // via the DisableMethods or DisablePointerMethods options.
87 | ContinueOnMethod bool
88 |
89 | // SortKeys specifies map keys should be sorted before being printed. Use
90 | // this to have a more deterministic, diffable output. Note that only
91 | // native types (bool, int, uint, floats, uintptr and string) and types
92 | // that support the error or Stringer interfaces (if methods are
93 | // enabled) are supported, with other types sorted according to the
94 | // reflect.Value.String() output which guarantees display stability.
95 | SortKeys bool
96 |
97 | // SpewKeys specifies that, as a last resort attempt, map keys should
98 | // be spewed to strings and sorted by those strings. This is only
99 | // considered if SortKeys is true.
100 | SpewKeys bool
101 | }
102 |
103 | // Config is the active configuration of the top-level functions.
104 | // The configuration can be changed by modifying the contents of spew.Config.
105 | var Config = ConfigState{Indent: " "}
106 |
107 | // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
108 | // passed with a Formatter interface returned by c.NewFormatter. It returns
109 | // the formatted string as a value that satisfies error. See NewFormatter
110 | // for formatting details.
111 | //
112 | // This function is shorthand for the following syntax:
113 | //
114 | // fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
115 | func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
116 | return fmt.Errorf(format, c.convertArgs(a)...)
117 | }
118 |
119 | // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
120 | // passed with a Formatter interface returned by c.NewFormatter. It returns
121 | // the number of bytes written and any write error encountered. See
122 | // NewFormatter for formatting details.
123 | //
124 | // This function is shorthand for the following syntax:
125 | //
126 | // fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
127 | func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
128 | return fmt.Fprint(w, c.convertArgs(a)...)
129 | }
130 |
131 | // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
132 | // passed with a Formatter interface returned by c.NewFormatter. It returns
133 | // the number of bytes written and any write error encountered. See
134 | // NewFormatter for formatting details.
135 | //
136 | // This function is shorthand for the following syntax:
137 | //
138 | // fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
139 | func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
140 | return fmt.Fprintf(w, format, c.convertArgs(a)...)
141 | }
142 |
143 | // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
144 | // passed with a Formatter interface returned by c.NewFormatter. See
145 | // NewFormatter for formatting details.
146 | //
147 | // This function is shorthand for the following syntax:
148 | //
149 | // fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
150 | func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
151 | return fmt.Fprintln(w, c.convertArgs(a)...)
152 | }
153 |
154 | // Print is a wrapper for fmt.Print that treats each argument as if it were
155 | // passed with a Formatter interface returned by c.NewFormatter. It returns
156 | // the number of bytes written and any write error encountered. See
157 | // NewFormatter for formatting details.
158 | //
159 | // This function is shorthand for the following syntax:
160 | //
161 | // fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
162 | func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
163 | return fmt.Print(c.convertArgs(a)...)
164 | }
165 |
166 | // Printf is a wrapper for fmt.Printf that treats each argument as if it were
167 | // passed with a Formatter interface returned by c.NewFormatter. It returns
168 | // the number of bytes written and any write error encountered. See
169 | // NewFormatter for formatting details.
170 | //
171 | // This function is shorthand for the following syntax:
172 | //
173 | // fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
174 | func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
175 | return fmt.Printf(format, c.convertArgs(a)...)
176 | }
177 |
178 | // Println is a wrapper for fmt.Println that treats each argument as if it were
179 | // passed with a Formatter interface returned by c.NewFormatter. It returns
180 | // the number of bytes written and any write error encountered. See
181 | // NewFormatter for formatting details.
182 | //
183 | // This function is shorthand for the following syntax:
184 | //
185 | // fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
186 | func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
187 | return fmt.Println(c.convertArgs(a)...)
188 | }
189 |
190 | // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
191 | // passed with a Formatter interface returned by c.NewFormatter. It returns
192 | // the resulting string. See NewFormatter for formatting details.
193 | //
194 | // This function is shorthand for the following syntax:
195 | //
196 | // fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
197 | func (c *ConfigState) Sprint(a ...interface{}) string {
198 | return fmt.Sprint(c.convertArgs(a)...)
199 | }
200 |
201 | // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
202 | // passed with a Formatter interface returned by c.NewFormatter. It returns
203 | // the resulting string. See NewFormatter for formatting details.
204 | //
205 | // This function is shorthand for the following syntax:
206 | //
207 | // fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
208 | func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
209 | return fmt.Sprintf(format, c.convertArgs(a)...)
210 | }
211 |
212 | // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
213 | // were passed with a Formatter interface returned by c.NewFormatter. It
214 | // returns the resulting string. See NewFormatter for formatting details.
215 | //
216 | // This function is shorthand for the following syntax:
217 | //
218 | // fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
219 | func (c *ConfigState) Sprintln(a ...interface{}) string {
220 | return fmt.Sprintln(c.convertArgs(a)...)
221 | }
222 |
223 | /*
224 | NewFormatter returns a custom formatter that satisfies the fmt.Formatter
225 | interface. As a result, it integrates cleanly with standard fmt package
226 | printing functions. The formatter is useful for inline printing of smaller data
227 | types similar to the standard %v format specifier.
228 |
229 | The custom formatter only responds to the %v (most compact), %+v (adds pointer
230 | addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
231 | combinations. Any other verbs such as %x and %q will be sent to the the
232 | standard fmt package for formatting. In addition, the custom formatter ignores
233 | the width and precision arguments (however they will still work on the format
234 | specifiers not handled by the custom formatter).
235 |
236 | Typically this function shouldn't be called directly. It is much easier to make
237 | use of the custom formatter by calling one of the convenience functions such as
238 | c.Printf, c.Println, or c.Printf.
239 | */
240 | func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
241 | return newFormatter(c, v)
242 | }
243 |
244 | // Fdump formats and displays the passed arguments to io.Writer w. It formats
245 | // exactly the same as Dump.
246 | func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
247 | fdump(c, w, a...)
248 | }
249 |
250 | /*
251 | Dump displays the passed parameters to standard out with newlines, customizable
252 | indentation, and additional debug information such as complete types and all
253 | pointer addresses used to indirect to the final value. It provides the
254 | following features over the built-in printing facilities provided by the fmt
255 | package:
256 |
257 | * Pointers are dereferenced and followed
258 | * Circular data structures are detected and handled properly
259 | * Custom Stringer/error interfaces are optionally invoked, including
260 | on unexported types
261 | * Custom types which only implement the Stringer/error interfaces via
262 | a pointer receiver are optionally invoked when passing non-pointer
263 | variables
264 | * Byte arrays and slices are dumped like the hexdump -C command which
265 | includes offsets, byte values in hex, and ASCII output
266 |
267 | The configuration options are controlled by modifying the public members
268 | of c. See ConfigState for options documentation.
269 |
270 | See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
271 | get the formatted result as a string.
272 | */
273 | func (c *ConfigState) Dump(a ...interface{}) {
274 | fdump(c, os.Stdout, a...)
275 | }
276 |
277 | // Sdump returns a string with the passed arguments formatted exactly the same
278 | // as Dump.
279 | func (c *ConfigState) Sdump(a ...interface{}) string {
280 | var buf bytes.Buffer
281 | fdump(c, &buf, a...)
282 | return buf.String()
283 | }
284 |
285 | // convertArgs accepts a slice of arguments and returns a slice of the same
286 | // length with each argument converted to a spew Formatter interface using
287 | // the ConfigState associated with s.
288 | func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
289 | formatters = make([]interface{}, len(args))
290 | for index, arg := range args {
291 | formatters[index] = newFormatter(c, arg)
292 | }
293 | return formatters
294 | }
295 |
296 | // NewDefaultConfig returns a ConfigState with the following default settings.
297 | //
298 | // Indent: " "
299 | // MaxDepth: 0
300 | // DisableMethods: false
301 | // DisablePointerMethods: false
302 | // ContinueOnMethod: false
303 | // SortKeys: false
304 | func NewDefaultConfig() *ConfigState {
305 | return &ConfigState{Indent: " "}
306 | }
307 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Dave Collins
3 | *
4 | * Permission to use, copy, modify, and distribute this software for any
5 | * purpose with or without fee is hereby granted, provided that the above
6 | * copyright notice and this permission notice appear in all copies.
7 | *
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 | */
16 |
17 | /*
18 | Package spew implements a deep pretty printer for Go data structures to aid in
19 | debugging.
20 |
21 | A quick overview of the additional features spew provides over the built-in
22 | printing facilities for Go data types are as follows:
23 |
24 | * Pointers are dereferenced and followed
25 | * Circular data structures are detected and handled properly
26 | * Custom Stringer/error interfaces are optionally invoked, including
27 | on unexported types
28 | * Custom types which only implement the Stringer/error interfaces via
29 | a pointer receiver are optionally invoked when passing non-pointer
30 | variables
31 | * Byte arrays and slices are dumped like the hexdump -C command which
32 | includes offsets, byte values in hex, and ASCII output (only when using
33 | Dump style)
34 |
35 | There are two different approaches spew allows for dumping Go data structures:
36 |
37 | * Dump style which prints with newlines, customizable indentation,
38 | and additional debug information such as types and all pointer addresses
39 | used to indirect to the final value
40 | * A custom Formatter interface that integrates cleanly with the standard fmt
41 | package and replaces %v, %+v, %#v, and %#+v to provide inline printing
42 | similar to the default %v while providing the additional functionality
43 | outlined above and passing unsupported format verbs such as %x and %q
44 | along to fmt
45 |
46 | Quick Start
47 |
48 | This section demonstrates how to quickly get started with spew. See the
49 | sections below for further details on formatting and configuration options.
50 |
51 | To dump a variable with full newlines, indentation, type, and pointer
52 | information use Dump, Fdump, or Sdump:
53 | spew.Dump(myVar1, myVar2, ...)
54 | spew.Fdump(someWriter, myVar1, myVar2, ...)
55 | str := spew.Sdump(myVar1, myVar2, ...)
56 |
57 | Alternatively, if you would prefer to use format strings with a compacted inline
58 | printing style, use the convenience wrappers Printf, Fprintf, etc with
59 | %v (most compact), %+v (adds pointer addresses), %#v (adds types), or
60 | %#+v (adds types and pointer addresses):
61 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
62 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
63 | spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
64 | spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
65 |
66 | Configuration Options
67 |
68 | Configuration of spew is handled by fields in the ConfigState type. For
69 | convenience, all of the top-level functions use a global state available
70 | via the spew.Config global.
71 |
72 | It is also possible to create a ConfigState instance that provides methods
73 | equivalent to the top-level functions. This allows concurrent configuration
74 | options. See the ConfigState documentation for more details.
75 |
76 | The following configuration options are available:
77 | * Indent
78 | String to use for each indentation level for Dump functions.
79 | It is a single space by default. A popular alternative is "\t".
80 |
81 | * MaxDepth
82 | Maximum number of levels to descend into nested data structures.
83 | There is no limit by default.
84 |
85 | * DisableMethods
86 | Disables invocation of error and Stringer interface methods.
87 | Method invocation is enabled by default.
88 |
89 | * DisablePointerMethods
90 | Disables invocation of error and Stringer interface methods on types
91 | which only accept pointer receivers from non-pointer variables.
92 | Pointer method invocation is enabled by default.
93 |
94 | * ContinueOnMethod
95 | Enables recursion into types after invoking error and Stringer interface
96 | methods. Recursion after method invocation is disabled by default.
97 |
98 | * SortKeys
99 | Specifies map keys should be sorted before being printed. Use
100 | this to have a more deterministic, diffable output. Note that
101 | only native types (bool, int, uint, floats, uintptr and string)
102 | and types which implement error or Stringer interfaces are
103 | supported with other types sorted according to the
104 | reflect.Value.String() output which guarantees display
105 | stability. Natural map order is used by default.
106 |
107 | * SpewKeys
108 | Specifies that, as a last resort attempt, map keys should be
109 | spewed to strings and sorted by those strings. This is only
110 | considered if SortKeys is true.
111 |
112 | Dump Usage
113 |
114 | Simply call spew.Dump with a list of variables you want to dump:
115 |
116 | spew.Dump(myVar1, myVar2, ...)
117 |
118 | You may also call spew.Fdump if you would prefer to output to an arbitrary
119 | io.Writer. For example, to dump to standard error:
120 |
121 | spew.Fdump(os.Stderr, myVar1, myVar2, ...)
122 |
123 | A third option is to call spew.Sdump to get the formatted output as a string:
124 |
125 | str := spew.Sdump(myVar1, myVar2, ...)
126 |
127 | Sample Dump Output
128 |
129 | See the Dump example for details on the setup of the types and variables being
130 | shown here.
131 |
132 | (main.Foo) {
133 | unexportedField: (*main.Bar)(0xf84002e210)({
134 | flag: (main.Flag) flagTwo,
135 | data: (uintptr)
136 | }),
137 | ExportedField: (map[interface {}]interface {}) (len=1) {
138 | (string) (len=3) "one": (bool) true
139 | }
140 | }
141 |
142 | Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
143 | command as shown.
144 | ([]uint8) (len=32 cap=32) {
145 | 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
146 | 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
147 | 00000020 31 32 |12|
148 | }
149 |
150 | Custom Formatter
151 |
152 | Spew provides a custom formatter that implements the fmt.Formatter interface
153 | so that it integrates cleanly with standard fmt package printing functions. The
154 | formatter is useful for inline printing of smaller data types similar to the
155 | standard %v format specifier.
156 |
157 | The custom formatter only responds to the %v (most compact), %+v (adds pointer
158 | addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
159 | combinations. Any other verbs such as %x and %q will be sent to the the
160 | standard fmt package for formatting. In addition, the custom formatter ignores
161 | the width and precision arguments (however they will still work on the format
162 | specifiers not handled by the custom formatter).
163 |
164 | Custom Formatter Usage
165 |
166 | The simplest way to make use of the spew custom formatter is to call one of the
167 | convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
168 | functions have syntax you are most likely already familiar with:
169 |
170 | spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
171 | spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
172 | spew.Println(myVar, myVar2)
173 | spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
174 | spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
175 |
176 | See the Index for the full list convenience functions.
177 |
178 | Sample Formatter Output
179 |
180 | Double pointer to a uint8:
181 | %v: <**>5
182 | %+v: <**>(0xf8400420d0->0xf8400420c8)5
183 | %#v: (**uint8)5
184 | %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
185 |
186 | Pointer to circular struct with a uint8 field and a pointer to itself:
187 | %v: <*>{1 <*>}
188 | %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)}
189 | %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)}
190 | %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)}
191 |
192 | See the Printf example for details on the setup of variables being shown
193 | here.
194 |
195 | Errors
196 |
197 | Since it is possible for custom Stringer/error interfaces to panic, spew
198 | detects them and handles them internally by printing the panic information
199 | inline with the output. Since spew is intended to provide deep pretty printing
200 | capabilities on structures, it intentionally does not return any errors.
201 | */
202 | package spew
203 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Dave Collins
3 | *
4 | * Permission to use, copy, modify, and distribute this software for any
5 | * purpose with or without fee is hereby granted, provided that the above
6 | * copyright notice and this permission notice appear in all copies.
7 | *
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 | */
16 |
17 | package spew
18 |
19 | import (
20 | "bytes"
21 | "fmt"
22 | "reflect"
23 | "strconv"
24 | "strings"
25 | )
26 |
27 | // supportedFlags is a list of all the character flags supported by fmt package.
28 | const supportedFlags = "0-+# "
29 |
30 | // formatState implements the fmt.Formatter interface and contains information
31 | // about the state of a formatting operation. The NewFormatter function can
32 | // be used to get a new Formatter which can be used directly as arguments
33 | // in standard fmt package printing calls.
34 | type formatState struct {
35 | value interface{}
36 | fs fmt.State
37 | depth int
38 | pointers map[uintptr]int
39 | ignoreNextType bool
40 | cs *ConfigState
41 | }
42 |
43 | // buildDefaultFormat recreates the original format string without precision
44 | // and width information to pass in to fmt.Sprintf in the case of an
45 | // unrecognized type. Unless new types are added to the language, this
46 | // function won't ever be called.
47 | func (f *formatState) buildDefaultFormat() (format string) {
48 | buf := bytes.NewBuffer(percentBytes)
49 |
50 | for _, flag := range supportedFlags {
51 | if f.fs.Flag(int(flag)) {
52 | buf.WriteRune(flag)
53 | }
54 | }
55 |
56 | buf.WriteRune('v')
57 |
58 | format = buf.String()
59 | return format
60 | }
61 |
62 | // constructOrigFormat recreates the original format string including precision
63 | // and width information to pass along to the standard fmt package. This allows
64 | // automatic deferral of all format strings this package doesn't support.
65 | func (f *formatState) constructOrigFormat(verb rune) (format string) {
66 | buf := bytes.NewBuffer(percentBytes)
67 |
68 | for _, flag := range supportedFlags {
69 | if f.fs.Flag(int(flag)) {
70 | buf.WriteRune(flag)
71 | }
72 | }
73 |
74 | if width, ok := f.fs.Width(); ok {
75 | buf.WriteString(strconv.Itoa(width))
76 | }
77 |
78 | if precision, ok := f.fs.Precision(); ok {
79 | buf.Write(precisionBytes)
80 | buf.WriteString(strconv.Itoa(precision))
81 | }
82 |
83 | buf.WriteRune(verb)
84 |
85 | format = buf.String()
86 | return format
87 | }
88 |
89 | // unpackValue returns values inside of non-nil interfaces when possible and
90 | // ensures that types for values which have been unpacked from an interface
91 | // are displayed when the show types flag is also set.
92 | // This is useful for data types like structs, arrays, slices, and maps which
93 | // can contain varying types packed inside an interface.
94 | func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
95 | if v.Kind() == reflect.Interface {
96 | f.ignoreNextType = false
97 | if !v.IsNil() {
98 | v = v.Elem()
99 | }
100 | }
101 | return v
102 | }
103 |
104 | // formatPtr handles formatting of pointers by indirecting them as necessary.
105 | func (f *formatState) formatPtr(v reflect.Value) {
106 | // Display nil if top level pointer is nil.
107 | showTypes := f.fs.Flag('#')
108 | if v.IsNil() && (!showTypes || f.ignoreNextType) {
109 | f.fs.Write(nilAngleBytes)
110 | return
111 | }
112 |
113 | // Remove pointers at or below the current depth from map used to detect
114 | // circular refs.
115 | for k, depth := range f.pointers {
116 | if depth >= f.depth {
117 | delete(f.pointers, k)
118 | }
119 | }
120 |
121 | // Keep list of all dereferenced pointers to possibly show later.
122 | pointerChain := make([]uintptr, 0)
123 |
124 | // Figure out how many levels of indirection there are by derferencing
125 | // pointers and unpacking interfaces down the chain while detecting circular
126 | // references.
127 | nilFound := false
128 | cycleFound := false
129 | indirects := 0
130 | ve := v
131 | for ve.Kind() == reflect.Ptr {
132 | if ve.IsNil() {
133 | nilFound = true
134 | break
135 | }
136 | indirects++
137 | addr := ve.Pointer()
138 | pointerChain = append(pointerChain, addr)
139 | if pd, ok := f.pointers[addr]; ok && pd < f.depth {
140 | cycleFound = true
141 | indirects--
142 | break
143 | }
144 | f.pointers[addr] = f.depth
145 |
146 | ve = ve.Elem()
147 | if ve.Kind() == reflect.Interface {
148 | if ve.IsNil() {
149 | nilFound = true
150 | break
151 | }
152 | ve = ve.Elem()
153 | }
154 | }
155 |
156 | // Display type or indirection level depending on flags.
157 | if showTypes && !f.ignoreNextType {
158 | f.fs.Write(openParenBytes)
159 | f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
160 | f.fs.Write([]byte(ve.Type().String()))
161 | f.fs.Write(closeParenBytes)
162 | } else {
163 | if nilFound || cycleFound {
164 | indirects += strings.Count(ve.Type().String(), "*")
165 | }
166 | f.fs.Write(openAngleBytes)
167 | f.fs.Write([]byte(strings.Repeat("*", indirects)))
168 | f.fs.Write(closeAngleBytes)
169 | }
170 |
171 | // Display pointer information depending on flags.
172 | if f.fs.Flag('+') && (len(pointerChain) > 0) {
173 | f.fs.Write(openParenBytes)
174 | for i, addr := range pointerChain {
175 | if i > 0 {
176 | f.fs.Write(pointerChainBytes)
177 | }
178 | printHexPtr(f.fs, addr)
179 | }
180 | f.fs.Write(closeParenBytes)
181 | }
182 |
183 | // Display dereferenced value.
184 | switch {
185 | case nilFound == true:
186 | f.fs.Write(nilAngleBytes)
187 |
188 | case cycleFound == true:
189 | f.fs.Write(circularShortBytes)
190 |
191 | default:
192 | f.ignoreNextType = true
193 | f.format(ve)
194 | }
195 | }
196 |
197 | // format is the main workhorse for providing the Formatter interface. It
198 | // uses the passed reflect value to figure out what kind of object we are
199 | // dealing with and formats it appropriately. It is a recursive function,
200 | // however circular data structures are detected and handled properly.
201 | func (f *formatState) format(v reflect.Value) {
202 | // Handle invalid reflect values immediately.
203 | kind := v.Kind()
204 | if kind == reflect.Invalid {
205 | f.fs.Write(invalidAngleBytes)
206 | return
207 | }
208 |
209 | // Handle pointers specially.
210 | if kind == reflect.Ptr {
211 | f.formatPtr(v)
212 | return
213 | }
214 |
215 | // Print type information unless already handled elsewhere.
216 | if !f.ignoreNextType && f.fs.Flag('#') {
217 | f.fs.Write(openParenBytes)
218 | f.fs.Write([]byte(v.Type().String()))
219 | f.fs.Write(closeParenBytes)
220 | }
221 | f.ignoreNextType = false
222 |
223 | // Call Stringer/error interfaces if they exist and the handle methods
224 | // flag is enabled.
225 | if !f.cs.DisableMethods {
226 | if (kind != reflect.Invalid) && (kind != reflect.Interface) {
227 | if handled := handleMethods(f.cs, f.fs, v); handled {
228 | return
229 | }
230 | }
231 | }
232 |
233 | switch kind {
234 | case reflect.Invalid:
235 | // Do nothing. We should never get here since invalid has already
236 | // been handled above.
237 |
238 | case reflect.Bool:
239 | printBool(f.fs, v.Bool())
240 |
241 | case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
242 | printInt(f.fs, v.Int(), 10)
243 |
244 | case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
245 | printUint(f.fs, v.Uint(), 10)
246 |
247 | case reflect.Float32:
248 | printFloat(f.fs, v.Float(), 32)
249 |
250 | case reflect.Float64:
251 | printFloat(f.fs, v.Float(), 64)
252 |
253 | case reflect.Complex64:
254 | printComplex(f.fs, v.Complex(), 32)
255 |
256 | case reflect.Complex128:
257 | printComplex(f.fs, v.Complex(), 64)
258 |
259 | case reflect.Slice:
260 | if v.IsNil() {
261 | f.fs.Write(nilAngleBytes)
262 | break
263 | }
264 | fallthrough
265 |
266 | case reflect.Array:
267 | f.fs.Write(openBracketBytes)
268 | f.depth++
269 | if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
270 | f.fs.Write(maxShortBytes)
271 | } else {
272 | numEntries := v.Len()
273 | for i := 0; i < numEntries; i++ {
274 | if i > 0 {
275 | f.fs.Write(spaceBytes)
276 | }
277 | f.ignoreNextType = true
278 | f.format(f.unpackValue(v.Index(i)))
279 | }
280 | }
281 | f.depth--
282 | f.fs.Write(closeBracketBytes)
283 |
284 | case reflect.String:
285 | f.fs.Write([]byte(v.String()))
286 |
287 | case reflect.Interface:
288 | // The only time we should get here is for nil interfaces due to
289 | // unpackValue calls.
290 | if v.IsNil() {
291 | f.fs.Write(nilAngleBytes)
292 | }
293 |
294 | case reflect.Ptr:
295 | // Do nothing. We should never get here since pointers have already
296 | // been handled above.
297 |
298 | case reflect.Map:
299 | // nil maps should be indicated as different than empty maps
300 | if v.IsNil() {
301 | f.fs.Write(nilAngleBytes)
302 | break
303 | }
304 |
305 | f.fs.Write(openMapBytes)
306 | f.depth++
307 | if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
308 | f.fs.Write(maxShortBytes)
309 | } else {
310 | keys := v.MapKeys()
311 | if f.cs.SortKeys {
312 | sortValues(keys, f.cs)
313 | }
314 | for i, key := range keys {
315 | if i > 0 {
316 | f.fs.Write(spaceBytes)
317 | }
318 | f.ignoreNextType = true
319 | f.format(f.unpackValue(key))
320 | f.fs.Write(colonBytes)
321 | f.ignoreNextType = true
322 | f.format(f.unpackValue(v.MapIndex(key)))
323 | }
324 | }
325 | f.depth--
326 | f.fs.Write(closeMapBytes)
327 |
328 | case reflect.Struct:
329 | numFields := v.NumField()
330 | f.fs.Write(openBraceBytes)
331 | f.depth++
332 | if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
333 | f.fs.Write(maxShortBytes)
334 | } else {
335 | vt := v.Type()
336 | for i := 0; i < numFields; i++ {
337 | if i > 0 {
338 | f.fs.Write(spaceBytes)
339 | }
340 | vtf := vt.Field(i)
341 | if f.fs.Flag('+') || f.fs.Flag('#') {
342 | f.fs.Write([]byte(vtf.Name))
343 | f.fs.Write(colonBytes)
344 | }
345 | f.format(f.unpackValue(v.Field(i)))
346 | }
347 | }
348 | f.depth--
349 | f.fs.Write(closeBraceBytes)
350 |
351 | case reflect.Uintptr:
352 | printHexPtr(f.fs, uintptr(v.Uint()))
353 |
354 | case reflect.UnsafePointer, reflect.Chan, reflect.Func:
355 | printHexPtr(f.fs, v.Pointer())
356 |
357 | // There were not any other types at the time this code was written, but
358 | // fall back to letting the default fmt package handle it if any get added.
359 | default:
360 | format := f.buildDefaultFormat()
361 | if v.CanInterface() {
362 | fmt.Fprintf(f.fs, format, v.Interface())
363 | } else {
364 | fmt.Fprintf(f.fs, format, v.String())
365 | }
366 | }
367 | }
368 |
369 | // Format satisfies the fmt.Formatter interface. See NewFormatter for usage
370 | // details.
371 | func (f *formatState) Format(fs fmt.State, verb rune) {
372 | f.fs = fs
373 |
374 | // Use standard formatting for verbs that are not v.
375 | if verb != 'v' {
376 | format := f.constructOrigFormat(verb)
377 | fmt.Fprintf(fs, format, f.value)
378 | return
379 | }
380 |
381 | if f.value == nil {
382 | if fs.Flag('#') {
383 | fs.Write(interfaceBytes)
384 | }
385 | fs.Write(nilAngleBytes)
386 | return
387 | }
388 |
389 | f.format(reflect.ValueOf(f.value))
390 | }
391 |
392 | // newFormatter is a helper function to consolidate the logic from the various
393 | // public methods which take varying config states.
394 | func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
395 | fs := &formatState{value: v, cs: cs}
396 | fs.pointers = make(map[uintptr]int)
397 | return fs
398 | }
399 |
400 | /*
401 | NewFormatter returns a custom formatter that satisfies the fmt.Formatter
402 | interface. As a result, it integrates cleanly with standard fmt package
403 | printing functions. The formatter is useful for inline printing of smaller data
404 | types similar to the standard %v format specifier.
405 |
406 | The custom formatter only responds to the %v (most compact), %+v (adds pointer
407 | addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
408 | combinations. Any other verbs such as %x and %q will be sent to the the
409 | standard fmt package for formatting. In addition, the custom formatter ignores
410 | the width and precision arguments (however they will still work on the format
411 | specifiers not handled by the custom formatter).
412 |
413 | Typically this function shouldn't be called directly. It is much easier to make
414 | use of the custom formatter by calling one of the convenience functions such as
415 | Printf, Println, or Fprintf.
416 | */
417 | func NewFormatter(v interface{}) fmt.Formatter {
418 | return newFormatter(&Config, v)
419 | }
420 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/spew.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013 Dave Collins
3 | *
4 | * Permission to use, copy, modify, and distribute this software for any
5 | * purpose with or without fee is hereby granted, provided that the above
6 | * copyright notice and this permission notice appear in all copies.
7 | *
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 | */
16 |
17 | package spew
18 |
19 | import (
20 | "fmt"
21 | "io"
22 | )
23 |
24 | // Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
25 | // passed with a default Formatter interface returned by NewFormatter. It
26 | // returns the formatted string as a value that satisfies error. See
27 | // NewFormatter for formatting details.
28 | //
29 | // This function is shorthand for the following syntax:
30 | //
31 | // fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
32 | func Errorf(format string, a ...interface{}) (err error) {
33 | return fmt.Errorf(format, convertArgs(a)...)
34 | }
35 |
36 | // Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
37 | // passed with a default Formatter interface returned by NewFormatter. It
38 | // returns the number of bytes written and any write error encountered. See
39 | // NewFormatter for formatting details.
40 | //
41 | // This function is shorthand for the following syntax:
42 | //
43 | // fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
44 | func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
45 | return fmt.Fprint(w, convertArgs(a)...)
46 | }
47 |
48 | // Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
49 | // passed with a default Formatter interface returned by NewFormatter. It
50 | // returns the number of bytes written and any write error encountered. See
51 | // NewFormatter for formatting details.
52 | //
53 | // This function is shorthand for the following syntax:
54 | //
55 | // fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
56 | func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
57 | return fmt.Fprintf(w, format, convertArgs(a)...)
58 | }
59 |
60 | // Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
61 | // passed with a default Formatter interface returned by NewFormatter. See
62 | // NewFormatter for formatting details.
63 | //
64 | // This function is shorthand for the following syntax:
65 | //
66 | // fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
67 | func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
68 | return fmt.Fprintln(w, convertArgs(a)...)
69 | }
70 |
71 | // Print is a wrapper for fmt.Print that treats each argument as if it were
72 | // passed with a default Formatter interface returned by NewFormatter. It
73 | // returns the number of bytes written and any write error encountered. See
74 | // NewFormatter for formatting details.
75 | //
76 | // This function is shorthand for the following syntax:
77 | //
78 | // fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
79 | func Print(a ...interface{}) (n int, err error) {
80 | return fmt.Print(convertArgs(a)...)
81 | }
82 |
83 | // Printf is a wrapper for fmt.Printf that treats each argument as if it were
84 | // passed with a default Formatter interface returned by NewFormatter. It
85 | // returns the number of bytes written and any write error encountered. See
86 | // NewFormatter for formatting details.
87 | //
88 | // This function is shorthand for the following syntax:
89 | //
90 | // fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
91 | func Printf(format string, a ...interface{}) (n int, err error) {
92 | return fmt.Printf(format, convertArgs(a)...)
93 | }
94 |
95 | // Println is a wrapper for fmt.Println that treats each argument as if it were
96 | // passed with a default Formatter interface returned by NewFormatter. It
97 | // returns the number of bytes written and any write error encountered. See
98 | // NewFormatter for formatting details.
99 | //
100 | // This function is shorthand for the following syntax:
101 | //
102 | // fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
103 | func Println(a ...interface{}) (n int, err error) {
104 | return fmt.Println(convertArgs(a)...)
105 | }
106 |
107 | // Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
108 | // passed with a default Formatter interface returned by NewFormatter. It
109 | // returns the resulting string. See NewFormatter for formatting details.
110 | //
111 | // This function is shorthand for the following syntax:
112 | //
113 | // fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
114 | func Sprint(a ...interface{}) string {
115 | return fmt.Sprint(convertArgs(a)...)
116 | }
117 |
118 | // Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
119 | // passed with a default Formatter interface returned by NewFormatter. It
120 | // returns the resulting string. See NewFormatter for formatting details.
121 | //
122 | // This function is shorthand for the following syntax:
123 | //
124 | // fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
125 | func Sprintf(format string, a ...interface{}) string {
126 | return fmt.Sprintf(format, convertArgs(a)...)
127 | }
128 |
129 | // Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
130 | // were passed with a default Formatter interface returned by NewFormatter. It
131 | // returns the resulting string. See NewFormatter for formatting details.
132 | //
133 | // This function is shorthand for the following syntax:
134 | //
135 | // fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
136 | func Sprintln(a ...interface{}) string {
137 | return fmt.Sprintln(convertArgs(a)...)
138 | }
139 |
140 | // convertArgs accepts a slice of arguments and returns a slice of the same
141 | // length with each argument converted to a default spew Formatter interface.
142 | func convertArgs(args []interface{}) (formatters []interface{}) {
143 | formatters = make([]interface{}, len(args))
144 | for index, arg := range args {
145 | formatters[index] = NewFormatter(arg)
146 | }
147 | return formatters
148 | }
149 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/accessors.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "fmt"
5 | "regexp"
6 | "strconv"
7 | "strings"
8 | )
9 |
10 | // arrayAccesRegexString is the regex used to extract the array number
11 | // from the access path
12 | const arrayAccesRegexString = `^(.+)\[([0-9]+)\]$`
13 |
14 | // arrayAccesRegex is the compiled arrayAccesRegexString
15 | var arrayAccesRegex = regexp.MustCompile(arrayAccesRegexString)
16 |
17 | // Get gets the value using the specified selector and
18 | // returns it inside a new Obj object.
19 | //
20 | // If it cannot find the value, Get will return a nil
21 | // value inside an instance of Obj.
22 | //
23 | // Get can only operate directly on map[string]interface{} and []interface.
24 | //
25 | // Example
26 | //
27 | // To access the title of the third chapter of the second book, do:
28 | //
29 | // o.Get("books[1].chapters[2].title")
30 | func (m Map) Get(selector string) *Value {
31 | rawObj := access(m, selector, nil, false, false)
32 | return &Value{data: rawObj}
33 | }
34 |
35 | // Set sets the value using the specified selector and
36 | // returns the object on which Set was called.
37 | //
38 | // Set can only operate directly on map[string]interface{} and []interface
39 | //
40 | // Example
41 | //
42 | // To set the title of the third chapter of the second book, do:
43 | //
44 | // o.Set("books[1].chapters[2].title","Time to Go")
45 | func (m Map) Set(selector string, value interface{}) Map {
46 | access(m, selector, value, true, false)
47 | return m
48 | }
49 |
50 | // access accesses the object using the selector and performs the
51 | // appropriate action.
52 | func access(current, selector, value interface{}, isSet, panics bool) interface{} {
53 |
54 | switch selector.(type) {
55 | case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
56 |
57 | if array, ok := current.([]interface{}); ok {
58 | index := intFromInterface(selector)
59 |
60 | if index >= len(array) {
61 | if panics {
62 | panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
63 | }
64 | return nil
65 | }
66 |
67 | return array[index]
68 | }
69 |
70 | return nil
71 |
72 | case string:
73 |
74 | selStr := selector.(string)
75 | selSegs := strings.SplitN(selStr, PathSeparator, 2)
76 | thisSel := selSegs[0]
77 | index := -1
78 | var err error
79 |
80 | // https://github.com/stretchr/objx/issues/12
81 | if strings.Contains(thisSel, "[") {
82 |
83 | arrayMatches := arrayAccesRegex.FindStringSubmatch(thisSel)
84 |
85 | if len(arrayMatches) > 0 {
86 |
87 | // Get the key into the map
88 | thisSel = arrayMatches[1]
89 |
90 | // Get the index into the array at the key
91 | index, err = strconv.Atoi(arrayMatches[2])
92 |
93 | if err != nil {
94 | // This should never happen. If it does, something has gone
95 | // seriously wrong. Panic.
96 | panic("objx: Array index is not an integer. Must use array[int].")
97 | }
98 |
99 | }
100 | }
101 |
102 | if curMap, ok := current.(Map); ok {
103 | current = map[string]interface{}(curMap)
104 | }
105 |
106 | // get the object in question
107 | switch current.(type) {
108 | case map[string]interface{}:
109 | curMSI := current.(map[string]interface{})
110 | if len(selSegs) <= 1 && isSet {
111 | curMSI[thisSel] = value
112 | return nil
113 | } else {
114 | current = curMSI[thisSel]
115 | }
116 | default:
117 | current = nil
118 | }
119 |
120 | if current == nil && panics {
121 | panic(fmt.Sprintf("objx: '%v' invalid on object.", selector))
122 | }
123 |
124 | // do we need to access the item of an array?
125 | if index > -1 {
126 | if array, ok := current.([]interface{}); ok {
127 | if index < len(array) {
128 | current = array[index]
129 | } else {
130 | if panics {
131 | panic(fmt.Sprintf("objx: Index %d is out of range. Slice only contains %d items.", index, len(array)))
132 | }
133 | current = nil
134 | }
135 | }
136 | }
137 |
138 | if len(selSegs) > 1 {
139 | current = access(current, selSegs[1], value, isSet, panics)
140 | }
141 |
142 | }
143 |
144 | return current
145 |
146 | }
147 |
148 | // intFromInterface converts an interface object to the largest
149 | // representation of an unsigned integer using a type switch and
150 | // assertions
151 | func intFromInterface(selector interface{}) int {
152 | var value int
153 | switch selector.(type) {
154 | case int:
155 | value = selector.(int)
156 | case int8:
157 | value = int(selector.(int8))
158 | case int16:
159 | value = int(selector.(int16))
160 | case int32:
161 | value = int(selector.(int32))
162 | case int64:
163 | value = int(selector.(int64))
164 | case uint:
165 | value = int(selector.(uint))
166 | case uint8:
167 | value = int(selector.(uint8))
168 | case uint16:
169 | value = int(selector.(uint16))
170 | case uint32:
171 | value = int(selector.(uint32))
172 | case uint64:
173 | value = int(selector.(uint64))
174 | default:
175 | panic("objx: array access argument is not an integer type (this should never happen)")
176 | }
177 |
178 | return value
179 | }
180 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/constants.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | const (
4 | // PathSeparator is the character used to separate the elements
5 | // of the keypath.
6 | //
7 | // For example, `location.address.city`
8 | PathSeparator string = "."
9 |
10 | // SignatureSeparator is the character that is used to
11 | // separate the Base64 string from the security signature.
12 | SignatureSeparator = "_"
13 | )
14 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/conversions.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "bytes"
5 | "encoding/base64"
6 | "encoding/json"
7 | "errors"
8 | "fmt"
9 | "net/url"
10 | )
11 |
12 | // JSON converts the contained object to a JSON string
13 | // representation
14 | func (m Map) JSON() (string, error) {
15 |
16 | result, err := json.Marshal(m)
17 |
18 | if err != nil {
19 | err = errors.New("objx: JSON encode failed with: " + err.Error())
20 | }
21 |
22 | return string(result), err
23 |
24 | }
25 |
26 | // MustJSON converts the contained object to a JSON string
27 | // representation and panics if there is an error
28 | func (m Map) MustJSON() string {
29 | result, err := m.JSON()
30 | if err != nil {
31 | panic(err.Error())
32 | }
33 | return result
34 | }
35 |
36 | // Base64 converts the contained object to a Base64 string
37 | // representation of the JSON string representation
38 | func (m Map) Base64() (string, error) {
39 |
40 | var buf bytes.Buffer
41 |
42 | jsonData, err := m.JSON()
43 | if err != nil {
44 | return "", err
45 | }
46 |
47 | encoder := base64.NewEncoder(base64.StdEncoding, &buf)
48 | encoder.Write([]byte(jsonData))
49 | encoder.Close()
50 |
51 | return buf.String(), nil
52 |
53 | }
54 |
55 | // MustBase64 converts the contained object to a Base64 string
56 | // representation of the JSON string representation and panics
57 | // if there is an error
58 | func (m Map) MustBase64() string {
59 | result, err := m.Base64()
60 | if err != nil {
61 | panic(err.Error())
62 | }
63 | return result
64 | }
65 |
66 | // SignedBase64 converts the contained object to a Base64 string
67 | // representation of the JSON string representation and signs it
68 | // using the provided key.
69 | func (m Map) SignedBase64(key string) (string, error) {
70 |
71 | base64, err := m.Base64()
72 | if err != nil {
73 | return "", err
74 | }
75 |
76 | sig := HashWithKey(base64, key)
77 |
78 | return base64 + SignatureSeparator + sig, nil
79 |
80 | }
81 |
82 | // MustSignedBase64 converts the contained object to a Base64 string
83 | // representation of the JSON string representation and signs it
84 | // using the provided key and panics if there is an error
85 | func (m Map) MustSignedBase64(key string) string {
86 | result, err := m.SignedBase64(key)
87 | if err != nil {
88 | panic(err.Error())
89 | }
90 | return result
91 | }
92 |
93 | /*
94 | URL Query
95 | ------------------------------------------------
96 | */
97 |
98 | // URLValues creates a url.Values object from an Obj. This
99 | // function requires that the wrapped object be a map[string]interface{}
100 | func (m Map) URLValues() url.Values {
101 |
102 | vals := make(url.Values)
103 |
104 | for k, v := range m {
105 | //TODO: can this be done without sprintf?
106 | vals.Set(k, fmt.Sprintf("%v", v))
107 | }
108 |
109 | return vals
110 | }
111 |
112 | // URLQuery gets an encoded URL query representing the given
113 | // Obj. This function requires that the wrapped object be a
114 | // map[string]interface{}
115 | func (m Map) URLQuery() (string, error) {
116 | return m.URLValues().Encode(), nil
117 | }
118 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/doc.go:
--------------------------------------------------------------------------------
1 | // objx - Go package for dealing with maps, slices, JSON and other data.
2 | //
3 | // Overview
4 | //
5 | // Objx provides the `objx.Map` type, which is a `map[string]interface{}` that exposes
6 | // a powerful `Get` method (among others) that allows you to easily and quickly get
7 | // access to data within the map, without having to worry too much about type assertions,
8 | // missing data, default values etc.
9 | //
10 | // Pattern
11 | //
12 | // Objx uses a preditable pattern to make access data from within `map[string]interface{}'s
13 | // easy.
14 | //
15 | // Call one of the `objx.` functions to create your `objx.Map` to get going:
16 | //
17 | // m, err := objx.FromJSON(json)
18 | //
19 | // NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong,
20 | // the rest will be optimistic and try to figure things out without panicking.
21 | //
22 | // Use `Get` to access the value you're interested in. You can use dot and array
23 | // notation too:
24 | //
25 | // m.Get("places[0].latlng")
26 | //
27 | // Once you have saught the `Value` you're interested in, you can use the `Is*` methods
28 | // to determine its type.
29 | //
30 | // if m.Get("code").IsStr() { /* ... */ }
31 | //
32 | // Or you can just assume the type, and use one of the strong type methods to
33 | // extract the real value:
34 | //
35 | // m.Get("code").Int()
36 | //
37 | // If there's no value there (or if it's the wrong type) then a default value
38 | // will be returned, or you can be explicit about the default value.
39 | //
40 | // Get("code").Int(-1)
41 | //
42 | // If you're dealing with a slice of data as a value, Objx provides many useful
43 | // methods for iterating, manipulating and selecting that data. You can find out more
44 | // by exploring the index below.
45 | //
46 | // Reading data
47 | //
48 | // A simple example of how to use Objx:
49 | //
50 | // // use MustFromJSON to make an objx.Map from some JSON
51 | // m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`)
52 | //
53 | // // get the details
54 | // name := m.Get("name").Str()
55 | // age := m.Get("age").Int()
56 | //
57 | // // get their nickname (or use their name if they
58 | // // don't have one)
59 | // nickname := m.Get("nickname").Str(name)
60 | //
61 | // Ranging
62 | //
63 | // Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For
64 | // example, to `range` the data, do what you would expect:
65 | //
66 | // m := objx.MustFromJSON(json)
67 | // for key, value := range m {
68 | //
69 | // /* ... do your magic ... */
70 | //
71 | // }
72 | package objx
73 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/map.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "encoding/base64"
5 | "encoding/json"
6 | "errors"
7 | "io/ioutil"
8 | "net/url"
9 | "strings"
10 | )
11 |
12 | // MSIConvertable is an interface that defines methods for converting your
13 | // custom types to a map[string]interface{} representation.
14 | type MSIConvertable interface {
15 | // MSI gets a map[string]interface{} (msi) representing the
16 | // object.
17 | MSI() map[string]interface{}
18 | }
19 |
20 | // Map provides extended functionality for working with
21 | // untyped data, in particular map[string]interface (msi).
22 | type Map map[string]interface{}
23 |
24 | // Value returns the internal value instance
25 | func (m Map) Value() *Value {
26 | return &Value{data: m}
27 | }
28 |
29 | // Nil represents a nil Map.
30 | var Nil Map = New(nil)
31 |
32 | // New creates a new Map containing the map[string]interface{} in the data argument.
33 | // If the data argument is not a map[string]interface, New attempts to call the
34 | // MSI() method on the MSIConvertable interface to create one.
35 | func New(data interface{}) Map {
36 | if _, ok := data.(map[string]interface{}); !ok {
37 | if converter, ok := data.(MSIConvertable); ok {
38 | data = converter.MSI()
39 | } else {
40 | return nil
41 | }
42 | }
43 | return Map(data.(map[string]interface{}))
44 | }
45 |
46 | // MSI creates a map[string]interface{} and puts it inside a new Map.
47 | //
48 | // The arguments follow a key, value pattern.
49 | //
50 | // Panics
51 | //
52 | // Panics if any key arugment is non-string or if there are an odd number of arguments.
53 | //
54 | // Example
55 | //
56 | // To easily create Maps:
57 | //
58 | // m := objx.MSI("name", "Mat", "age", 29, "subobj", objx.MSI("active", true))
59 | //
60 | // // creates an Map equivalent to
61 | // m := objx.New(map[string]interface{}{"name": "Mat", "age": 29, "subobj": map[string]interface{}{"active": true}})
62 | func MSI(keyAndValuePairs ...interface{}) Map {
63 |
64 | newMap := make(map[string]interface{})
65 | keyAndValuePairsLen := len(keyAndValuePairs)
66 |
67 | if keyAndValuePairsLen%2 != 0 {
68 | panic("objx: MSI must have an even number of arguments following the 'key, value' pattern.")
69 | }
70 |
71 | for i := 0; i < keyAndValuePairsLen; i = i + 2 {
72 |
73 | key := keyAndValuePairs[i]
74 | value := keyAndValuePairs[i+1]
75 |
76 | // make sure the key is a string
77 | keyString, keyStringOK := key.(string)
78 | if !keyStringOK {
79 | panic("objx: MSI must follow 'string, interface{}' pattern. " + keyString + " is not a valid key.")
80 | }
81 |
82 | newMap[keyString] = value
83 |
84 | }
85 |
86 | return New(newMap)
87 | }
88 |
89 | // ****** Conversion Constructors
90 |
91 | // MustFromJSON creates a new Map containing the data specified in the
92 | // jsonString.
93 | //
94 | // Panics if the JSON is invalid.
95 | func MustFromJSON(jsonString string) Map {
96 | o, err := FromJSON(jsonString)
97 |
98 | if err != nil {
99 | panic("objx: MustFromJSON failed with error: " + err.Error())
100 | }
101 |
102 | return o
103 | }
104 |
105 | // FromJSON creates a new Map containing the data specified in the
106 | // jsonString.
107 | //
108 | // Returns an error if the JSON is invalid.
109 | func FromJSON(jsonString string) (Map, error) {
110 |
111 | var data interface{}
112 | err := json.Unmarshal([]byte(jsonString), &data)
113 |
114 | if err != nil {
115 | return Nil, err
116 | }
117 |
118 | return New(data), nil
119 |
120 | }
121 |
122 | // FromBase64 creates a new Obj containing the data specified
123 | // in the Base64 string.
124 | //
125 | // The string is an encoded JSON string returned by Base64
126 | func FromBase64(base64String string) (Map, error) {
127 |
128 | decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64String))
129 |
130 | decoded, err := ioutil.ReadAll(decoder)
131 | if err != nil {
132 | return nil, err
133 | }
134 |
135 | return FromJSON(string(decoded))
136 | }
137 |
138 | // MustFromBase64 creates a new Obj containing the data specified
139 | // in the Base64 string and panics if there is an error.
140 | //
141 | // The string is an encoded JSON string returned by Base64
142 | func MustFromBase64(base64String string) Map {
143 |
144 | result, err := FromBase64(base64String)
145 |
146 | if err != nil {
147 | panic("objx: MustFromBase64 failed with error: " + err.Error())
148 | }
149 |
150 | return result
151 | }
152 |
153 | // FromSignedBase64 creates a new Obj containing the data specified
154 | // in the Base64 string.
155 | //
156 | // The string is an encoded JSON string returned by SignedBase64
157 | func FromSignedBase64(base64String, key string) (Map, error) {
158 | parts := strings.Split(base64String, SignatureSeparator)
159 | if len(parts) != 2 {
160 | return nil, errors.New("objx: Signed base64 string is malformed.")
161 | }
162 |
163 | sig := HashWithKey(parts[0], key)
164 | if parts[1] != sig {
165 | return nil, errors.New("objx: Signature for base64 data does not match.")
166 | }
167 |
168 | return FromBase64(parts[0])
169 | }
170 |
171 | // MustFromSignedBase64 creates a new Obj containing the data specified
172 | // in the Base64 string and panics if there is an error.
173 | //
174 | // The string is an encoded JSON string returned by Base64
175 | func MustFromSignedBase64(base64String, key string) Map {
176 |
177 | result, err := FromSignedBase64(base64String, key)
178 |
179 | if err != nil {
180 | panic("objx: MustFromSignedBase64 failed with error: " + err.Error())
181 | }
182 |
183 | return result
184 | }
185 |
186 | // FromURLQuery generates a new Obj by parsing the specified
187 | // query.
188 | //
189 | // For queries with multiple values, the first value is selected.
190 | func FromURLQuery(query string) (Map, error) {
191 |
192 | vals, err := url.ParseQuery(query)
193 |
194 | if err != nil {
195 | return nil, err
196 | }
197 |
198 | m := make(map[string]interface{})
199 | for k, vals := range vals {
200 | m[k] = vals[0]
201 | }
202 |
203 | return New(m), nil
204 | }
205 |
206 | // MustFromURLQuery generates a new Obj by parsing the specified
207 | // query.
208 | //
209 | // For queries with multiple values, the first value is selected.
210 | //
211 | // Panics if it encounters an error
212 | func MustFromURLQuery(query string) Map {
213 |
214 | o, err := FromURLQuery(query)
215 |
216 | if err != nil {
217 | panic("objx: MustFromURLQuery failed with error: " + err.Error())
218 | }
219 |
220 | return o
221 |
222 | }
223 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/mutations.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | // Exclude returns a new Map with the keys in the specified []string
4 | // excluded.
5 | func (d Map) Exclude(exclude []string) Map {
6 |
7 | excluded := make(Map)
8 | for k, v := range d {
9 | var shouldInclude bool = true
10 | for _, toExclude := range exclude {
11 | if k == toExclude {
12 | shouldInclude = false
13 | break
14 | }
15 | }
16 | if shouldInclude {
17 | excluded[k] = v
18 | }
19 | }
20 |
21 | return excluded
22 | }
23 |
24 | // Copy creates a shallow copy of the Obj.
25 | func (m Map) Copy() Map {
26 | copied := make(map[string]interface{})
27 | for k, v := range m {
28 | copied[k] = v
29 | }
30 | return New(copied)
31 | }
32 |
33 | // Merge blends the specified map with a copy of this map and returns the result.
34 | //
35 | // Keys that appear in both will be selected from the specified map.
36 | // This method requires that the wrapped object be a map[string]interface{}
37 | func (m Map) Merge(merge Map) Map {
38 | return m.Copy().MergeHere(merge)
39 | }
40 |
41 | // Merge blends the specified map with this map and returns the current map.
42 | //
43 | // Keys that appear in both will be selected from the specified map. The original map
44 | // will be modified. This method requires that
45 | // the wrapped object be a map[string]interface{}
46 | func (m Map) MergeHere(merge Map) Map {
47 |
48 | for k, v := range merge {
49 | m[k] = v
50 | }
51 |
52 | return m
53 |
54 | }
55 |
56 | // Transform builds a new Obj giving the transformer a chance
57 | // to change the keys and values as it goes. This method requires that
58 | // the wrapped object be a map[string]interface{}
59 | func (m Map) Transform(transformer func(key string, value interface{}) (string, interface{})) Map {
60 | newMap := make(map[string]interface{})
61 | for k, v := range m {
62 | modifiedKey, modifiedVal := transformer(k, v)
63 | newMap[modifiedKey] = modifiedVal
64 | }
65 | return New(newMap)
66 | }
67 |
68 | // TransformKeys builds a new map using the specified key mapping.
69 | //
70 | // Unspecified keys will be unaltered.
71 | // This method requires that the wrapped object be a map[string]interface{}
72 | func (m Map) TransformKeys(mapping map[string]string) Map {
73 | return m.Transform(func(key string, value interface{}) (string, interface{}) {
74 |
75 | if newKey, ok := mapping[key]; ok {
76 | return newKey, value
77 | }
78 |
79 | return key, value
80 | })
81 | }
82 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/security.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | import (
4 | "crypto/sha1"
5 | "encoding/hex"
6 | )
7 |
8 | // HashWithKey hashes the specified string using the security
9 | // key.
10 | func HashWithKey(data, key string) string {
11 | hash := sha1.New()
12 | hash.Write([]byte(data + ":" + key))
13 | return hex.EncodeToString(hash.Sum(nil))
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/tests.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | // Has gets whether there is something at the specified selector
4 | // or not.
5 | //
6 | // If m is nil, Has will always return false.
7 | func (m Map) Has(selector string) bool {
8 | if m == nil {
9 | return false
10 | }
11 | return !m.Get(selector).IsNil()
12 | }
13 |
14 | // IsNil gets whether the data is nil or not.
15 | func (v *Value) IsNil() bool {
16 | return v == nil || v.data == nil
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/vendor/github.com/stretchr/objx/value.go:
--------------------------------------------------------------------------------
1 | package objx
2 |
3 | // Value provides methods for extracting interface{} data in various
4 | // types.
5 | type Value struct {
6 | // data contains the raw data being managed by this Value
7 | data interface{}
8 | }
9 |
10 | // Data returns the raw data contained by this Value
11 | func (v *Value) Data() interface{} {
12 | return v.data
13 | }
14 |
--------------------------------------------------------------------------------
/vendor/manifest:
--------------------------------------------------------------------------------
1 | {
2 | "version": 0,
3 | "dependencies": [
4 | {
5 | "importpath": "github.com/stretchr/testify",
6 | "repository": "https://github.com/stretchr/testify",
7 | "vcs": "git",
8 | "revision": "2402e8e7a02fc811447d11f881aa9746cdc57983",
9 | "branch": "master",
10 | "notests": true
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------