meetup-generator 0.0.20210128 → 1.2.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ require_relative 'version'
2
+
3
+ def gem_version
4
+ format('%s.%s', BASE_VERSION, build_number)
5
+ end
6
+
7
+ def build_number
8
+ ENV['TRAVIS_BUILD_NUMBER'] || 0
9
+ end
@@ -0,0 +1,63 @@
1
+ require 'json'
2
+ require 'yaml'
3
+
4
+ # Everything needed for a meetup generator
5
+ #
6
+ class MeetupGenerator
7
+ attr_reader :words, :lib, :unused_templates
8
+
9
+ def initialize
10
+ grep, dict = find_unix_stuff
11
+ @words = `#{grep} "^[a-z]*$" #{dict}`.split("\n")
12
+ @lib = YAML.load_file(ROOT + 'lib' + 'all_the_things.yaml')
13
+ end
14
+
15
+ def find_unix_stuff
16
+ case RUBY_PLATFORM
17
+ when /solaris/
18
+ %w[/bin/grep /usr/share/lib/dict/words]
19
+ when /linux/
20
+ %w[/bin/grep /usr/share/dict/words]
21
+ when /darwin/
22
+ %w[/usr/bin/grep /usr/share/dict/words]
23
+ else
24
+ abort "unsupported platform: #{RUBY_PLATFORM}"
25
+ end
26
+ end
27
+
28
+ def title
29
+ @unused_templates ||= lib[:template].dup
30
+ t = unused_templates.sample
31
+ unused_templates.delete(t)
32
+ t.scan(/%\w+%/).each { |k| t = t.sub(k, lib[k[1..-2].to_sym].sample) }
33
+ t.scan(/RAND\d+/).each do |i|
34
+ t = t.sub(i, rand(2..(i.sub(/RAND/, '').to_i)).to_s)
35
+ end
36
+ t
37
+ end
38
+
39
+ def talks(count = 5)
40
+ @unused_templates = lib[:template].dup
41
+ count.times.with_object([]) { |_i, a| a.<< title }
42
+ end
43
+
44
+ def talker
45
+ lib[:first_name].sample + ' ' + lib[:last_name].sample
46
+ end
47
+
48
+ def role
49
+ lib[:job_role].sample + ' ' + lib[:job_title].sample
50
+ end
51
+
52
+ def company
53
+ words.sample.sub(/([^aeiou])er$/, '\\1r').downcase + '.io'
54
+ end
55
+
56
+ def refreshment
57
+ lib[:food_style].sample + ' ' + lib[:food].sample
58
+ end
59
+
60
+ def talk
61
+ { talk: talks(1)[0], talker: talker, role: role, company: company }
62
+ end
63
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,4 @@
1
+ # We define the major and minor here. The patch version comes from
2
+ # the Travis build number
3
+ #
4
+ BASE_VERSION = '1.2'.freeze
@@ -1,13 +1,11 @@
1
- # frozen_string_literal: true
2
-
1
+ require 'pathname'
3
2
  require 'date'
4
-
5
- # Github actions sets the RELEASE_VERSION environment variable
3
+ require 'English'
4
+ require_relative 'lib/build_helpers'
6
5
 
7
6
  Gem::Specification.new do |gem|
8
7
  gem.name = 'meetup-generator'
9
- gem.version = ENV['RELEASE_VERSION'] ||
10
- "0.0.#{Time.now.strftime('%Y%m%d')}"
8
+ gem.version = gem_version
11
9
  gem.date = Date.today.to_s
12
10
 
13
11
  gem.summary = 'Stupid fatuous random string generatpr'
@@ -15,29 +13,23 @@ Gem::Specification.new do |gem|
15
13
  'DevOps meetup, using all the latest buzzwords, ' \
16
14
  'new-shiny, and clichés'
17
15
  gem.authors = ['Robert Fisher']
18
- gem.email = 'rob@sysdef.xyz'
16
+ gem.email = 'slackboy@gmail.com'
19
17
  gem.homepage = 'https://github.com/snltd/meetup-generator'
20
18
  gem.license = 'BSD-2-Clause'
21
19
 
22
- gem.bindir = 'bin'
23
- gem.executables = ['meetup-generator.rb', 'locate_meetup-generator']
24
- gem.files = IO.readlines('package/runtime_files', chomp: true)
20
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
25
21
  gem.test_files = gem.files.grep(%r{^spec/})
26
- gem.require_paths = %w[lib]
27
22
 
28
- gem.add_runtime_dependency 'puma', '~> 5.1'
29
- gem.add_runtime_dependency 'sinatra', '~>2.1'
30
- gem.add_runtime_dependency 'slim', '~> 4.1'
23
+ gem.add_runtime_dependency 'sinatra', '~>2.0', '>= 2.0.1'
24
+ gem.add_runtime_dependency 'slim', '~> 3.0', '>= 3.0.0'
25
+ gem.add_runtime_dependency 'puma', '~> 3.11', '>= 3.11.0'
31
26
 
32
- gem.add_development_dependency 'bundler', '~> 2.0'
33
- gem.add_development_dependency 'minitest', '~> 5.14'
34
- gem.add_development_dependency 'nokogiri', '~> 1.10'
35
- gem.add_development_dependency 'rack-test', '~> 1.1'
36
- gem.add_development_dependency 'rake', '~> 13.0'
37
- gem.add_development_dependency 'rubocop', '~> 1.9'
38
- gem.add_development_dependency 'rubocop-minitest', '~> 0.10'
39
- gem.add_development_dependency 'rubocop-performance', '~> 1.3'
40
- gem.add_development_dependency 'rubocop-rake', '~> 0.5'
27
+ gem.add_development_dependency 'bundler', '~> 1.3'
28
+ gem.add_development_dependency 'minitest', '~> 5.11', '>= 5.11.0'
29
+ gem.add_development_dependency 'nokogiri', '~> 1.8', '>= 1.8.0'
30
+ gem.add_development_dependency 'rack-test', '~> 0.8', '>= 0.8.0'
31
+ gem.add_development_dependency 'rake', '~> 12.3', '>= 12.3.0'
32
+ gem.add_development_dependency 'rubocop', '~> 0.52', '>= 0.52.0'
41
33
 
42
- gem.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
34
+ gem.required_ruby_version = Gem::Requirement.new('>= 2.2.0')
43
35
  end
data/public/css/main.css CHANGED
@@ -11,15 +11,11 @@ body {
11
11
  line-height: 120%;
12
12
  }
13
13
 
14
- .indent {
14
+ .tperson {
15
15
  font-size: small;
16
16
  margin-left: 12em;
17
17
  }
18
18
 
19
- .indent a {
20
- color: #0f0;
21
- }
22
-
23
19
  ul {
24
20
  list-style: none;
25
21
  }
@@ -31,6 +27,7 @@ li {
31
27
  }
32
28
 
33
29
  .ttitle {
30
+ /*font-style: italic;*/
34
31
  font-weight: bold;
35
32
  background-color: #0ff;
36
33
  color: #000;
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
2
+ #
3
+ # Acceptance tests for the meetup generator. Yeah, I know.
4
+ #
4
5
  %w[minitest minitest/unit minitest/autorun rack/test pathname json
5
6
  yaml cgi nokogiri].each { |f| require f }
6
7
 
@@ -8,25 +9,21 @@ MGROOT = Pathname.new(__FILE__).realpath.dirname.parent
8
9
 
9
10
  OUTER_APP = Rack::Builder.parse_file((MGROOT + 'config.ru').to_s).first
10
11
 
11
- # Acceptance tests for the meetup generator. Yeah, I know.
12
- #
13
12
  class TestApp < MiniTest::Test
14
13
  attr_reader :things
15
-
16
14
  include Rack::Test::Methods
17
15
 
18
16
  def initialize(args)
19
17
  super(args)
20
- @things = YAML.safe_load(IO.read(MGROOT + 'lib' + 'all_the_things.yaml'),
21
- symbolize_names: true)
18
+ @things = YAML.load_file(MGROOT + 'lib' + 'all_the_things.yaml')
22
19
  end
23
20
 
24
21
  def app
25
22
  OUTER_APP
26
23
  end
27
24
 
28
- # Load the page a thousand times and make sure no talk titles
29
- # occur twice
25
+ # Load the page 1000 times and make sure no talk titles occur
26
+ # twice
30
27
  #
31
28
  def test_no_repeats
32
29
  1000.times do
@@ -36,80 +33,54 @@ class TestApp < MiniTest::Test
36
33
  end
37
34
  end
38
35
 
39
- # Get all of the templates used to generate talk titles, and
40
- # re-run the test until we've seen them all. Then we know no
41
- # template causes a crash. That's good enough.
42
- #
43
36
  def test_default
37
+ #
38
+ # Get all of the templates used to generate talk titles, and re-run
39
+ # the test until we've seen them all. Then we know no template
40
+ # causes a crash. That's good enough.
41
+ #
44
42
  templates = things[:template].map do |t|
45
43
  escaped = Regexp.escape(CGI.escapeHTML(t))
46
- matcher = escaped.gsub(/%\w+%/, '[\w\-]+').gsub(/RAND\d+/, '\d+')
47
- .gsub(/FNOPS/, '\w+')
44
+ matcher = escaped.gsub(/%\w+%/, '\w+').gsub(/RAND\d+/, '\d+')
48
45
  Regexp.new('^.*ttitle">' + matcher + '</span>.*$')
49
46
  end
50
47
 
51
48
  until templates.empty?
52
49
  get '/'
53
- assert_equal('text/html;charset=utf-8',
54
- last_response.header['Content-Type'])
55
- last_response.ok?
56
- resp = last_response.body
57
- assert_match(/The code./, resp)
58
- assert_match(/DevOps Meetup/, resp)
59
- templates.each { |t| templates.delete(t) if resp.match?(t) }
50
+ assert last_response.ok?
51
+ assert last_response.header['Content-Type'] == 'text/html;charset=utf-8'
52
+ x = last_response.body
53
+ assert_match(/The code./, x)
54
+ assert_match(/DevOps Meetup/, x)
55
+ templates.each { |t| templates.delete(t) if x.match(t) }
60
56
  end
61
57
  end
62
58
 
63
- def test_api_talker
64
- get format('/api/talker')
65
- assert last_response.ok?
66
- assert_instance_of(String, last_response.body)
67
- assert_match(/^"\w+ \w+"$/, last_response.body)
68
- assert last_response.header['Content-Type'] == 'application/json'
69
- end
70
-
71
- def test_api_company
72
- get format('/api/company')
59
+ def test_api_talk
60
+ get '/api/talk'
73
61
  assert last_response.ok?
74
- assert_instance_of(String, last_response.body)
75
- assert_match(/^"\w+.io"$/, last_response.body)
76
62
  assert last_response.header['Content-Type'] == 'application/json'
63
+ resp = last_response.body
64
+ refute_empty resp
65
+ j = JSON.parse(resp)
66
+ fields = %w[talk talker role company]
67
+ assert_equal(j.keys, fields)
68
+ fields.each { |f| refute_empty j[f] }
69
+ name = j['talker'].split
70
+ assert_includes(things[:first_name], name.first)
71
+ assert_includes(things[:last_name], name.last)
72
+ assert j['company'].end_with?('.io')
77
73
  end
78
74
 
79
75
  def test_api_misc
80
- %w[title role refreshment location date].each do |word|
81
- get format('/api/%<word>s', word: word)
76
+ %w[title talker company role refreshment].each do |word|
77
+ get format('/api/%s', word)
82
78
  assert last_response.ok?
83
- assert_instance_of(String, last_response.body)
84
79
  assert last_response.header['Content-Type'] == 'application/json'
85
80
  end
86
81
  end
87
82
 
88
- def test_api_talk
89
- get format('/api/talk')
90
- assert last_response.ok?
91
- assert_instance_of(String, last_response.body)
92
- as_obj = JSON.parse(last_response.body, symbolize_names: true)
93
- assert_equal(%i[title talker role company], as_obj.keys)
94
- end
95
-
96
- def test_api_agenda
97
- get format('/api/agenda')
98
- assert last_response.ok?
99
- assert_instance_of(String, last_response.body)
100
- agenda = JSON.parse(last_response.body, symbolize_names: true)
101
- assert_equal(%i[date location refreshment talks], agenda.keys.sort)
102
-
103
- agenda[:talks].each do |t|
104
- assert_equal(%i[title talker role company], t.keys)
105
- end
106
-
107
- assert_instance_of(String, agenda[:refreshment])
108
- assert_instance_of(String, agenda[:date])
109
- assert_instance_of(String, agenda[:location])
110
- end
111
-
112
- def test_api_not_found
83
+ def test_api_404
113
84
  get '/api/no_such_thing'
114
85
  assert_equal(last_response.status, 404)
115
86
  end
data/spec/unit_spec.rb ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'minitest/autorun'
4
+ require_relative '../lib/meetup-generator'
5
+
6
+ THINGS = { food_style: %w[artisan],
7
+ food: %w[flatbread],
8
+ first_name: %w[John],
9
+ last_name: %w[Smith],
10
+ job_role: %w[Neckbeard],
11
+ job_title: ['Without Portfolio'],
12
+ tech: %w[Ruby],
13
+ template: ['RAND20 %tech% things'] }.freeze
14
+
15
+ class Giblets < MeetupGenerator
16
+ def initialize; end
17
+ end
18
+
19
+ class GibletsTest < MiniTest::Test
20
+ attr_reader :m
21
+
22
+ def setup
23
+ @m = Giblets.new
24
+ m.instance_variable_set(:@lib, THINGS)
25
+ end
26
+
27
+ def test_title
28
+ x = m.title
29
+ assert_instance_of(String, x)
30
+ assert !x.empty?
31
+ refute_match(/%\w+%/, x)
32
+ refute_match(/RAND/, x)
33
+ end
34
+
35
+ def test_talk
36
+ x = m.talks(1)
37
+ assert_instance_of(Array, x)
38
+ assert_instance_of(String, x.first)
39
+ toks = x.first.split
40
+ number = toks.first.to_i
41
+ assert number > 0
42
+ assert number <= 20
43
+ assert_equal('Ruby', toks[1])
44
+ assert_equal('things', toks[2])
45
+ end
46
+
47
+ def test_talker
48
+ assert_equal(m.talker, 'John Smith')
49
+ end
50
+
51
+ def test_role
52
+ assert_equal(m.role, 'Neckbeard Without Portfolio')
53
+ end
54
+
55
+ def test_company_no_e
56
+ m.instance_variable_set(:@words, %w[leadswinger])
57
+ assert_equal(m.company, 'leadswingr.io')
58
+ end
59
+
60
+ def test_company
61
+ m.instance_variable_set(:@words, %w[Cabbage])
62
+ assert_equal(m.company, 'cabbage.io')
63
+ end
64
+
65
+ def test_refreshment
66
+ assert_equal(m.refreshment, 'artisan flatbread')
67
+ end
68
+ end
data/views/default.slim CHANGED
@@ -7,42 +7,42 @@ html
7
7
 
8
8
  body
9
9
  #container
10
- h1
11
- ' #DevOps Meetup //
12
- => @agenda[:location]
13
- ' //
14
- == @agenda[:date]
10
+ h1 #DevOps Meetup // Shoreditch, probably // #{(Date.today + 1).strftime("%d/%m/%Y")}
15
11
 
16
12
  ul
17
13
  li 18:00 // Introduction
18
14
 
19
15
  li
20
16
  ' 18:10 // Lightning talk //
21
- == slim :partial_talk
17
+ span.ttitle=@talks.pop
18
+ .tperson=@jobs.pop
22
19
 
23
20
  li
24
21
  ' 18:20 //
25
- == slim :partial_talk
22
+ span.ttitle=@talks.pop
23
+ .tperson=@jobs.pop
26
24
 
27
- li
28
- ' 18:50 // break
29
- .indent=@agenda[:refreshment]
25
+ li 18:50 // break
26
+ .tperson=@food
30
27
 
31
28
  li
32
29
  ' 19:20 //
33
- == slim :partial_talk
30
+ span.ttitle=@talks.pop
31
+ .tperson=@jobs.pop
34
32
 
35
33
  li
36
34
  ' 19:40 // Ignite //
37
- == slim :partial_talk
35
+ span.ttitle=@talks.pop
36
+ .tperson=@jobs.pop
38
37
 
39
38
  li
40
39
  ' 20:00 //
41
- == slim :partial_talk
40
+ span.ttitle=@talks.pop
41
+ .tperson=@jobs.pop
42
42
 
43
43
  li
44
44
  ' 20:30 // Close
45
- .indent Everyone is hiring, but no one's paying
45
+ .tperson Everyone is hiring, but no one's paying
46
46
 
47
47
  #footer
48
48
  a href='https://github.com/snltd/meetup-generator' The code.
@@ -5,7 +5,7 @@
5
5
  <service_bundle type='manifest' name='snltd:sinatra:meetup-generator'>
6
6
 
7
7
  <service
8
- name='sysdef/meetup-generator'
8
+ name='application/sinatra/meetup-generator'
9
9
  type='service'
10
10
  version='1'>
11
11
 
@@ -90,7 +90,7 @@
90
90
  </common_name>
91
91
 
92
92
  <documentation>
93
- <doc_link name='meetup.sysdef.xyz' uri='http://meetup.sysdef.xyz' />
93
+ <doc_link name='meetup.rfisher.co.uk' uri='http://meetup.rdfisher.co.uk' />
94
94
  </documentation>
95
95
 
96
96
  </template>