├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── bin ├── sparkler └── spc_chart ├── tests.watchr └── tests ├── arguments.py ├── fixtures └── phpunit_commits_per_day ├── lib ├── line_plot_above_100_data_points_test.sh ├── line_plot_below_100_data_points_test.sh ├── many_labels_50_test.sh ├── phpunit_commits_per_day_test.sh ├── regular_args_with_labels_test.sh ├── regular_arguments.sh ├── values_newline_delimited_test.sh ├── values_test.sh └── values_with_labels_test.sh ├── options.py ├── plots ├── line_plot_below_100_data_points.png ├── many_labels_50.png ├── more_than_100_data_points.png ├── phpunit_commits_per_day.png ├── regular_args_with_labels.png ├── regular_arguments.png ├── values.png ├── values_newline_delimited.png └── values_with_labels.png └── run /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | 3 | #Emacs tmp files 4 | *~ 5 | *# 6 | .#* 7 | \#* 8 | 9 | #MacOS tmp files 10 | .DS_Store 11 | 12 | #Maruku generated files 13 | README.html 14 | 15 | #Sparkler generated files 16 | graph-*.png 17 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at noah@onemorebug.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016 Noah Sussman New Media, LLC 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this library except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | [www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) 7 | 8 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, 9 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | sparkler: graphical plots from shell command output 2 | ======== 3 | 4 | ## Usage 5 | 6 | Just pipe a newline-delimited list of integers to **bin/sparkler** or **bin/spc_chart** and it 7 | will produce a graphical plot. 8 | 9 | ### Labeled Series, Including Time Series 10 | 11 | `spc_chart` and `sparkler` both support labels on data series as long as the first value on each 12 | line is a number and the rest of the line is the label. If there are many labels sampling will 13 | be performed so that only a few labels appear on the x-axis. This keeps the graph readable even 14 | if there are hundreds of data points. 15 | 16 | For example this can be useful if you have a time series: 17 | 18 | echo "27 Wed Sep 26 13:50:57 EDT 2018 19 | 13 Wed Oct 3 13:50:56 EDT 2018 20 | 9 Wed Sep 19 13:50:51 EDT 2018 21 | 4 Wed Oct 3 13:50:51 EDT 2018 22 | 25 Wed Sep 26 13:50:51 EDT 2018 23 | 10 Wed Oct 17 13:50:49 EDT 2018 24 | 29 Wed Oct 17 13:45:51 EDT 2018 25 | 31 Wed Oct 17 13:45:49 EDT 2018 26 | 34 Wed Oct 17 13:44:52 EDT 2018 27 | 16 Wed Oct 17 13:44:51 EDT 2018 28 | 1 Wed Oct 17 13:43:53 EDT 2018 29 | 17 Wed Oct 17 13:43:51 EDT 2018 30 | 5 Wed Oct 17 13:42:54 EDT 2018 31 | 0 Wed Oct 17 13:42:51 EDT 2018 32 | 9 Wed Oct 17 13:40:55 EDT 2018 33 | 21 Wed Oct 17 13:40:51 EDT 2018 34 | 11 Wed Sep 19 11:50:57 EDT 2018" \ 35 | | bin/spc_chart 36 | 37 | This produces a chart file named `spc-chart-d8e9d9e86bcc714332e8954a6bafd2521b86a242.png` 38 | 39 | If you open that PNG file you will see this chart: 40 | 41 | a dot plot with control lines above and below the time series 43 | 44 | ### Simple Use 45 | 46 | The following command will produce a graphical plot that shows the 47 | first nine integers of the Fibonacci Sequence. 48 | 49 | echo 0 1 1 2 3 5 8 13 21 | bin/sparkler 50 | 51 | or 52 | 53 | echo "0 54 | 1 55 | 1 56 | 2" | bin/sparkler 57 | 58 | Any text after the integer tokens is used as labels for the x-axis: 59 | 60 | echo "0 this is a label 61 | 1 this is another label 62 | 1 and so on 63 | 2 yep labels" | bin/sparkler 64 | 65 | You can also pass arguments directly: 66 | 67 | bin/sparkler 0 1 1 2 3 5 8 13 21 68 | 69 | or 70 | 71 | bin/sparkler "0 72 | 1 73 | 1 74 | 2" 75 | 76 | and also 77 | 78 | bin/sparkler "0 this is a label 79 | 1 this is another label 80 | 1 and so on 81 | 2 fun with labels" 82 | 83 | ## Synopsis 84 | 85 | A cli tool directly inspired by [spark][spark]. sparkler produces 86 | graphical plots from whitespace-delimited lists of numbers passed by 87 | other command line arguments. 88 | 89 | In 2017 I wrote [an introductory article about sparkler.](http://infiniteundo.com/post/158800222608/sparkler-graphs-in-terminal "it has some nice screenshots") 90 | 91 | sparkler makes an attempt to be smart about displaying data in a way 92 | that makes sense while reducing visual noise. 93 | 94 | * if the x-axis has labels, perform sampling for large data sets (so 95 | that the labels never overlap) 96 | * fit the graph to the drawing area, so that the graph always fills 97 | the entire area available for display 98 | * use log scale if the range of values is large 99 | 100 | The output image is written to a file called `graph-.png` in the 101 | current working directory, where `` is the sha1 hash of the 102 | argument list that was passed to sparkler. This means that each data 103 | set you pass to sparkler should result in a consistent file name that 104 | is unique to that data set. The name of the generated png file is 105 | echoed back to the command line so that you can easily reference it in 106 | your scripts. Eg: 107 | 108 | open `sparkler 0 1 1 2 3 5` 109 | 110 | sparkler graphs should fit exactly on a sheet of legal paper when 111 | printed. 112 | 113 | ## Installation 114 | 115 | The following command will install all dependencies, and should work 116 | on any system with a relatively modern version of Python: 117 | 118 | sudo easy_install numpy matplotlib 119 | 120 | You can optionally move or symlink **bin/sparkler** to 121 | **/usr/bin/sparkler** (or anywhere in your path) and it should then be 122 | usable from anywhere on your system, just like any other shell 123 | command. 124 | 125 | ## How to run the tests 126 | 127 | tests/run 128 | 129 | If the exit code is `0`, all is well. 130 | 131 | ### How do the tests work? 132 | 133 | The tests generate graphs off of various inputs and then diff the each 134 | generated image against a fixture image, to validate that the expected 135 | graphs were produced. 136 | 137 | ## What's not included 138 | 139 | **sparkler** is intended to be like **spark:** a dead simple tool that 140 | does the right thing 99% of the time. Thus there are no configuration 141 | options. 142 | 143 | The general use case for **sparkler** is: "I am looking at the output 144 | from a shell command and I wonder what it looks like as a graph." More 145 | complex use cases are intentionally not considered. 146 | 147 | When you require that level of detail in your analysis, you should 148 | switch to using matplotlib directly, or use another data visualization 149 | tool like R, GNUPlot, Flot or d3. 150 | 151 | Specifically, you cannot label the axis nor add a title to the graph 152 | using **sparkler.** For that you can edit the PNG output files using 153 | an image-annotating tool like Photoshop, Skitch or Jing. 154 | 155 | And you also cannot combine multiple data series on a single 156 | graph. When you reach a point where you have multiple data series 157 | saved in different files, you should consider using a tool more 158 | powerful than **sparkler.** 159 | 160 | [spark]: https://github.com/holman/spark 'spark is an awesome command-line tool for drawing sparklines in your shell' 161 | -------------------------------------------------------------------------------- /bin/sparkler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | 5 | A CLI tool like spark, that produces sparklines from 6 | whitespace-delimited lists of numbers passed by other command line 7 | arguments. See https://github.com/holman/spark 8 | 9 | There are three valid use cases: 10 | 11 | 1. space-delimited list of values (no labels, all values on one line): 12 | 13 | git log --since 'september' --format='%ad' --date-order | \ 14 | awk '{print $1" "$2" "$3}' | uniq -c | tac | awk '{print $1}' | \ 15 | xargs python graphs.py 16 | 17 | 2. newline-delimited list of values (no labels, newline-delimited): 18 | 19 | git log --since 'september' --format='%ad' --date-order | \ 20 | awk '{print $1" "$2" "$3}' | uniq -c | tac | awk '{print $1}' | \ 21 | python graphs.py 22 | 23 | 3. newline-delimited list where each line is a value followed by label text: 24 | 25 | git log --since 'september' --format='%ad' --date-order | \ 26 | awk '{print $1" "$2" "$3}' | uniq -c | tac | \ 27 | python graphs.py 28 | 29 | """ 30 | 31 | import sys 32 | import hashlib 33 | import numpy 34 | import matplotlib 35 | matplotlib.use('Agg') 36 | import matplotlib.pyplot as plt 37 | 38 | def make_plot(values): 39 | low_water_mark = min(values) 40 | high_water_mark = max(values) 41 | index_of_high_water = values.index(high_water_mark) 42 | median_value = numpy.median(values) 43 | 44 | use_log_scale = False 45 | 46 | if (high_water_mark - low_water_mark) > 1000: 47 | use_log_scale = True 48 | 49 | plt.bar( 50 | range(len(values)), 51 | values, 52 | color='#333333', 53 | linewidth=0, 54 | align='center', 55 | width=1, 56 | log=use_log_scale 57 | ) 58 | 59 | if plt.axis()[3] != high_water_mark: 60 | plt.annotate( 61 | '{0:g}'.format(high_water_mark), 62 | xy=(index_of_high_water, high_water_mark), 63 | xytext=(0, 12), 64 | xycoords=('data'), 65 | textcoords='offset points', 66 | ha='center', 67 | color="#666666", 68 | arrowprops=dict( 69 | arrowstyle='-', 70 | color="#666666" 71 | ), 72 | bbox=dict( 73 | boxstyle="square", 74 | fc="w", 75 | color="#666666" 76 | ) 77 | ) 78 | 79 | plt.axhline( 80 | y=median_value, 81 | color="#666666", 82 | alpha=0.5 83 | ) 84 | 85 | plt.annotate( 86 | '{0:g}'.format(median_value), 87 | xy=(1, median_value), 88 | xytext=(8, 0), 89 | xycoords=('axes fraction', 'data'), 90 | textcoords='offset points', 91 | va='center', 92 | color="#333333" 93 | ) 94 | 95 | plt.axis('tight') 96 | 97 | def plot_integers(raw_values): 98 | values = [float(s) for s in raw_values] 99 | make_plot(values) 100 | 101 | def get_inputs(): 102 | if len(sys.argv) > 1: 103 | sys.argv.pop(0) 104 | 105 | if len(sys.argv) == 1: 106 | return sys.argv[0].strip().split('\n') 107 | else: 108 | return sys.argv 109 | else: 110 | raw_input = sys.stdin.readlines() 111 | if len(raw_input) == 1: 112 | return raw_input[0].strip().split(' ') 113 | else: 114 | return raw_input 115 | 116 | """ 117 | Only so many labels fit comfortably along the y-axis. After that, 118 | downsample the labels so that we only print as many as will fit. Don't 119 | attempt to be smart about which labels to filter, just use the overall 120 | count of labels as a guide. 121 | """ 122 | def sample_from_labels(labels): 123 | labels_that_can_fit_on_the_y_axis = 40 124 | filtered_labels = [] 125 | if (len(labels) > labels_that_can_fit_on_the_y_axis): 126 | filtered_labels = filter_for_labels(labels_that_can_fit_on_the_y_axis, labels) 127 | else: 128 | filtered_labels = labels 129 | return filtered_labels 130 | 131 | def filter_for_labels(labels_that_can_fit_on_the_y_axis, labels): 132 | filtered_labels = [] 133 | every_nth_label = len(labels) / (labels_that_can_fit_on_the_y_axis / 2) 134 | for index, label in enumerate(labels): 135 | if (index + 1) == len(labels): 136 | filtered_labels.append(label) 137 | elif index % every_nth_label != 0 or (len(labels) - index + 1) < every_nth_label : 138 | filtered_labels.append(' ') 139 | else: 140 | filtered_labels.append(label) 141 | 142 | return filtered_labels 143 | 144 | def sparkler_cli(): 145 | raw_values = get_inputs() 146 | 147 | if len(raw_values) > 1 and len(raw_values[0].split()) > 1: 148 | values = [] 149 | labels = [] 150 | 151 | for s in raw_values: 152 | tokens = s.strip().split() 153 | cons = tokens.pop(0) 154 | cdr = ' '.join(tokens) 155 | values.append(float(cons)) 156 | labels.append(cdr) 157 | 158 | labels = sample_from_labels(labels) 159 | 160 | make_plot(values) 161 | plt.xticks(range(len(values)), labels, size='small', rotation=75) 162 | 163 | elif len(raw_values) > 1: 164 | plot_integers(raw_values) 165 | 166 | else: 167 | plot_integers(raw_values[0].split()) 168 | 169 | fig = matplotlib.pyplot.gcf() 170 | fig.set_size_inches(13.5, 8) 171 | 172 | guid = hashlib.sha1(''.join(raw_values).encode('utf-8')).hexdigest() 173 | 174 | file_name='./graph-' + guid + '.png' 175 | 176 | fig.savefig(file_name, dpi=300, bbox_inches='tight') 177 | 178 | print(file_name) 179 | 180 | sparkler_cli() 181 | -------------------------------------------------------------------------------- /bin/spc_chart: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | Create SPC charts from data sets. Inspired by Simon Guilfoyle's 5 | "Intelligent Policing" http://amzn.to/1dNNCfb 6 | 7 | The algorithm described by Guilfoyle in the book is: 8 | 9 | Given a list of data points sorted in chronological order, iterate 10 | over the list starting at index 1 (that is, skip the last entry in 11 | the list), subtracting each value from the previous value. The 12 | resulting list of values is the "set of ranges." 13 | 14 | Take the median value from the set of ranges, and multiply it by 15 | 3.14. This is the "distance from the center line to the control 16 | limits." 17 | 18 | Find the average of all the data points in the original list. The 19 | average of the data series is the "center line of the control chart." 20 | 21 | Now plot the original data series and draw: 22 | 23 | 1. a solid line at the average 24 | 25 | 2. Two dashed lines that are "distance from the center line to the control 26 | limits" units above and below the center line, respectively. 27 | """ 28 | 29 | import sys 30 | import hashlib 31 | import numpy 32 | import matplotlib 33 | matplotlib.use('Agg') 34 | import matplotlib.pyplot as plt 35 | 36 | def calculate_ranges(values): 37 | accumulator = [] 38 | for count, x in enumerate(values): 39 | ++count 40 | 41 | if (count + 1) < len(values): 42 | range = x - values[count + 1] 43 | accumulator.append(abs(range)) 44 | 45 | return accumulator 46 | 47 | def make_plot(values): 48 | low_water_mark = min(values) 49 | high_water_mark = max(values) 50 | use_log_scale = False 51 | 52 | if (high_water_mark - low_water_mark) > 1000: 53 | use_log_scale = True 54 | 55 | ranges = calculate_ranges(values) 56 | raw_median_range = numpy.median(ranges) 57 | 58 | if raw_median_range > 1 or raw_median_range < -1 : 59 | median_of_ranges = abs(raw_median_range) 60 | else: 61 | median_of_ranges = 1 62 | 63 | avg_value = numpy.average(values) 64 | 65 | upper_limit = median_of_ranges * 3.14 + avg_value 66 | 67 | lower_limit = avg_value - median_of_ranges * 3.14 68 | 69 | stdout_filehandle = sys.stdout 70 | sys.stdout = sys.stderr 71 | 72 | sys.stdout = stdout_filehandle 73 | 74 | plt.plot(values, 'ko') 75 | 76 | plt.axhline( 77 | y=avg_value, 78 | color="#666666", 79 | ) 80 | 81 | plt.annotate( 82 | '{0:g}'.format(avg_value), 83 | xy=(1, avg_value), 84 | xytext=(8, 0), 85 | xycoords=('axes fraction', 'data'), 86 | textcoords='offset points', 87 | va='center', 88 | color="#333333" 89 | ) 90 | 91 | plt.axhline( 92 | y=upper_limit, 93 | color="#333333", 94 | linestyle=':' 95 | ) 96 | 97 | plt.annotate( 98 | '{0:g}'.format(upper_limit), 99 | xy=(1, upper_limit), 100 | xytext=(8, 0), 101 | xycoords=('axes fraction', 'data'), 102 | textcoords='offset points', 103 | va='center', 104 | color="#333333" 105 | ) 106 | 107 | if lower_limit > 0: 108 | plt.axhline( 109 | y=lower_limit, 110 | color="#333333", 111 | linestyle=':' 112 | ) 113 | 114 | if lower_limit > 0: 115 | plt.annotate( 116 | '{0:g}'.format(lower_limit), 117 | xy=(1, lower_limit), 118 | xytext=(8, 0), 119 | xycoords=('axes fraction', 'data'), 120 | textcoords='offset points', 121 | va='center', 122 | color="#333333" 123 | ) 124 | 125 | def plot_integers(raw_values): 126 | values = [float(s) for s in raw_values] 127 | make_plot(values) 128 | 129 | def get_inputs(): 130 | if len(sys.argv) > 1: 131 | sys.argv.pop(0) 132 | 133 | if len(sys.argv) == 1: 134 | return sys.argv[0].strip().split('\n') 135 | else: 136 | return sys.argv 137 | else: 138 | raw_input = sys.stdin.readlines() 139 | if len(raw_input) == 1: 140 | return raw_input[0].strip().split(' ') 141 | else: 142 | return raw_input 143 | 144 | """ 145 | Only so many labels fit comfortably along the y-axis. After that, 146 | downsample the labels so that we only print as many as will fit. Don't 147 | attempt to be smart about which labels to filter, just use the overall 148 | count of labels as a guide. 149 | """ 150 | def sample_from_labels(labels): 151 | labels_that_can_fit_on_the_y_axis = 40 152 | filtered_labels = [] 153 | if (len(labels) > labels_that_can_fit_on_the_y_axis): 154 | filtered_labels = filter_for_labels(labels_that_can_fit_on_the_y_axis, labels) 155 | else: 156 | filtered_labels = labels 157 | return filtered_labels 158 | 159 | def filter_for_labels(labels_that_can_fit_on_the_y_axis, labels): 160 | filtered_labels = [] 161 | every_nth_label = len(labels) / (labels_that_can_fit_on_the_y_axis / 2) 162 | for index, label in enumerate(labels): 163 | if (index + 1) == len(labels): 164 | filtered_labels.append(label) 165 | elif index % every_nth_label != 0 or (len(labels) - index + 1) < every_nth_label : 166 | filtered_labels.append(' ') 167 | else: 168 | filtered_labels.append(label) 169 | 170 | return filtered_labels 171 | 172 | def spc_chart_cli(): 173 | raw_values = get_inputs() 174 | 175 | if len(raw_values) > 1 and len(raw_values[0].split()) > 1: 176 | values = [] 177 | labels = [] 178 | 179 | for s in raw_values: 180 | tokens = s.strip().split() 181 | cons = tokens.pop(0) 182 | cdr = ' '.join(tokens) 183 | values.append(float(cons)) 184 | labels.append(cdr) 185 | 186 | labels = sample_from_labels(labels) 187 | 188 | make_plot(values) 189 | plt.xticks(range(len(values)), labels, size='small', rotation=75) 190 | 191 | elif len(raw_values) > 1: 192 | plot_integers(raw_values) 193 | 194 | else: 195 | plot_integers(raw_values[0].split()) 196 | 197 | fig = matplotlib.pyplot.gcf() 198 | fig.set_size_inches(13.5, 8) 199 | 200 | guid = hashlib.sha1(''.join(raw_values).encode('utf-8')).hexdigest() 201 | 202 | file_name='./spc-chart-' + guid + '.png' 203 | 204 | fig.savefig(file_name, dpi=300, bbox_inches='tight') 205 | 206 | print(file_name) 207 | 208 | spc_chart_cli() 209 | -------------------------------------------------------------------------------- /tests.watchr: -------------------------------------------------------------------------------- 1 | # Run me with: 2 | # watchr -d tests.watchr 3 | # 4 | # Also requires the Watchr and ruby-growl gems as well as JSHint, 5 | # JSLint and PHP CodeSniffer. Install them thusly: 6 | # 7 | # sudo gem install watchr ruby-growl 8 | # 9 | # To use fsevent you currently have to patch watchr.rb as described here: 10 | # https://github.com/mynyml/watchr/issues/36#issuecomment-7794856 11 | # Then 12 | # sudo gem install rev 13 | 14 | @growl_clients = %w{ 15 | 127.0.0.1 16 | } 17 | 18 | def check action, title, message 19 | guid = %x{echo '#{title}' | sha1sum - | cut -d' ' -f1}.chomp 20 | if system %{set -x; #{action}} 21 | if system %{test -e /tmp/#{guid}} 22 | puts "\033[32;1m" + title + " RECOVERY\n\t" + message + "\033[0m" 23 | system %{rm /tmp/#{guid}} 24 | @growl_clients.each do | host | 25 | system %{growl -H #{host} -t 'RECOVERED OK: #{title}' -m '#{message}'} 26 | end 27 | end 28 | else 29 | puts "\033[31;1m" + title + " FAILURE\n\t" + message + "\033[0m" 30 | system %{touch /tmp/#{guid}} 31 | @growl_clients.each do | host | 32 | system %{growl -H #{host} -t 'FAIL: #{title}' -m '#{message}'} 33 | end 34 | return false 35 | end 36 | return true 37 | end 38 | 39 | # Rules 40 | # 41 | # Less specific rules should be listed first. 42 | 43 | watch( '(.*\.py$)' ) { |m| 44 | check(%{tests/run}, 45 | "Tests for #{m[2]}", 46 | m[1]) 47 | } 48 | 49 | watch( '(.*bin/sparkler$)' ) { |m| 50 | check(%{tests/run}, 51 | "Tests for #{m[2]}", 52 | m[1]) 53 | } 54 | 55 | 56 | # Press Ctl-C to quit. 57 | 58 | Signal.trap('INT' ) { abort("\n") } # Ctrl-C 59 | -------------------------------------------------------------------------------- /tests/arguments.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | if len(sys.argv) > 1: 4 | 5 | print 'sys.argv:' 6 | print sys.argv 7 | 8 | else: 9 | 10 | # for multiline input: 11 | print 'sys.stdin.readlines()' 12 | print sys.stdin.readlines() 13 | -------------------------------------------------------------------------------- /tests/fixtures/phpunit_commits_per_day: -------------------------------------------------------------------------------- 1 | 2 Wed Oct 17 2012 2 | 1 Mon Oct 15 2012 3 | 1 Sun Oct 14 2012 4 | 2 Thu Oct 11 2012 5 | 7 Tue Oct 9 2012 6 | 3 Mon Oct 8 2012 7 | 2 Sun Oct 7 2012 8 | 1 Mon Sep 24 2012 9 | 2 Sun Oct 7 2012 10 | 7 Sat Oct 6 2012 11 | 10 Fri Oct 5 2012 12 | 1 Wed Oct 3 2012 13 | 5 Thu Oct 4 2012 14 | 2 Wed Oct 3 2012 15 | 4 Tue Oct 2 2012 16 | 3 Mon Oct 1 2012 17 | 2 Fri Sep 28 2012 18 | 4 Mon Sep 24 2012 19 | 2 Sun Sep 23 2012 20 | 1 Fri Sep 21 2012 21 | 4 Thu Sep 20 2012 22 | 3 Wed Sep 19 2012 23 | 7 Tue Sep 18 2012 24 | 7 Mon Sep 17 2012 25 | 1 Wed Sep 12 2012 26 | 1 Tue Sep 11 2012 27 | 6 Mon Sep 10 2012 28 | 1 Thu Sep 6 2012 29 | 2 Fri Sep 7 2012 30 | 1 Thu Sep 6 2012 31 | 2 Wed Sep 5 2012 32 | 4 Fri Aug 31 2012 33 | 1 Wed Aug 22 2012 34 | 1 Sat Aug 18 2012 35 | 1 Fri Aug 17 2012 36 | 4 Wed Aug 15 2012 37 | 10 Tue Aug 14 2012 38 | 2 Mon Aug 13 2012 39 | 2 Tue Aug 7 2012 40 | 4 Fri Aug 3 2012 41 | 6 Fri Jul 27 2012 42 | 1 Mon Jul 16 2012 43 | 1 Mon Jul 2 2012 44 | 1 Tue Jul 3 2012 45 | 2 Mon Jul 2 2012 46 | 2 Sun Jul 1 2012 47 | 2 Fri Jun 22 2012 48 | 4 Wed Jun 13 2012 49 | 1 Fri Jun 8 2012 50 | 1 Mon May 28 2012 51 | 1 Fri May 18 2012 52 | 7 Thu May 31 2012 53 | 4 Sun May 27 2012 54 | 3 Sat May 26 2012 55 | 1 Wed Apr 11 2012 56 | 2 Wed May 16 2012 57 | 2 Tue May 15 2012 58 | 1 Wed May 9 2012 59 | 5 Sun May 6 2012 60 | 10 Sat May 5 2012 61 | 2 Fri Apr 22 2011 62 | 2 Sat May 5 2012 63 | 1 Thu May 3 2012 64 | 1 Mon Apr 30 2012 65 | 1 Tue May 1 2012 66 | 1 Mon Apr 30 2012 67 | 2 Sat Apr 21 2012 68 | 1 Wed Apr 18 2012 69 | 1 Tue Apr 3 2012 70 | 1 Wed Apr 18 2012 71 | 1 Sat Apr 14 2012 72 | 2 Tue Apr 10 2012 73 | 1 Tue Apr 3 2012 74 | 3 Sun Apr 1 2012 75 | 1 Thu Mar 17 2011 76 | 3 Sat Mar 31 2012 77 | 1 Thu Aug 18 2011 78 | 2 Sat Mar 31 2012 79 | 1 Mon Feb 27 2012 80 | 2 Sat Mar 31 2012 81 | 1 Fri Mar 30 2012 82 | 1 Mon Feb 20 2012 83 | 2 Mon Mar 26 2012 84 | 5 Sat Mar 24 2012 85 | 2 Wed Mar 14 2012 86 | 2 Thu Mar 8 2012 87 | 1 Sat Mar 3 2012 88 | 1 Thu Mar 1 2012 89 | 7 Sun Feb 26 2012 90 | 1 Mon Feb 27 2012 91 | 1 Tue Feb 21 2012 92 | 4 Mon Feb 20 2012 93 | 1 Sun Feb 19 2012 94 | 1 Sat Feb 18 2012 95 | 1 Fri Nov 18 2011 96 | 3 Wed Feb 15 2012 97 | 2 Sun Feb 12 2012 98 | 6 Thu Feb 9 2012 99 | 2 Wed Feb 8 2012 100 | 2 Tue Jan 31 2012 101 | 1 Sun Jan 29 2012 102 | 1 Sat Jan 28 2012 103 | 4 Fri Jan 27 2012 104 | 1 Thu Jan 26 2012 105 | 2 Wed Jan 25 2012 106 | 4 Tue Jan 24 2012 107 | 6 Mon Jan 23 2012 108 | 1 Sat Jan 21 2012 109 | 2 Fri Jan 20 2012 110 | 4 Thu Jan 19 2012 111 | 2 Sat Jan 14 2012 112 | 1 Fri Jan 13 2012 113 | 3 Thu Jan 12 2012 114 | 2 Mon Jan 9 2012 115 | 9 Sat Jan 7 2012 116 | 1 Thu Jan 5 2012 117 | 10 Tue Jan 3 2012 118 | 8 Mon Jan 2 2012 119 | 5 Sun Jan 1 2012 120 | 1 Sat Dec 31 2011 121 | 1 Wed Dec 28 2011 122 | 8 Tue Dec 27 2011 123 | 1 Mon Dec 26 2011 124 | 2 Fri Dec 23 2011 125 | 2 Thu Dec 22 2011 126 | 18 Wed Dec 21 2011 127 | 20 Tue Dec 20 2011 128 | 2 Mon Dec 19 2011 129 | 9 Sun Dec 18 2011 130 | 3 Fri Dec 16 2011 131 | 1 Wed Aug 31 2011 132 | 6 Fri Dec 16 2011 133 | 9 Thu Dec 15 2011 134 | 1 Wed Dec 14 2011 135 | 2 Tue Dec 13 2011 136 | 5 Mon Dec 12 2011 137 | 4 Sun Dec 11 2011 138 | 3 Sat Dec 10 2011 139 | 2 Sun Dec 11 2011 140 | 1 Sat Dec 10 2011 141 | 3 Fri Dec 9 2011 142 | 1 Wed Dec 7 2011 143 | 3 Mon Dec 5 2011 144 | 2 Sat Dec 3 2011 145 | 1 Wed Nov 30 2011 146 | 4 Sun Nov 27 2011 147 | 4 Sat Nov 26 2011 148 | 6 Fri Nov 25 2011 149 | 1 Fri Nov 18 2011 150 | 6 Thu Nov 17 2011 151 | 2 Wed Nov 16 2011 152 | 1 Tue Nov 15 2011 153 | 14 Sat Nov 12 2011 154 | 18 Fri Nov 11 2011 155 | 13 Thu Nov 10 2011 156 | 1 Fri Sep 2 2011 157 | 3 Thu Nov 10 2011 158 | 14 Wed Nov 9 2011 159 | 13 Tue Nov 8 2011 160 | 4 Fri Nov 4 2011 161 | 5 Thu Nov 3 2011 162 | 1 Wed Nov 2 2011 163 | 1 Mon Oct 31 2011 164 | 5 Wed Oct 26 2011 165 | 4 Mon Oct 24 2011 166 | 2 Tue Oct 18 2011 167 | 4 Tue Oct 11 2011 168 | 2 Sat Oct 8 2011 169 | 5 Fri Oct 7 2011 170 | 6 Tue Oct 4 2011 171 | 3 Fri Sep 30 2011 172 | 1 Thu Sep 29 2011 173 | 1 Wed Sep 28 2011 174 | 3 Tue Sep 27 2011 175 | 5 Mon Sep 26 2011 176 | 1 Sun Sep 25 2011 177 | 3 Sat Sep 24 2011 178 | 2 Fri Sep 23 2011 179 | 3 Thu Sep 15 2011 180 | 3 Sun Sep 11 2011 181 | 3 Wed Sep 7 2011 182 | 2 Tue Sep 6 2011 183 | 1 Mon Sep 5 2011 184 | 6 Sun Sep 4 2011 185 | 5 Sat Sep 3 2011 186 | 4 Fri Sep 2 2011 187 | 5 Mon Aug 29 2011 188 | 2 Sun Aug 28 2011 189 | 3 Fri Aug 26 2011 190 | 4 Thu Aug 25 2011 191 | 10 Wed Aug 24 2011 192 | 1 Tue Aug 23 2011 193 | 1 Fri Aug 19 2011 194 | 1 Tue Aug 16 2011 195 | 1 Wed Aug 10 2011 196 | 2 Mon Aug 8 2011 197 | 1 Sun Jul 31 2011 198 | 2 Wed Jul 27 2011 199 | 4 Sun Jul 24 2011 200 | 1 Tue Jul 5 2011 201 | 6 Thu Jun 16 2011 202 | 1 Wed Jun 15 2011 203 | 10 Tue Jun 14 2011 204 | 7 Tue Jun 7 2011 205 | 2 Tue Jun 14 2011 206 | 1 Fri May 27 2011 207 | 2 Tue Jun 14 2011 208 | 1 Fri Jun 10 2011 209 | 7 Thu Jun 9 2011 210 | 1 Wed Jun 8 2011 211 | 2 Mon Jun 6 2011 212 | 2 Thu Jun 2 2011 213 | 3 Sun May 22 2011 214 | 2 Sat May 21 2011 215 | 1 Wed May 18 2011 216 | 1 Tue May 17 2011 217 | 1 Wed May 18 2011 218 | 2 Mon May 9 2011 219 | 9 Fri May 6 2011 220 | 1 Wed Feb 9 2011 221 | 1 Mon Feb 7 2011 222 | 2 Thu Apr 14 2011 223 | 1 Wed Apr 13 2011 224 | 2 Tue Apr 12 2011 225 | 2 Sun Apr 10 2011 226 | 1 Wed Apr 6 2011 227 | 2 Sun Apr 3 2011 228 | 1 Sat Apr 2 2011 229 | 2 Thu Mar 31 2011 230 | 1 Tue Mar 29 2011 231 | 1 Mon Mar 28 2011 232 | 8 Sat Mar 12 2011 233 | 1 Thu Mar 10 2011 234 | 3 Fri Mar 11 2011 235 | 8 Mon Mar 7 2011 236 | 1 Sun Mar 6 2011 237 | 2 Sat Mar 5 2011 238 | 1 Thu Mar 3 2011 239 | 2 Tue Mar 1 2011 240 | 1 Thu Feb 24 2011 241 | 10 Sun Feb 20 2011 242 | 5 Mon Feb 14 2011 243 | 4 Sun Feb 13 2011 244 | 13 Sat Feb 12 2011 245 | 4 Fri Feb 11 2011 246 | 3 Thu Feb 10 2011 247 | 1 Wed Feb 9 2011 248 | 2 Mon Feb 7 2011 249 | 2 Thu Feb 3 2011 250 | 3 Sat Jan 29 2011 251 | 1 Thu Jan 27 2011 252 | 6 Wed Jan 26 2011 253 | 9 Tue Jan 25 2011 254 | 11 Sat Jan 22 2011 255 | 5 Fri Jan 21 2011 256 | 5 Thu Jan 20 2011 257 | 13 Wed Jan 19 2011 258 | 5 Tue Jan 18 2011 259 | 6 Mon Jan 17 2011 260 | 5 Sun Jan 16 2011 261 | 5 Sat Jan 15 2011 262 | 4 Fri Jan 14 2011 263 | 1 Wed Jan 12 2011 264 | 3 Tue Jan 11 2011 265 | 4 Sat Jan 8 2011 266 | 26 Fri Jan 7 2011 267 | 4 Tue Jan 4 2011 268 | 4 Mon Jan 3 2011 269 | 2 Fri Dec 31 2010 270 | 4 Sat Dec 18 2010 271 | 2 Fri Dec 17 2010 272 | 3 Tue Dec 14 2010 273 | 1 Thu Dec 9 2010 274 | 2 Tue Dec 14 2010 275 | 2 Sun Dec 12 2010 276 | 1 Mon Dec 6 2010 277 | 3 Sun Dec 5 2010 278 | 11 Sat Dec 4 2010 279 | 5 Fri Dec 3 2010 280 | 2 Sun Nov 28 2010 281 | 2 Tue Nov 23 2010 282 | 3 Mon Nov 22 2010 283 | 5 Wed Nov 17 2010 284 | 1 Tue Nov 16 2010 285 | 3 Thu Nov 11 2010 286 | 1 Wed Nov 10 2010 287 | 2 Fri Oct 29 2010 288 | 1 Wed Oct 27 2010 289 | 4 Tue Oct 26 2010 290 | 3 Sun Oct 24 2010 291 | 1 Wed Sep 1 2010 292 | 7 Sat Oct 23 2010 293 | 4 Fri Oct 22 2010 294 | 1 Tue Oct 12 2010 295 | 5 Wed Oct 20 2010 296 | 7 Mon Oct 18 2010 297 | 6 Sun Oct 17 2010 298 | 9 Sat Oct 16 2010 299 | 1 Fri Oct 15 2010 300 | 1 Sat Oct 16 2010 301 | 1 Sun Oct 10 2010 302 | 2 Fri Oct 8 2010 303 | 1 Wed Oct 6 2010 304 | 4 Tue Oct 5 2010 305 | 3 Tue Sep 28 2010 306 | 1 Sat Sep 25 2010 307 | 4 Sun Sep 19 2010 308 | 1 Mon Sep 13 2010 309 | 2 Sun Sep 12 2010 310 | 1 Tue Aug 31 2010 311 | 2 Thu Aug 26 2010 312 | 1 Wed Aug 25 2010 313 | 7 Thu Aug 19 2010 314 | 2 Wed Aug 18 2010 315 | 3 Tue Aug 17 2010 316 | 7 Mon Aug 16 2010 317 | 1 Sun Aug 15 2010 318 | 8 Sat Aug 14 2010 319 | 1 Thu Aug 12 2010 320 | 2 Sat Jul 31 2010 321 | 3 Tue Jul 27 2010 322 | 1 Thu Jul 22 2010 323 | 1 Wed Jul 21 2010 324 | 2 Tue Jul 20 2010 325 | 1 Sun Jul 18 2010 326 | 11 Sat Jul 17 2010 327 | 2 Fri Jul 16 2010 328 | 5 Wed Jul 7 2010 329 | 8 Tue Jul 6 2010 330 | 2 Sat Jul 3 2010 331 | 5 Fri Jul 2 2010 332 | 1 Tue Nov 17 2009 333 | 5 Fri Jul 2 2010 334 | 1 Thu Jul 1 2010 335 | 1 Sat Jun 26 2010 336 | 5 Tue Jun 22 2010 337 | 3 Sun Jun 20 2010 338 | 4 Sat Jun 19 2010 339 | 3 Fri Jun 18 2010 340 | 1 Wed Jun 16 2010 341 | 21 Tue Jun 15 2010 342 | 1 Mon Jun 14 2010 343 | 3 Sun Jun 13 2010 344 | 8 Sat Jun 12 2010 345 | 1 Fri Jun 11 2010 346 | 1 Fri Apr 23 2010 347 | 1 Tue Jun 8 2010 348 | 4 Sat Jun 5 2010 349 | 2 Wed Jun 2 2010 350 | 1 Tue Jun 1 2010 351 | 2 Mon May 31 2010 352 | 2 Sun May 30 2010 353 | 3 Tue May 25 2010 354 | 1 Mon May 24 2010 355 | 1 Thu May 20 2010 356 | 2 Tue May 18 2010 357 | 4 Mon May 17 2010 358 | 1 Sat May 15 2010 359 | 3 Sun May 9 2010 360 | 11 Sat May 8 2010 361 | 1 Fri May 7 2010 362 | 3 Wed May 5 2010 363 | 1 Tue May 4 2010 364 | 7 Thu Apr 29 2010 365 | 4 Fri Apr 23 2010 366 | 2 Thu Apr 15 2010 367 | 10 Wed Apr 14 2010 368 | 3 Mon Apr 12 2010 369 | 2 Fri Apr 9 2010 370 | 3 Thu Apr 8 2010 371 | 6 Wed Apr 7 2010 372 | 7 Tue Apr 6 2010 373 | 7 Mon Apr 5 2010 374 | 2 Fri Apr 2 2010 375 | 7 Thu Apr 1 2010 376 | 1 Wed Mar 31 2010 377 | 1 Mon Mar 29 2010 378 | 1 Thu Mar 25 2010 379 | 2 Wed Mar 24 2010 380 | 1 Thu Mar 18 2010 381 | 3 Wed Mar 17 2010 382 | 7 Mon Mar 8 2010 383 | 1 Sun Feb 28 2010 384 | 4 Wed Feb 24 2010 385 | 1 Tue Feb 16 2010 386 | 1 Sun Feb 14 2010 387 | 1 Sat Feb 13 2010 388 | 6 Fri Feb 12 2010 389 | 3 Thu Feb 11 2010 390 | 4 Mon Feb 8 2010 391 | 4 Sat Feb 6 2010 392 | 7 Fri Feb 5 2010 393 | 3 Wed Feb 3 2010 394 | 2 Thu Feb 4 2010 395 | 8 Tue Feb 2 2010 396 | 4 Mon Feb 1 2010 397 | 6 Sun Jan 24 2010 398 | 17 Fri Jan 22 2010 399 | 4 Thu Jan 21 2010 400 | 10 Tue Jan 19 2010 401 | 2 Mon Jan 18 2010 402 | 1 Sun Jan 17 2010 403 | 1 Thu Jan 14 2010 404 | 5 Fri Jan 15 2010 405 | 3 Thu Jan 14 2010 406 | 2 Fri Jan 8 2010 407 | 2 Thu Jan 7 2010 408 | 16 Fri Jan 1 2010 409 | 19 Thu Dec 31 2009 410 | 5 Wed Dec 30 2009 411 | 6 Tue Dec 29 2009 412 | 1 Thu Oct 22 2009 413 | 3 Tue Dec 29 2009 414 | 3 Mon Dec 28 2009 415 | 3 Sun Dec 27 2009 416 | 7 Sat Dec 26 2009 417 | 4 Fri Dec 25 2009 418 | 1 Mon Dec 21 2009 419 | 10 Fri Dec 25 2009 420 | 9 Wed Dec 23 2009 421 | 23 Tue Dec 22 2009 422 | 2 Mon Dec 21 2009 423 | 4 Thu Dec 17 2009 424 | 2 Wed Dec 16 2009 425 | 3 Mon Dec 14 2009 426 | 3 Sat Dec 12 2009 427 | 9 Fri Dec 11 2009 428 | 1 Thu Dec 10 2009 429 | 5 Wed Dec 9 2009 430 | 2 Tue Dec 8 2009 431 | 3 Mon Nov 30 2009 432 | 2 Tue Nov 24 2009 433 | 6 Mon Nov 23 2009 434 | 1 Sat Nov 21 2009 435 | 11 Thu Nov 19 2009 436 | 2 Wed Nov 18 2009 437 | 2 Mon Nov 16 2009 438 | 10 Sun Nov 15 2009 439 | 7 Sat Nov 14 2009 440 | 8 Fri Nov 13 2009 441 | 5 Thu Nov 12 2009 442 | 4 Fri Nov 6 2009 443 | 2 Thu Nov 5 2009 444 | 4 Wed Nov 4 2009 445 | 4 Tue Oct 27 2009 446 | 1 Sun Oct 25 2009 447 | 4 Thu Oct 22 2009 448 | 2 Tue Oct 20 2009 449 | 2 Thu Oct 15 2009 450 | 6 Mon Oct 12 2009 451 | 2 Sat Oct 10 2009 452 | 2 Fri Oct 9 2009 453 | 2 Thu Oct 8 2009 454 | 2 Sat Oct 3 2009 455 | 1 Fri Oct 2 2009 456 | 2 Wed Sep 30 2009 457 | 6 Tue Sep 29 2009 458 | 2 Mon Sep 28 2009 459 | 4 Thu Sep 24 2009 460 | 5 Wed Sep 23 2009 461 | 5 Wed Sep 16 2009 462 | 2 Sun Sep 13 2009 463 | 2 Tue Sep 8 2009 464 | 4 Mon Sep 7 2009 465 | 4 Fri Sep 4 2009 466 | 4 Thu Sep 3 2009 467 | 2 Wed Sep 2 2009 468 | 11 Sat Aug 29 2009 469 | 3 Fri Aug 28 2009 470 | 14 Thu Aug 27 2009 471 | 3 Tue Aug 25 2009 472 | 8 Tue Aug 18 2009 473 | 14 Mon Aug 17 2009 474 | 2 Sun Aug 16 2009 475 | 2 Sat Aug 15 2009 476 | 6 Wed Aug 12 2009 477 | 8 Tue Aug 11 2009 478 | 3 Mon Aug 10 2009 479 | 1 Thu Aug 6 2009 480 | 5 Wed Aug 5 2009 481 | 4 Tue Aug 4 2009 482 | 4 Sun Aug 2 2009 483 | 1 Sat Aug 1 2009 484 | 12 Fri Jul 31 2009 485 | 15 Thu Jul 30 2009 486 | 4 Wed Jul 29 2009 487 | 5 Sat Jul 25 2009 488 | 1 Sun Jul 19 2009 489 | 7 Sat Jul 18 2009 490 | 4 Fri Jul 17 2009 491 | 10 Thu Jul 16 2009 492 | 8 Mon Jul 13 2009 493 | 8 Sun Jul 12 2009 494 | 5 Sat Jul 11 2009 495 | 2 Fri Jul 10 2009 496 | 15 Wed Jul 8 2009 497 | 2 Tue Jul 7 2009 498 | 2 Mon Jul 6 2009 499 | 2 Tue Jun 30 2009 500 | 2 Fri Jun 26 2009 501 | 2 Wed Jun 17 2009 502 | 2 Mon Jun 15 2009 503 | 2 Sat Jun 6 2009 504 | 16 Thu Jun 4 2009 505 | 2 Tue Jun 2 2009 506 | 4 Mon Jun 1 2009 507 | 2 Sun May 31 2009 508 | 2 Fri May 29 2009 509 | 1 Wed May 20 2009 510 | 1 Tue May 19 2009 511 | 3 Thu May 14 2009 512 | 7 Tue May 12 2009 513 | 4 Mon May 11 2009 514 | 1 Fri May 8 2009 515 | 4 Wed May 6 2009 516 | 3 Sat May 2 2009 517 | 5 Fri May 1 2009 518 | 8 Thu Apr 30 2009 519 | 2 Tue Apr 28 2009 520 | 2 Mon Apr 27 2009 521 | 1 Sat Apr 25 2009 522 | 4 Wed Apr 22 2009 523 | 2 Tue Apr 21 2009 524 | 2 Mon Apr 20 2009 525 | 2 Wed Apr 15 2009 526 | 16 Tue Apr 14 2009 527 | 5 Mon Apr 13 2009 528 | 4 Sun Apr 12 2009 529 | 4 Sat Apr 11 2009 530 | 9 Fri Apr 10 2009 531 | 8 Thu Apr 9 2009 532 | 8 Mon Apr 6 2009 533 | 3 Sat Apr 4 2009 534 | 2 Fri Apr 3 2009 535 | 5 Thu Apr 2 2009 536 | 2 Tue Mar 31 2009 537 | 2 Sat Mar 28 2009 538 | 8 Thu Mar 26 2009 539 | 2 Wed Mar 25 2009 540 | 1 Tue Mar 24 2009 541 | 8 Sun Mar 22 2009 542 | 2 Sat Mar 21 2009 543 | 4 Tue Mar 17 2009 544 | 3 Sun Mar 8 2009 545 | 1 Fri Mar 6 2009 546 | 2 Mon Mar 2 2009 547 | 3 Sun Mar 1 2009 548 | 1 Sat Feb 28 2009 549 | 4 Thu Feb 26 2009 550 | 11 Wed Feb 25 2009 551 | 8 Tue Feb 24 2009 552 | 2 Mon Feb 23 2009 553 | 2 Sat Feb 21 2009 554 | 2 Fri Feb 20 2009 555 | 2 Thu Feb 19 2009 556 | 4 Wed Feb 18 2009 557 | 2 Tue Feb 17 2009 558 | 3 Sun Feb 15 2009 559 | 3 Sat Feb 14 2009 560 | 1 Fri Feb 13 2009 561 | 9 Wed Feb 11 2009 562 | 3 Tue Feb 10 2009 563 | 2 Sun Feb 8 2009 564 | 2 Sat Feb 7 2009 565 | 2 Fri Feb 6 2009 566 | 2 Wed Feb 4 2009 567 | 2 Tue Feb 3 2009 568 | 5 Mon Feb 2 2009 569 | 9 Sun Feb 1 2009 570 | 4 Sat Jan 31 2009 571 | 8 Fri Jan 30 2009 572 | 1 Wed Jan 28 2009 573 | 7 Tue Jan 27 2009 574 | 3 Mon Jan 26 2009 575 | 4 Sun Jan 25 2009 576 | 2 Sat Jan 24 2009 577 | 6 Thu Jan 22 2009 578 | 13 Wed Jan 21 2009 579 | 3 Tue Jan 20 2009 580 | 12 Mon Jan 19 2009 581 | 5 Sat Jan 17 2009 582 | 4 Fri Jan 16 2009 583 | 5 Thu Jan 15 2009 584 | 2 Wed Jan 14 2009 585 | 5 Tue Jan 13 2009 586 | 2 Sat Jan 10 2009 587 | 5 Fri Jan 9 2009 588 | 9 Thu Jan 8 2009 589 | 2 Tue Jan 6 2009 590 | 2 Sat Jan 3 2009 591 | 7 Fri Jan 2 2009 592 | 4 Thu Jan 1 2009 593 | 6 Wed Dec 31 2008 594 | 4 Mon Dec 29 2008 595 | 7 Thu Dec 25 2008 596 | 2 Wed Dec 24 2008 597 | 8 Tue Dec 23 2008 598 | 4 Mon Dec 22 2008 599 | 4 Sun Dec 21 2008 600 | 4 Sat Dec 20 2008 601 | 4 Fri Dec 19 2008 602 | 2 Thu Dec 18 2008 603 | 7 Wed Dec 17 2008 604 | 9 Tue Dec 16 2008 605 | 13 Sun Dec 14 2008 606 | 1 Sat Dec 13 2008 607 | 3 Fri Dec 12 2008 608 | 2 Thu Dec 11 2008 609 | 12 Wed Dec 10 2008 610 | 5 Tue Dec 9 2008 611 | 2 Mon Dec 8 2008 612 | 4 Thu Dec 4 2008 613 | 2 Wed Dec 3 2008 614 | 4 Mon Dec 1 2008 615 | 1 Sat Nov 29 2008 616 | 2 Thu Nov 27 2008 617 | 5 Wed Nov 26 2008 618 | 4 Tue Nov 25 2008 619 | 5 Mon Nov 24 2008 620 | 8 Sun Nov 23 2008 621 | 4 Sat Nov 22 2008 622 | 4 Fri Nov 21 2008 623 | 2 Thu Nov 20 2008 624 | 2 Wed Nov 19 2008 625 | 3 Tue Nov 18 2008 626 | 1 Sun Nov 16 2008 627 | 2 Fri Nov 14 2008 628 | 2 Thu Nov 13 2008 629 | 1 Wed Nov 12 2008 630 | 1 Tue Nov 11 2008 631 | 1 Mon Nov 10 2008 632 | 8 Sat Nov 8 2008 633 | 1 Fri Nov 7 2008 634 | 1 Thu Nov 6 2008 635 | 5 Tue Nov 4 2008 636 | 1 Mon Nov 3 2008 637 | 1 Sat Nov 1 2008 638 | 2 Wed Oct 29 2008 639 | 4 Sun Oct 26 2008 640 | 1 Sat Oct 25 2008 641 | 1 Fri Oct 24 2008 642 | 1 Thu Oct 23 2008 643 | 1 Wed Oct 22 2008 644 | 1 Tue Oct 21 2008 645 | 1 Mon Oct 20 2008 646 | 2 Sun Oct 19 2008 647 | 1 Sat Oct 18 2008 648 | 1 Thu Oct 16 2008 649 | 4 Wed Oct 15 2008 650 | 1 Mon Oct 13 2008 651 | 1 Sun Oct 12 2008 652 | 1 Sun Oct 5 2008 653 | 1 Thu Oct 2 2008 654 | 1 Wed Sep 24 2008 655 | 1 Sun Sep 21 2008 656 | 1 Tue Sep 16 2008 657 | 1 Mon Sep 15 2008 658 | 1 Thu Sep 11 2008 659 | 1 Wed Sep 10 2008 660 | 1 Tue Sep 9 2008 661 | 5 Thu Sep 4 2008 662 | 3 Wed Sep 3 2008 663 | 4 Mon Sep 1 2008 664 | 4 Sun Aug 31 2008 665 | 7 Sat Aug 30 2008 666 | 2 Fri Aug 29 2008 667 | 1 Thu Aug 28 2008 668 | 5 Wed Aug 27 2008 669 | 3 Tue Aug 26 2008 670 | 3 Mon Aug 25 2008 671 | 4 Sun Aug 24 2008 672 | 7 Sat Aug 23 2008 673 | 3 Fri Aug 22 2008 674 | 4 Thu Aug 21 2008 675 | 3 Sun Aug 17 2008 676 | 2 Sat Aug 16 2008 677 | 6 Fri Aug 15 2008 678 | 2 Thu Aug 14 2008 679 | 2 Fri Aug 8 2008 680 | 2 Thu Aug 7 2008 681 | 2 Tue Aug 5 2008 682 | 2 Mon Aug 4 2008 683 | 1 Tue Jul 29 2008 684 | 10 Tue Jul 22 2008 685 | 4 Fri Jul 18 2008 686 | 7 Wed Jul 16 2008 687 | 6 Mon Jul 14 2008 688 | 4 Sat Jul 12 2008 689 | 2 Fri Jul 11 2008 690 | 9 Thu Jul 10 2008 691 | 6 Wed Jul 9 2008 692 | 6 Mon Jul 7 2008 693 | 6 Thu Jul 3 2008 694 | 2 Wed Jul 2 2008 695 | 10 Mon Jun 30 2008 696 | 12 Sat Jun 28 2008 697 | 6 Fri Jun 27 2008 698 | 2 Thu Jun 26 2008 699 | 4 Tue Jun 24 2008 700 | 2 Thu Jun 19 2008 701 | 2 Wed Jun 18 2008 702 | 7 Mon Jun 16 2008 703 | 2 Fri Jun 13 2008 704 | 3 Tue Jun 10 2008 705 | 8 Mon Jun 9 2008 706 | 13 Sun Jun 8 2008 707 | 11 Sat Jun 7 2008 708 | 4 Fri Jun 6 2008 709 | 4 Thu Jun 5 2008 710 | 4 Wed Jun 4 2008 711 | 18 Sat May 31 2008 712 | 7 Fri May 30 2008 713 | 4 Thu May 29 2008 714 | 4 Sun May 25 2008 715 | 2 Thu May 22 2008 716 | 2 Fri May 9 2008 717 | 6 Thu May 8 2008 718 | 2 Wed May 7 2008 719 | 4 Sun May 4 2008 720 | 4 Sat May 3 2008 721 | 2 Thu May 1 2008 722 | 14 Wed Apr 30 2008 723 | 2 Tue Apr 29 2008 724 | 8 Thu Apr 24 2008 725 | 3 Wed Apr 23 2008 726 | 8 Sun Apr 20 2008 727 | 2 Thu Apr 17 2008 728 | 4 Tue Apr 15 2008 729 | 3 Mon Apr 14 2008 730 | 4 Fri Apr 11 2008 731 | 4 Thu Apr 10 2008 732 | 8 Wed Apr 9 2008 733 | 4 Mon Apr 7 2008 734 | 2 Sun Apr 6 2008 735 | 4 Fri Apr 4 2008 736 | 8 Thu Apr 3 2008 737 | 2 Wed Apr 2 2008 738 | 4 Fri Mar 28 2008 739 | 2 Sat Mar 22 2008 740 | 4 Fri Mar 21 2008 741 | 5 Wed Mar 19 2008 742 | 4 Mon Mar 17 2008 743 | 2 Wed Mar 12 2008 744 | 2 Thu Mar 6 2008 745 | 4 Mon Mar 3 2008 746 | 2 Sat Mar 1 2008 747 | 1 Fri Feb 29 2008 748 | 2 Wed Feb 27 2008 749 | 2 Sun Feb 24 2008 750 | 2 Fri Feb 22 2008 751 | 2 Wed Feb 20 2008 752 | 6 Tue Feb 19 2008 753 | 2 Mon Feb 18 2008 754 | 6 Sat Feb 16 2008 755 | 6 Fri Feb 15 2008 756 | 4 Thu Feb 14 2008 757 | 1 Tue Feb 12 2008 758 | 6 Sun Feb 10 2008 759 | 9 Sat Feb 9 2008 760 | 3 Fri Feb 8 2008 761 | 4 Thu Feb 7 2008 762 | 12 Wed Feb 6 2008 763 | 6 Tue Feb 5 2008 764 | 4 Wed Jan 30 2008 765 | 2 Tue Jan 29 2008 766 | 2 Fri Jan 25 2008 767 | 2 Wed Jan 23 2008 768 | 11 Tue Jan 22 2008 769 | 3 Sat Jan 19 2008 770 | 15 Fri Jan 18 2008 771 | 20 Thu Jan 17 2008 772 | 4 Wed Jan 16 2008 773 | 8 Tue Jan 15 2008 774 | 8 Mon Jan 14 2008 775 | 2 Sun Jan 13 2008 776 | 2 Wed Jan 9 2008 777 | 8 Tue Jan 8 2008 778 | 2 Sun Dec 30 2007 779 | 5 Thu Dec 27 2007 780 | 4 Wed Dec 26 2007 781 | 4 Tue Dec 25 2007 782 | 1 Mon Dec 24 2007 783 | 6 Sun Dec 23 2007 784 | 2 Fri Dec 21 2007 785 | 2 Thu Dec 20 2007 786 | 4 Wed Dec 19 2007 787 | 7 Tue Dec 18 2007 788 | 6 Mon Dec 17 2007 789 | 1 Sun Dec 16 2007 790 | 3 Thu Dec 13 2007 791 | 2 Wed Dec 12 2007 792 | 6 Tue Dec 11 2007 793 | 7 Mon Dec 10 2007 794 | 4 Sun Dec 9 2007 795 | 3 Sat Dec 8 2007 796 | 7 Thu Dec 6 2007 797 | 9 Wed Dec 5 2007 798 | 4 Tue Dec 4 2007 799 | 2 Sat Dec 1 2007 800 | 2 Fri Nov 30 2007 801 | 12 Wed Nov 28 2007 802 | 18 Tue Nov 27 2007 803 | 3 Sun Nov 25 2007 804 | 5 Sat Nov 24 2007 805 | 2 Fri Nov 23 2007 806 | 4 Wed Nov 21 2007 807 | 4 Tue Nov 20 2007 808 | 18 Mon Nov 19 2007 809 | 5 Sun Nov 18 2007 810 | 10 Fri Nov 16 2007 811 | 1 Thu Nov 15 2007 812 | 3 Wed Nov 14 2007 813 | 13 Tue Nov 13 2007 814 | 6 Mon Nov 12 2007 815 | 10 Sun Nov 11 2007 816 | 6 Fri Nov 9 2007 817 | 3 Thu Nov 8 2007 818 | 3 Wed Nov 7 2007 819 | 3 Sun Nov 4 2007 820 | 2 Sat Nov 3 2007 821 | 4 Fri Nov 2 2007 822 | 7 Thu Nov 1 2007 823 | 2 Wed Oct 31 2007 824 | 5 Tue Oct 30 2007 825 | 7 Mon Oct 29 2007 826 | 3 Sun Oct 28 2007 827 | 3 Sat Oct 27 2007 828 | 4 Wed Oct 24 2007 829 | 2 Tue Oct 23 2007 830 | 5 Mon Oct 22 2007 831 | 3 Sun Oct 21 2007 832 | 7 Sat Oct 20 2007 833 | 3 Fri Oct 19 2007 834 | 9 Thu Oct 18 2007 835 | 7 Wed Oct 17 2007 836 | 1 Tue Oct 16 2007 837 | 1 Mon Oct 15 2007 838 | 1 Sat Oct 13 2007 839 | 1 Fri Oct 12 2007 840 | 1 Sat Oct 6 2007 841 | 1 Thu Oct 4 2007 842 | 4 Wed Oct 3 2007 843 | 3 Mon Oct 1 2007 844 | 1 Sat Sep 29 2007 845 | 1 Fri Sep 28 2007 846 | 2 Thu Sep 27 2007 847 | 1 Mon Sep 24 2007 848 | 1 Fri Sep 14 2007 849 | 1 Wed Sep 12 2007 850 | 2 Tue Sep 11 2007 851 | 4 Sun Sep 9 2007 852 | 2 Fri Sep 7 2007 853 | 4 Thu Sep 6 2007 854 | 3 Wed Sep 5 2007 855 | 2 Tue Sep 4 2007 856 | 5 Mon Sep 3 2007 857 | 5 Sun Sep 2 2007 858 | 11 Sat Sep 1 2007 859 | 9 Fri Aug 31 2007 860 | 3 Thu Aug 30 2007 861 | 5 Wed Aug 29 2007 862 | 4 Tue Aug 28 2007 863 | 5 Wed Aug 22 2007 864 | 8 Tue Aug 21 2007 865 | 3 Mon Aug 20 2007 866 | 1 Sun Aug 19 2007 867 | 5 Sat Aug 18 2007 868 | 5 Fri Aug 17 2007 869 | 5 Thu Aug 16 2007 870 | 1 Wed Aug 15 2007 871 | 5 Sat Aug 11 2007 872 | 8 Fri Aug 10 2007 873 | 4 Thu Aug 9 2007 874 | 11 Wed Aug 8 2007 875 | 11 Tue Aug 7 2007 876 | 8 Mon Aug 6 2007 877 | 4 Sun Aug 5 2007 878 | 5 Sat Aug 4 2007 879 | 12 Fri Aug 3 2007 880 | 11 Thu Aug 2 2007 881 | 3 Wed Aug 1 2007 882 | 1 Tue Jul 31 2007 883 | 2 Mon Jul 30 2007 884 | 1 Sun Jul 29 2007 885 | 2 Sat Jul 28 2007 886 | 1 Fri Jul 27 2007 887 | 4 Thu Jul 26 2007 888 | 1 Wed Jul 25 2007 889 | 1 Mon Jul 23 2007 890 | 1 Sun Jul 22 2007 891 | 1 Sat Jul 21 2007 892 | 2 Fri Jul 20 2007 893 | 5 Thu Jul 19 2007 894 | 1 Sun Jul 15 2007 895 | 3 Thu Jul 12 2007 896 | 6 Wed Jul 11 2007 897 | 1 Mon Jul 9 2007 898 | 2 Sun Jul 8 2007 899 | 1 Fri Jul 6 2007 900 | 3 Thu Jul 5 2007 901 | 1 Wed Jul 4 2007 902 | 7 Tue Jul 3 2007 903 | 6 Mon Jul 2 2007 904 | 4 Sun Jul 1 2007 905 | 1 Sat Jun 30 2007 906 | 3 Thu Jun 28 2007 907 | 1 Tue Jun 26 2007 908 | 4 Sun Jun 24 2007 909 | 2 Sat Jun 23 2007 910 | 1 Fri Jun 22 2007 911 | 2 Thu Jun 21 2007 912 | 2 Wed Jun 20 2007 913 | 7 Tue Jun 19 2007 914 | 1 Sat Jun 16 2007 915 | 1 Thu Jun 14 2007 916 | 1 Sat Jun 2 2007 917 | 2 Mon May 28 2007 918 | 5 Fri May 25 2007 919 | 1 Sun May 6 2007 920 | 1 Mon Apr 30 2007 921 | 1 Fri Apr 27 2007 922 | 1 Thu Apr 26 2007 923 | 1 Wed Apr 18 2007 924 | 2 Mon Apr 16 2007 925 | 2 Sun Apr 15 2007 926 | 3 Fri Apr 13 2007 927 | 9 Tue Apr 3 2007 928 | 2 Mon Apr 2 2007 929 | 2 Fri Mar 30 2007 930 | 2 Wed Mar 28 2007 931 | 9 Mon Mar 26 2007 932 | 2 Sun Mar 25 2007 933 | 4 Sat Mar 24 2007 934 | 2 Fri Mar 23 2007 935 | 2 Thu Mar 22 2007 936 | 2 Tue Mar 20 2007 937 | 6 Sun Mar 18 2007 938 | 10 Fri Mar 16 2007 939 | 4 Thu Mar 15 2007 940 | 4 Wed Mar 14 2007 941 | 2 Tue Mar 13 2007 942 | 2 Sun Mar 11 2007 943 | 2 Sun Mar 4 2007 944 | 8 Sat Mar 3 2007 945 | 1 Fri Mar 2 2007 946 | 2 Thu Mar 1 2007 947 | 3 Mon Feb 26 2007 948 | 14 Sun Feb 25 2007 949 | 11 Sat Feb 24 2007 950 | 15 Thu Feb 22 2007 951 | 8 Wed Feb 21 2007 952 | 27 Tue Feb 20 2007 953 | 8 Mon Feb 19 2007 954 | 1 Sun Feb 18 2007 955 | 1 Sat Feb 17 2007 956 | 3 Wed Feb 14 2007 957 | 5 Tue Feb 13 2007 958 | 8 Mon Feb 12 2007 959 | 2 Sat Feb 10 2007 960 | 4 Wed Feb 7 2007 961 | 1 Tue Feb 6 2007 962 | 1 Fri Feb 2 2007 963 | 1 Sun Jan 28 2007 964 | 1 Wed Jan 24 2007 965 | 2 Fri Jan 19 2007 966 | 1 Thu Jan 18 2007 967 | 3 Tue Jan 16 2007 968 | 6 Mon Jan 15 2007 969 | 2 Sun Jan 14 2007 970 | 8 Sat Jan 13 2007 971 | 1 Thu Jan 11 2007 972 | 2 Wed Jan 10 2007 973 | 1 Sun Jan 7 2007 974 | 2 Wed Dec 27 2006 975 | 2 Sun Dec 24 2006 976 | 3 Sat Dec 9 2006 977 | 1 Wed Dec 6 2006 978 | 1 Wed Nov 22 2006 979 | 3 Tue Nov 21 2006 980 | 4 Sun Nov 19 2006 981 | 1 Fri Nov 17 2006 982 | 1 Thu Nov 16 2006 983 | 2 Wed Nov 15 2006 984 | 2 Tue Nov 14 2006 985 | 2 Mon Nov 13 2006 986 | 7 Sat Nov 11 2006 987 | 9 Fri Nov 10 2006 988 | 5 Thu Nov 9 2006 989 | 4 Wed Nov 8 2006 990 | 13 Tue Nov 7 2006 991 | 3 Mon Nov 6 2006 992 | 4 Sun Nov 5 2006 993 | 1 Sat Nov 4 2006 994 | 1 Thu Oct 19 2006 995 | 3 Wed Oct 18 2006 996 | 4 Mon Oct 16 2006 997 | 2 Sun Oct 15 2006 998 | 1 Sat Oct 14 2006 999 | 2 Fri Oct 13 2006 1000 | 2 Thu Oct 12 2006 1001 | 1 Wed Oct 11 2006 1002 | 2 Mon Oct 9 2006 1003 | 3 Fri Oct 6 2006 1004 | 4 Thu Oct 5 2006 1005 | 3 Wed Oct 4 2006 1006 | 1 Sat Sep 30 2006 1007 | 5 Fri Sep 29 2006 1008 | 2 Thu Sep 28 2006 1009 | 3 Wed Sep 27 2006 1010 | 12 Tue Sep 26 2006 1011 | 5 Mon Sep 25 2006 1012 | 7 Sun Sep 24 2006 1013 | 2 Sat Sep 23 2006 1014 | 9 Thu Sep 21 2006 1015 | 4 Wed Sep 20 2006 1016 | 2 Mon Sep 18 2006 1017 | 1 Thu Sep 14 2006 1018 | 3 Wed Sep 13 2006 1019 | 5 Tue Sep 12 2006 1020 | 2 Mon Sep 11 2006 1021 | 6 Sun Sep 10 2006 1022 | 3 Fri Sep 8 2006 1023 | 1 Thu Sep 7 2006 1024 | 3 Wed Sep 6 2006 1025 | 3 Tue Sep 5 2006 1026 | 1 Sun Sep 3 2006 1027 | 5 Tue Aug 29 2006 1028 | 1 Mon Aug 28 2006 1029 | 3 Sun Aug 27 2006 1030 | 3 Wed Aug 23 2006 1031 | 3 Fri Aug 18 2006 1032 | 2 Thu Aug 17 2006 1033 | 1 Wed Aug 16 2006 1034 | 2 Tue Aug 15 2006 1035 | 2 Mon Aug 14 2006 1036 | 4 Sun Aug 13 2006 1037 | 8 Sat Aug 12 2006 1038 | 4 Fri Aug 11 2006 1039 | 2 Thu Aug 10 2006 1040 | 3 Wed Aug 9 2006 1041 | 2 Tue Aug 8 2006 1042 | 1 Mon Aug 7 2006 1043 | 1 Fri Aug 4 2006 1044 | 2 Thu Aug 3 2006 1045 | 1 Wed Aug 2 2006 1046 | 1 Fri Jul 7 2006 1047 | 2 Thu Jul 6 2006 1048 | 1 Wed Jul 5 2006 1049 | 3 Tue Jul 4 2006 1050 | 5 Fri Jun 30 2006 1051 | 3 Thu Jun 29 2006 1052 | -------------------------------------------------------------------------------- /tests/lib/line_plot_above_100_data_points_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-5f23cb7529be3599b0d200bdf85af5b33040c7e5.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | ruby -e 'x=1; 101.times {puts (x *= 1.02).to_s + " lorem ipsum"}' | \ 8 | bin/sparkler > /dev/null && \ 9 | diff tests/plots/more_than_100_data_points.png $actual 10 | -------------------------------------------------------------------------------- /tests/lib/line_plot_below_100_data_points_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-3dafba200d5ce30cc8b6f1c7fe6a87ebba8626f1.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | 8 | 9 | ruby -e 'x=1; 100.times {puts (x *= 1.02).to_s + " lorem ipsum"}' | \ 10 | bin/sparkler > /dev/null && \ 11 | diff tests/plots/line_plot_below_100_data_points.png $actual 12 | -------------------------------------------------------------------------------- /tests/lib/many_labels_50_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-ee3e64910e82f16bcfd238702fe262a15923a514.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | 8 | 9 | ruby -e 'x=1; 50.times {puts (x += 1).to_s + " lorem ipsum"}' | \ 10 | bin/sparkler > /dev/null && \ 11 | diff tests/plots/many_labels_50.png $actual 12 | -------------------------------------------------------------------------------- /tests/lib/phpunit_commits_per_day_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-7242742ee4624514e65b0e972e4b7306a42a3f2d.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | tac tests/fixtures/phpunit_commits_per_day | \ 8 | bin/sparkler > /dev/null && \ 9 | diff tests/plots/phpunit_commits_per_day.png $actual 10 | -------------------------------------------------------------------------------- /tests/lib/regular_args_with_labels_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-c0a3075e1aef64a480f4960acfb897faa5ec65e2.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | 8 | 9 | bin/sparkler > /dev/null '233 carl lenny 10 | 377 lisa milhouse 11 | 610 burns smithers' && \ 12 | diff tests/plots/regular_args_with_labels.png $actual 13 | -------------------------------------------------------------------------------- /tests/lib/regular_arguments.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-9ee5a8d183642ce661f2ca182dead4457215ee01.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | set -x 8 | 9 | bin/sparkler 55 89 144 && \ 10 | diff tests/plots/regular_arguments.png $actual 11 | -------------------------------------------------------------------------------- /tests/lib/values_newline_delimited_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | actual=./graph-eda93b565715058fdfce1ccbfdc9c5018cb7066f.png 4 | 5 | test -e $actual && rm $actual 6 | 7 | echo "3 8 | 5 9 | 8" | bin/sparkler > /dev/null && \ 10 | diff tests/plots/values_newline_delimited.png $actual 11 | 12 | -------------------------------------------------------------------------------- /tests/lib/values_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # The sha1 hash in the name of the file is constructed from the 4 | # argument list. So the same argument list should always produce the 5 | # same file name. 6 | 7 | actual=./graph-e7001334d9d19559a8bb0dd6015f16e31d15566c.png 8 | 9 | test -e $actual && rm $actual 10 | 11 | 12 | 13 | echo 0 1 1 | bin/sparkler > /dev/null && \ 14 | diff tests/plots/values.png $actual 15 | -------------------------------------------------------------------------------- /tests/lib/values_with_labels_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | 5 | actual=./graph-3f1c78fb398dba2115de388aaceaedb37f1019a7.png 6 | 7 | test -e $actual && rm $actual 8 | 9 | 10 | 11 | echo "13 foo bar 12 | 21 baz boz 13 | 34 homer marge" | bin/sparkler > /dev/null && \ 14 | diff tests/plots/values_with_labels.png $actual 15 | 16 | -------------------------------------------------------------------------------- /tests/options.py: -------------------------------------------------------------------------------- 1 | import argparse, sys 2 | 3 | print sys.argv 4 | 5 | parser = argparse.ArgumentParser(description='sparkler: make simple graphical plots.') 6 | 7 | parser.add_argument('values', metavar='N [label]', nargs='+', 8 | help='an integer for the accumulator') 9 | 10 | parser.add_argument( 11 | '-o, --output', 12 | metavar='', 13 | dest='output_file', 14 | help='name of the output file (default is ./my_graph.png)' 15 | ) 16 | 17 | args = parser.parse_args() 18 | 19 | print args 20 | 21 | -------------------------------------------------------------------------------- /tests/plots/line_plot_below_100_data_points.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/line_plot_below_100_data_points.png -------------------------------------------------------------------------------- /tests/plots/many_labels_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/many_labels_50.png -------------------------------------------------------------------------------- /tests/plots/more_than_100_data_points.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/more_than_100_data_points.png -------------------------------------------------------------------------------- /tests/plots/phpunit_commits_per_day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/phpunit_commits_per_day.png -------------------------------------------------------------------------------- /tests/plots/regular_args_with_labels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/regular_args_with_labels.png -------------------------------------------------------------------------------- /tests/plots/regular_arguments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/regular_arguments.png -------------------------------------------------------------------------------- /tests/plots/values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/values.png -------------------------------------------------------------------------------- /tests/plots/values_newline_delimited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/values_newline_delimited.png -------------------------------------------------------------------------------- /tests/plots/values_with_labels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/context-driven-testing-toolkit/sparkler/b9e7ea44afcefa85a3294463463f786bbd586537/tests/plots/values_with_labels.png -------------------------------------------------------------------------------- /tests/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | time find tests/lib -name *_test.sh | \ 4 | parallel -j0 'sh {} && echo -n . || (echo FAILED: {} && exit 1)' && \ 5 | echo && echo "SUCCESS! All tests passed." || (echo && echo FAILURE && exit 1) 6 | --------------------------------------------------------------------------------